Files
sendico/api/edge/bff/internal/server/verificationimp/request.go
2026-02-28 00:39:20 +01:00

58 lines
2.0 KiB
Go

package verificationimp
import (
"encoding/json"
"net/http"
"github.com/tech/sendico/pkg/api/http/response"
"github.com/tech/sendico/pkg/db/verification"
"github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/pkg/mutil/mask"
"github.com/tech/sendico/pkg/mutil/mzap"
emodel "github.com/tech/sendico/server/interface/model"
mutil "github.com/tech/sendico/server/internal/mutil/verification"
"go.uber.org/zap"
)
func (a *VerificationAPI) requestCode(r *http.Request, account *model.Account, token *emodel.AccountToken) http.HandlerFunc {
var req verificationCodeRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
a.logger.Warn("Failed to decode confirmation resend request", zap.Error(err))
return response.BadPayload(a.logger, a.Name(), err)
}
purpose, err := model.VPFromString(req.Purpose)
if err != nil {
return response.BadRequest(a.logger, a.Name(), "invalid_target", err.Error())
}
if purpose == model.PurposeLogin && (token == nil || !token.Pending) {
return response.Forbidden(a.logger, a.Name(), "pending_token_required", "login confirmation requires pending token")
}
target := a.resolveTarget(req.Target, account)
if target == "" {
return response.BadRequest(a.logger, a.Name(), "missing_destination", "email destination is required")
}
vReq := verification.NewOTPRequest(account.ID, purpose, target).
WithTTL(a.config.TTL).
WithCooldown(a.config.Cooldown).
WithMaxRetries(a.config.ResendLimit).
WithIdempotencyKey(req.IdempotencyKey)
otp, err := a.store.Create(r.Context(), vReq)
if err != nil {
a.logger.Warn("Failed to create confirmation code for resend", zap.Error(err), mzap.AccRef(account.ID))
return mutil.MapTokenErrorToResponse(a.logger, a.Name(), err)
}
a.sendCode(account, purpose, target, otp)
return response.Accepted(a.logger, verificationResponse{
TTLSeconds: int(vReq.Ttl.Seconds()),
CooldownSeconds: int(a.config.Cooldown.Seconds()),
Target: mask.Email(target),
IdempotencyKey: req.IdempotencyKey,
})
}