package auth import ( "context" "errors" "github.com/google/uuid" "github.com/rs/zerolog" "go.uber.org/fx" "base/config" "base/internal/domain/auth" "base/internal/domain/profile" "base/internal/dto" "base/internal/pkg/oauth" "base/pkg/email" "base/pkg/jwt" "base/pkg/store" ) var ( ErrUserNotFound = errors.New("user not found") ErrInvalidCredentials = errors.New("invalid credentials") ErrUserAlreadyExists = errors.New("user already exists") ErrInvalidVerificationCode = errors.New("invalid verification code") ErrEmailAlreadyVerified = errors.New("email already verified") ErrInvalidRefreshToken = errors.New("invalid refresh token") ErrAccountNotFound = errors.New("account not found") ErrProfileNotFound = errors.New("profile not found") ErrProfileAlreadyExists = errors.New("profile already exists") ErrHandleAlreadyTaken = errors.New("handle already taken") ) type Service interface { RegisterWithCredentials(ctx context.Context, request dto.RegisterRequest) (*dto.TokenResponse, error) LoginWithCredentials(ctx context.Context, email, password string) (*dto.TokenResponse, error) RefreshToken(ctx context.Context, refreshToken string) (*dto.TokenResponse, error) GetOAuthRedirectURL(ctx context.Context, request dto.OAuthRedirectURLRequest) (string, error) OAuthCallback(ctx context.Context, request dto.OAuthCallbackRequest) (*dto.OAuthCallbackResponse, error) SendVerificationEmail(ctx context.Context, request dto.SendVerificationEmailRequest) error VerifyAccount(ctx context.Context, request dto.VerifyAccountRequest) error SendResetPasswordEmail(ctx context.Context, request dto.SendResetPasswordEmailRequest) error ResetPassword(ctx context.Context, request dto.ResetPasswordRequest) (*dto.TokenResponse, error) SetupProfile(ctx context.Context, userID uuid.UUID, request dto.SetupProfileRequest) error GetUserInfo(ctx context.Context, userID uuid.UUID) (*dto.UserInfoResponse, error) } type service struct { logger zerolog.Logger config *config.AppConfig userRepo auth.UserRepository accountRepo auth.AccountRepository profileRepo profile.Repository emailService email.Email oauthService oauth.OAuth verificationStore store.Store[string] resetPasswordStore store.Store[string] jwtService jwt.TokenService } type Param struct { Logger zerolog.Logger Config *config.AppConfig UserRepo auth.UserRepository AccountRepo auth.AccountRepository ProfileRepo profile.Repository EmailService email.Email OAuthService oauth.OAuth VerificationStore store.Store[string] `name:"verification_store"` ResetPasswordStore store.Store[string] `name:"reset_password_store"` fx.In } func New(param Param) Service { return &service{ logger: param.Logger, config: param.Config, userRepo: param.UserRepo, accountRepo: param.AccountRepo, profileRepo: param.ProfileRepo, emailService: param.EmailService, oauthService: param.OAuthService, verificationStore: param.VerificationStore, resetPasswordStore: param.ResetPasswordStore, jwtService: jwt.New(param.Config.JWT.Secret, param.Config.JWT.AccessTokenExpiration, param.Config.JWT.RefreshTokenExpiration), } }