diff options
| author | James Elliott <james-d-elliott@users.noreply.github.com> | 2023-10-26 19:41:06 +1100 |
|---|---|---|
| committer | James Elliott <james-d-elliott@users.noreply.github.com> | 2024-03-04 20:29:11 +1100 |
| commit | 2a388194fbf56e8c030dc734f980dc223760b8d9 (patch) | |
| tree | 6dd17b6e4cbe3d1c0f6ab556632ae6fd2f68d145 /internal/storage/sql_provider.go | |
| parent | f81b414147014a8096ef995ea691c0010a4aab67 (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.go | 27 |
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) { |
