unified code verification service

This commit is contained in:
Stephan D
2026-02-10 01:55:33 +01:00
parent 76c3bfdea9
commit 7f540671c1
120 changed files with 1863 additions and 1394 deletions

View File

@@ -1,36 +0,0 @@
package model
import (
"time"
"github.com/tech/sendico/pkg/db/storable"
"github.com/tech/sendico/pkg/mservice"
"go.mongodb.org/mongo-driver/v2/bson"
)
type ConfirmationTarget string
const (
ConfirmationTargetLogin ConfirmationTarget = "login"
ConfirmationTargetPayout ConfirmationTarget = "payout"
)
type ConfirmationCode struct {
storable.Base `bson:",inline" json:",inline"`
AccountRef bson.ObjectID `bson:"accountRef" json:"accountRef"`
Destination string `bson:"destination" json:"destination"`
Target ConfirmationTarget `bson:"target" json:"target"`
CodeHash []byte `bson:"codeHash" json:"codeHash,omitempty"`
Salt []byte `bson:"salt" json:"salt,omitempty"`
ExpiresAt time.Time `bson:"expiresAt" json:"expiresAt"`
MaxAttempts int `bson:"maxAttempts" json:"maxAttempts"`
ResendLimit int `bson:"resendLimit" json:"resendLimit"`
CooldownUntil time.Time `bson:"cooldownUntil" json:"cooldownUntil"`
Used bool `bson:"used" json:"used"`
Attempts int `bson:"attempts" json:"attempts"`
ResendCount int `bson:"resendCount" json:"resendCount"`
}
func (*ConfirmationCode) Collection() string {
return mservice.Confirmations
}

View File

@@ -106,7 +106,7 @@ func StringToNotificationEvent(eventType, eventAction string) (NotificationEvent
if err == nil {
return NewNotification(et, ea), nil
}
if et == mservice.Confirmations {
if et == mservice.Verification {
action := strings.TrimSpace(eventAction)
if action == "" {
return nil, err

View File

@@ -1,9 +1,11 @@
package model
import (
"fmt"
"time"
"github.com/tech/sendico/pkg/db/storable"
"github.com/tech/sendico/pkg/merrors"
"go.mongodb.org/mongo-driver/v2/bson"
)
@@ -13,18 +15,45 @@ const (
PurposeAccountActivation VerificationPurpose = "account_activation"
PurposeEmailChange VerificationPurpose = "email_change"
PurposePasswordReset VerificationPurpose = "password_reset"
PurposeSensitiveAction VerificationPurpose = "sensitive_action"
PurposeMagicLogin VerificationPurpose = "magic_login"
PurposeLogin VerificationPurpose = "login"
PurposePayout VerificationPurpose = "payout"
)
func VPToString(code VerificationPurpose) string {
return string(code)
}
func VPFromString(s string) (VerificationPurpose, error) {
switch s {
case string(PurposeAccountActivation):
return PurposeAccountActivation, nil
case string(PurposeEmailChange):
return PurposeEmailChange, nil
case string(PurposePasswordReset):
return PurposePasswordReset, nil
case string(PurposeMagicLogin):
return PurposeMagicLogin, nil
case string(PurposeLogin):
return PurposeLogin, nil
case string(PurposePayout):
return PurposePayout, nil
default:
return "", merrors.InvalidArgument(fmt.Sprintf("invalid verification purpose: %s", s))
}
}
type VerificationToken struct {
storable.Base `bson:",inline" json:",inline"`
ArchivableBase `bson:",inline" json:",inline"`
storable.Base `bson:",inline" json:",inline"`
Target string `bson:"target,omitempty" json:"target"`
AccountRef bson.ObjectID `bson:"accountRef" json:"accountRef"`
Purpose VerificationPurpose `bson:"purpose" json:"purpose"`
IdempotencyKey *string `bson:"idempotencyKey,omitempty" json:"-"`
VerifyTokenHash string `bson:"verifyTokenHash" json:"-"`
Salt *string `bson:"salt,omitempty" json:"-"`
UsedAt *time.Time `bson:"usedAt,omitempty" json:"-"`
ExpiresAt time.Time `bson:"expiresAt" json:"-"`
MaxRetries *int `bson:"maxRetries,omitempty" json:"-"`
Attempts int `bson:"attempts" json:"-"`
}