package usecase import ( "context" "errors" "time" authdomain "gateway/internal/model/auth/domain" domrepo "gateway/internal/model/auth/domain/repository" domusecase "gateway/internal/model/auth/domain/usecase" "github.com/google/uuid" ) type loginMFAChallengeUseCase struct { store domrepo.LoginMFAChallengeStore } // LoginMFAChallengeUseCaseParam wires LoginMFAChallengeUseCase. type LoginMFAChallengeUseCaseParam struct { Store domrepo.LoginMFAChallengeStore } // MustLoginMFAChallengeUseCase constructs LoginMFAChallengeUseCase. func MustLoginMFAChallengeUseCase(param LoginMFAChallengeUseCaseParam) domusecase.LoginMFAChallengeUseCase { if param.Store == nil { panic("auth: login mfa challenge store is required") } return &loginMFAChallengeUseCase{store: param.Store} } func (uc *loginMFAChallengeUseCase) Create(ctx context.Context, req *domusecase.CreateLoginMFAChallengeRequest) (*domusecase.LoginMFAChallengeView, error) { if req == nil || req.TenantID == "" || req.TenantSlug == "" || req.UID == "" { return nil, errb.InputMissingRequired("tenant_id, tenant_slug and uid are required") } ttl := req.TTL if ttl <= 0 { ttl = 5 * time.Minute } challengeID := uuid.NewString() challenge := &domrepo.LoginMFAChallenge{ ChallengeID: challengeID, TenantID: req.TenantID, TenantSlug: req.TenantSlug, UID: req.UID, } if err := uc.store.Save(ctx, challenge, ttl); err != nil { return nil, wrapRepoErr(err, "save login mfa challenge failed") } return &domusecase.LoginMFAChallengeView{ ChallengeID: challengeID, ExpiresIn: int(ttl.Seconds()), }, nil } func (uc *loginMFAChallengeUseCase) Get(ctx context.Context, challengeID string) (*domusecase.CreateLoginMFAChallengeRequest, error) { if challengeID == "" { return nil, errb.InputMissingRequired("challenge_id is required") } challenge, err := uc.store.Get(ctx, challengeID) if err != nil { if errors.Is(err, authdomain.ErrLoginMFAChallengeNotFound) { return nil, errb.ResNotFound("login mfa challenge", challengeID).WithCause(err) } return nil, wrapRepoErr(err, "read login mfa challenge failed") } return &domusecase.CreateLoginMFAChallengeRequest{ TenantID: challenge.TenantID, TenantSlug: challenge.TenantSlug, UID: challenge.UID, }, nil } func (uc *loginMFAChallengeUseCase) Delete(ctx context.Context, challengeID string) error { if challengeID == "" { return errb.InputMissingRequired("challenge_id is required") } if err := uc.store.Delete(ctx, challengeID); err != nil { return wrapRepoErr(err, "delete login mfa challenge failed") } return nil } var _ domusecase.LoginMFAChallengeUseCase = (*loginMFAChallengeUseCase)(nil)