Files
honeyDueAPI/internal/dto/responses/auth.go
Trey t 409d9716bd Add Sign in with Apple authentication
- Add AppleSocialAuth model to store Apple ID linkages
- Create AppleAuthService for JWT verification with Apple's public keys
- Add AppleSignIn handler and route (POST /auth/apple-sign-in/)
- Implement account linking (links Apple ID to existing accounts by email)
- Add Redis caching for Apple public keys (24-hour TTL)
- Support private relay emails (@privaterelay.appleid.com)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 01:17:10 -06:00

174 lines
5.1 KiB
Go

package responses
import (
"time"
"github.com/treytartt/casera-api/internal/models"
)
// UserResponse represents a user in API responses
type UserResponse struct {
ID uint `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
IsActive bool `json:"is_active"`
Verified bool `json:"verified"`
DateJoined time.Time `json:"date_joined"`
LastLogin *time.Time `json:"last_login,omitempty"`
}
// UserProfileResponse represents a user profile in API responses
type UserProfileResponse struct {
ID uint `json:"id"`
UserID uint `json:"user_id"`
Verified bool `json:"verified"`
Bio string `json:"bio"`
PhoneNumber string `json:"phone_number"`
DateOfBirth *time.Time `json:"date_of_birth,omitempty"`
ProfilePicture string `json:"profile_picture"`
}
// LoginResponse represents the login response
type LoginResponse struct {
Token string `json:"token"`
User UserResponse `json:"user"`
}
// RegisterResponse represents the registration response
type RegisterResponse struct {
Token string `json:"token"`
User UserResponse `json:"user"`
Message string `json:"message"`
}
// CurrentUserResponse represents the /auth/me/ response
type CurrentUserResponse struct {
ID uint `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
IsActive bool `json:"is_active"`
DateJoined time.Time `json:"date_joined"`
LastLogin *time.Time `json:"last_login,omitempty"`
Profile *UserProfileResponse `json:"profile,omitempty"`
}
// VerifyEmailResponse represents the email verification response
type VerifyEmailResponse struct {
Message string `json:"message"`
Verified bool `json:"verified"`
}
// ForgotPasswordResponse represents the forgot password response
type ForgotPasswordResponse struct {
Message string `json:"message"`
}
// VerifyResetCodeResponse represents the verify reset code response
type VerifyResetCodeResponse struct {
Message string `json:"message"`
ResetToken string `json:"reset_token"`
}
// ResetPasswordResponse represents the reset password response
type ResetPasswordResponse struct {
Message string `json:"message"`
}
// MessageResponse represents a simple message response
type MessageResponse struct {
Message string `json:"message"`
}
// ErrorResponse represents an error response
type ErrorResponse struct {
Error string `json:"error"`
Details map[string]string `json:"details,omitempty"`
}
// NewUserResponse creates a UserResponse from a User model
func NewUserResponse(user *models.User) UserResponse {
verified := false
if user.Profile != nil {
verified = user.Profile.Verified
}
return UserResponse{
ID: user.ID,
Username: user.Username,
Email: user.Email,
FirstName: user.FirstName,
LastName: user.LastName,
IsActive: user.IsActive,
Verified: verified,
DateJoined: user.DateJoined,
LastLogin: user.LastLogin,
}
}
// NewUserProfileResponse creates a UserProfileResponse from a UserProfile model
func NewUserProfileResponse(profile *models.UserProfile) *UserProfileResponse {
if profile == nil {
return nil
}
return &UserProfileResponse{
ID: profile.ID,
UserID: profile.UserID,
Verified: profile.Verified,
Bio: profile.Bio,
PhoneNumber: profile.PhoneNumber,
DateOfBirth: profile.DateOfBirth,
ProfilePicture: profile.ProfilePicture,
}
}
// NewCurrentUserResponse creates a CurrentUserResponse from a User model
func NewCurrentUserResponse(user *models.User) CurrentUserResponse {
return CurrentUserResponse{
ID: user.ID,
Username: user.Username,
Email: user.Email,
FirstName: user.FirstName,
LastName: user.LastName,
IsActive: user.IsActive,
DateJoined: user.DateJoined,
LastLogin: user.LastLogin,
Profile: NewUserProfileResponse(user.Profile),
}
}
// NewLoginResponse creates a LoginResponse
func NewLoginResponse(token string, user *models.User) LoginResponse {
return LoginResponse{
Token: token,
User: NewUserResponse(user),
}
}
// NewRegisterResponse creates a RegisterResponse
func NewRegisterResponse(token string, user *models.User) RegisterResponse {
return RegisterResponse{
Token: token,
User: NewUserResponse(user),
Message: "Registration successful. Please check your email to verify your account.",
}
}
// AppleSignInResponse represents the Apple Sign In response
type AppleSignInResponse struct {
Token string `json:"token"`
User UserResponse `json:"user"`
IsNewUser bool `json:"is_new_user"`
}
// NewAppleSignInResponse creates an AppleSignInResponse
func NewAppleSignInResponse(token string, user *models.User, isNewUser bool) AppleSignInResponse {
return AppleSignInResponse{
Token: token,
User: NewUserResponse(user),
IsNewUser: isNewUser,
}
}