Files
sendico/api/pkg/db/internal/mongo/verificationimp/create.go
2026-02-05 20:51:03 +01:00

75 lines
1.7 KiB
Go

package verificationimp
import (
"context"
"crypto/rand"
"encoding/base64"
"time"
"github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/pkg/mutil/mzap"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/zap"
)
const verificationTokenBytes = 32
func newVerificationToken(
accountRef bson.ObjectID,
purpose model.VerificationPurpose,
target string,
ttl time.Duration,
) (*model.VerificationToken, string, error) {
raw := make([]byte, verificationTokenBytes)
if _, err := rand.Read(raw); err != nil {
return nil, "", err
}
rawToken := base64.RawURLEncoding.EncodeToString(raw)
hashStr := tokenHash(rawToken)
now := time.Now().UTC()
token := &model.VerificationToken{
AccountRef: accountRef,
Purpose: purpose,
Target: target,
VerifyTokenHash: hashStr,
UsedAt: nil,
ExpiresAt: now.Add(ttl),
}
return token, rawToken, nil
}
func (db *verificationDB) Create(
ctx context.Context,
accountRef bson.ObjectID,
purpose model.VerificationPurpose,
target string,
ttl time.Duration,
) (string, error) {
logFields := []zap.Field{
zap.String("purpose", string(purpose)), zap.Duration("ttl", ttl),
mzap.AccRef(accountRef), zap.String("target", target),
}
token, raw, err := newVerificationToken(accountRef, purpose, target, ttl)
if err != nil {
db.Logger.Warn("Failed to generate verification token", append(logFields, zap.Error(err))...)
return "", err
}
if err := db.DBImp.Create(ctx, token); err != nil {
db.Logger.Warn("Failed to persist verification token", append(logFields, zap.Error(err))...)
return "", err
}
db.Logger.Debug("Verification token created", append(logFields, zap.String("hash", token.VerifyTokenHash))...)
return raw, nil
}