summaryrefslogtreecommitdiff
path: root/internal/storage/sql_provider.go
diff options
context:
space:
mode:
authorJames Elliott <james-d-elliott@users.noreply.github.com>2023-10-26 19:41:06 +1100
committerJames Elliott <james-d-elliott@users.noreply.github.com>2024-03-04 20:29:11 +1100
commit2a388194fbf56e8c030dc734f980dc223760b8d9 (patch)
tree6dd17b6e4cbe3d1c0f6ab556632ae6fd2f68d145 /internal/storage/sql_provider.go
parentf81b414147014a8096ef995ea691c0010a4aab67 (diff)
feat(web): revoke reset password tokens
This adds functionality to the frontend to revoke the Reset Password JWT's. Closes #136 Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
Diffstat (limited to 'internal/storage/sql_provider.go')
-rw-r--r--internal/storage/sql_provider.go27
1 files changed, 26 insertions, 1 deletions
diff --git a/internal/storage/sql_provider.go b/internal/storage/sql_provider.go
index d53425485..66f8a7795 100644
--- a/internal/storage/sql_provider.go
+++ b/internal/storage/sql_provider.go
@@ -40,6 +40,7 @@ func NewSQLProvider(config *schema.Configuration, name, driverName, dataSourceNa
sqlInsertIdentityVerification: fmt.Sprintf(queryFmtInsertIdentityVerification, tableIdentityVerification),
sqlConsumeIdentityVerification: fmt.Sprintf(queryFmtConsumeIdentityVerification, tableIdentityVerification),
+ sqlRevokeIdentityVerification: fmt.Sprintf(queryFmtRevokeIdentityVerification, tableIdentityVerification),
sqlSelectIdentityVerification: fmt.Sprintf(queryFmtSelectIdentityVerification, tableIdentityVerification),
sqlInsertOneTimeCode: fmt.Sprintf(queryFmtInsertOTC, tableOneTimeCode),
@@ -171,6 +172,7 @@ type SQLProvider struct {
// Table: identity_verification.
sqlInsertIdentityVerification string
sqlConsumeIdentityVerification string
+ sqlRevokeIdentityVerification string
sqlSelectIdentityVerification string
// Table: one_time_code.
@@ -776,6 +778,15 @@ func (p *SQLProvider) ConsumeIdentityVerification(ctx context.Context, jti strin
return nil
}
+// RevokeIdentityVerification marks an identity verification record in the storage provider as revoked.
+func (p *SQLProvider) RevokeIdentityVerification(ctx context.Context, jti string, ip model.NullIP) (err error) {
+ if _, err = p.db.ExecContext(ctx, p.sqlRevokeIdentityVerification, ip, jti); err != nil {
+ return fmt.Errorf("error updating identity verification: %w", err)
+ }
+
+ return nil
+}
+
// FindIdentityVerification checks if an identity verification record is in the storage provider and active.
func (p *SQLProvider) FindIdentityVerification(ctx context.Context, jti string) (found bool, err error) {
verification := model.IdentityVerification{}
@@ -788,7 +799,9 @@ func (p *SQLProvider) FindIdentityVerification(ctx context.Context, jti string)
}
switch {
- case verification.Consumed.Valid:
+ case verification.RevokedAt.Valid:
+ return false, fmt.Errorf("the token has been revoked")
+ case verification.ConsumedAt.Valid:
return false, fmt.Errorf("the token has already been consumed")
case verification.ExpiresAt.Before(time.Now()):
return false, fmt.Errorf("the token expired %s ago", time.Since(verification.ExpiresAt))
@@ -797,6 +810,18 @@ func (p *SQLProvider) FindIdentityVerification(ctx context.Context, jti string)
}
}
+// LoadIdentityVerification loads an Identity Verification but does not do any validation.
+// For easy validation you should use FindIdentityVerification which ensures the JWT is still valid.
+func (p *SQLProvider) LoadIdentityVerification(ctx context.Context, jti string) (verification *model.IdentityVerification, err error) {
+ verification = &model.IdentityVerification{}
+
+ if err = p.db.GetContext(ctx, verification, p.sqlSelectIdentityVerification, jti); err != nil {
+ return nil, fmt.Errorf("error selecting identity verification: %w", err)
+ }
+
+ return verification, nil
+}
+
// SaveOneTimeCode saves a One-Time Code to the storage provider after generating the signature which is returned
// along with any error.
func (p *SQLProvider) SaveOneTimeCode(ctx context.Context, code model.OneTimeCode) (signature string, err error) {