814 lines
32 KiB
Go
814 lines
32 KiB
Go
package dto
|
|
|
|
import "encoding/json"
|
|
|
|
// JSON:API Request/Response DTOs for Auth
|
|
|
|
// Register
|
|
type RegisterAttributes struct {
|
|
Email string `json:"email" validate:"required,email" example:"user@example.com"`
|
|
Username string `json:"username" validate:"required,min=3,max=100" example:"john.doe"`
|
|
Password string `json:"password" validate:"required,min=8" example:"StrongP@ssw0rd"`
|
|
FirstName string `json:"first_name" validate:"required" example:"John"`
|
|
LastName string `json:"last_name" validate:"required" example:"Doe"`
|
|
MobilePhone string `json:"mobile_phone,omitempty" example:"+628123456789"`
|
|
}
|
|
|
|
type RegisterData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_register" example:"auth_register"`
|
|
Attributes RegisterAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type RegisterRequest struct {
|
|
Data RegisterData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Invite user
|
|
type InviteAttributes struct {
|
|
Email string `json:"email" validate:"required,email" example:"user@example.com"`
|
|
Username string `json:"username" validate:"required,min=3,max=100" example:"john.doe"`
|
|
FirstName string `json:"first_name" validate:"required" example:"John"`
|
|
LastName string `json:"last_name" validate:"required" example:"Doe"`
|
|
MobilePhone string `json:"mobile_phone,omitempty" example:"+628123456789"`
|
|
RoleID string `json:"role_id" validate:"required" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
RoleIDs []string `json:"role_ids,omitempty" example:"[\"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d\",\"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9e\"]"`
|
|
}
|
|
|
|
type InviteData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_invite" example:"auth_invite"`
|
|
Attributes InviteAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type InviteRequest struct {
|
|
Data InviteData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Set password from invite token
|
|
type SetPasswordAttributes struct {
|
|
Token string `json:"token" validate:"required" example:"kP8k2..."`
|
|
Password string `json:"password" validate:"required,min=8" example:"StrongP@ssw0rd"`
|
|
}
|
|
|
|
type SetPasswordData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_set_password" example:"auth_set_password"`
|
|
Attributes SetPasswordAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type SetPasswordRequest struct {
|
|
Data SetPasswordData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Resend set-password invite
|
|
type ResendSetPasswordInviteAttributes struct {
|
|
UserID string `json:"user_id" validate:"required" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
}
|
|
|
|
type ResendSetPasswordInviteData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_resend_set_password" example:"auth_resend_set_password"`
|
|
Attributes ResendSetPasswordInviteAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type ResendSetPasswordInviteRequest struct {
|
|
Data ResendSetPasswordInviteData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Forgot password
|
|
type ForgotPasswordAttributes struct {
|
|
Email string `json:"email" validate:"required,email" example:"user@example.com"`
|
|
}
|
|
|
|
type ForgotPasswordData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_forgot_password" example:"auth_forgot_password"`
|
|
Attributes ForgotPasswordAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type ForgotPasswordRequest struct {
|
|
Data ForgotPasswordData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Reset password
|
|
type ResetPasswordAttributes struct {
|
|
Token string `json:"token" validate:"required" example:"kP8k2..."`
|
|
NewPassword string `json:"new_password" validate:"required,min=8" example:"StrongP@ssw0rd!LongPassphrase"`
|
|
ConfirmPassword string `json:"confirm_password" validate:"required,min=8" example:"StrongP@ssw0rd!LongPassphrase"`
|
|
}
|
|
|
|
type ResetPasswordData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_reset_password" example:"auth_reset_password"`
|
|
Attributes ResetPasswordAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type ResetPasswordRequest struct {
|
|
Data ResetPasswordData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Setup security PIN
|
|
type SecurityPINSetupAttributes struct {
|
|
PIN string `json:"pin" validate:"required,len=6,numeric" example:"123456"`
|
|
ConfirmPIN string `json:"confirm_pin" validate:"required,len=6,numeric" example:"123456"`
|
|
}
|
|
|
|
type SecurityPINSetupData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_pin_setup" example:"auth_pin_setup"`
|
|
Attributes SecurityPINSetupAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type SecurityPINSetupRequest struct {
|
|
Data SecurityPINSetupData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type SecurityPINSetupResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_pin_setup"`
|
|
Attributes struct {
|
|
Configured bool `json:"configured" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Verify security PIN
|
|
type SecurityPINVerifyAttributes struct {
|
|
PIN string `json:"pin" validate:"required,len=6,numeric" example:"123456"`
|
|
Action string `json:"action" validate:"required,uuid4" example:"a546de2f-f1e6-4c2c-ab03-9b4bf39f4d74"`
|
|
}
|
|
|
|
type SecurityPINVerifyData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_pin_verify" example:"auth_pin_verify"`
|
|
Attributes SecurityPINVerifyAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type SecurityPINVerifyRequest struct {
|
|
Data SecurityPINVerifyData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type SecurityPINVerifyResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_pin_verify"`
|
|
Attributes struct {
|
|
Verified bool `json:"verified" example:"true"`
|
|
ActionToken string `json:"action_token" example:"pinv_1234567890abcdef"`
|
|
ActionTokenTTLMS int64 `json:"action_token_ttl_ms" example:"900000"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Change security PIN
|
|
type SecurityPINChangeAttributes struct {
|
|
CurrentPIN string `json:"current_pin" validate:"required,len=6,numeric" example:"123456"`
|
|
NewPIN string `json:"new_pin" validate:"required,len=6,numeric" example:"654321"`
|
|
ConfirmPIN string `json:"confirm_pin" validate:"required,len=6,numeric" example:"654321"`
|
|
}
|
|
|
|
type SecurityPINChangeData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_pin_change" example:"auth_pin_change"`
|
|
Attributes SecurityPINChangeAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type SecurityPINChangeRequest struct {
|
|
Data SecurityPINChangeData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Forgot security PIN
|
|
type ForgotSecurityPINAttributes struct {
|
|
Email string `json:"email" validate:"required,email" example:"user@example.com"`
|
|
}
|
|
|
|
type ForgotSecurityPINData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_forgot_pin" example:"auth_forgot_pin"`
|
|
Attributes ForgotSecurityPINAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type ForgotSecurityPINRequest struct {
|
|
Data ForgotSecurityPINData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Request security PIN reset
|
|
type RequestSecurityPINAttributes struct {
|
|
Method string `json:"method,omitempty" example:"password"`
|
|
Password string `json:"password,omitempty" example:"StrongP@ssw0rd"`
|
|
ReauthToken string `json:"reauth_token,omitempty" example:"sso_reauth_1234567890abcdef"`
|
|
}
|
|
|
|
type RequestSecurityPINData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_pin_request_reset" example:"auth_pin_request_reset"`
|
|
Attributes RequestSecurityPINAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type RequestSecurityPINRequest struct {
|
|
Data RequestSecurityPINData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type RequestSecurityPINResetResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_pin_request_reset"`
|
|
Attributes struct {
|
|
Message string `json:"message" example:"If allowed, a security PIN reset link has been sent to your email."`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Reset security PIN
|
|
type ResetSecurityPINAttributes struct {
|
|
Token string `json:"token,omitempty" example:"kP8k2..."`
|
|
Method string `json:"method,omitempty" example:"password"`
|
|
Password string `json:"password,omitempty" example:"StrongP@ssw0rd"`
|
|
ReauthToken string `json:"reauth_token,omitempty" example:"sso_reauth_1234567890abcdef"`
|
|
NewPIN string `json:"new_pin" validate:"required,len=6,numeric" example:"123456"`
|
|
ConfirmPIN string `json:"confirm_pin" validate:"required,len=6,numeric" example:"123456"`
|
|
}
|
|
|
|
type ResetSecurityPINData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_reset_pin" example:"auth_reset_pin"`
|
|
Attributes ResetSecurityPINAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type ResetSecurityPINRequest struct {
|
|
Data ResetSecurityPINData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Login
|
|
type LoginAttributes struct {
|
|
Email string `json:"email" validate:"required,email" example:"user@example.com"`
|
|
Password string `json:"password" validate:"required" example:"StrongP@ssw0rd"`
|
|
}
|
|
|
|
type LoginData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_login" example:"auth_login"`
|
|
Attributes LoginAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type LoginRequest struct {
|
|
Data LoginData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Exchange frontend Microsoft token result into backend session tokens
|
|
type ExchangeIDTokenClaims struct {
|
|
Aud string `json:"aud,omitempty" example:"12345678-1234-1234-1234-123456789012"`
|
|
Iss string `json:"iss,omitempty" example:"https://login.microsoftonline.com/abc-tenant-id/v2.0"`
|
|
Iat int64 `json:"iat,omitempty" example:"1715600000"`
|
|
Nbf int64 `json:"nbf,omitempty" example:"1715600000"`
|
|
Exp int64 `json:"exp,omitempty" example:"1715603600"`
|
|
Name string `json:"name,omitempty" example:"Andrio Effendi"`
|
|
PreferredUsername string `json:"preferred_username,omitempty" example:"andrio@mybit-innovation.com"`
|
|
Email string `json:"email,omitempty" example:"andrio@mybit-innovation.com"`
|
|
OID string `json:"oid,omitempty" example:"00000000-0000-0000-1234-567890abcdef"`
|
|
Sub string `json:"sub,omitempty" example:"AbCdEfGhIjKlMnOpQrStUvWxYz"`
|
|
TID string `json:"tid,omitempty" example:"abc-tenant-id"`
|
|
Ver string `json:"ver,omitempty" example:"2.0"`
|
|
}
|
|
|
|
type ExchangeAttributes struct {
|
|
AccessToken string `json:"access_token" validate:"required" example:"eyJ0eXAiOiJKV1Qi..."`
|
|
IDToken string `json:"id_token" validate:"required" example:"eyJ0eXAiOiJKV1Qi..."`
|
|
IDTokenClaims ExchangeIDTokenClaims `json:"id_token_claims"`
|
|
}
|
|
|
|
type ExchangeData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_exchange" example:"auth_exchange"`
|
|
Attributes ExchangeAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type ExchangeRequest struct {
|
|
Data ExchangeData `json:"data" validate:"required"`
|
|
}
|
|
|
|
func (c ExchangeIDTokenClaims) ToMap() map[string]any {
|
|
out := map[string]any{}
|
|
if c.Aud != "" {
|
|
out["aud"] = c.Aud
|
|
}
|
|
if c.Iss != "" {
|
|
out["iss"] = c.Iss
|
|
}
|
|
if c.Iat > 0 {
|
|
out["iat"] = c.Iat
|
|
}
|
|
if c.Nbf > 0 {
|
|
out["nbf"] = c.Nbf
|
|
}
|
|
if c.Exp > 0 {
|
|
out["exp"] = c.Exp
|
|
}
|
|
if c.Name != "" {
|
|
out["name"] = c.Name
|
|
}
|
|
if c.PreferredUsername != "" {
|
|
out["preferred_username"] = c.PreferredUsername
|
|
}
|
|
if c.Email != "" {
|
|
out["email"] = c.Email
|
|
}
|
|
if c.OID != "" {
|
|
out["oid"] = c.OID
|
|
}
|
|
if c.Sub != "" {
|
|
out["sub"] = c.Sub
|
|
}
|
|
if c.TID != "" {
|
|
out["tid"] = c.TID
|
|
}
|
|
if c.Ver != "" {
|
|
out["ver"] = c.Ver
|
|
}
|
|
return out
|
|
}
|
|
|
|
// WebAuthn register begin
|
|
type WebAuthnRegisterBeginData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_webauthn_register_begin" example:"auth_webauthn_register_begin"`
|
|
}
|
|
|
|
type WebAuthnRegisterBeginRequest struct {
|
|
Data WebAuthnRegisterBeginData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// WebAuthn register finish
|
|
type WebAuthnRegisterFinishAttributes struct {
|
|
ChallengeToken string `json:"challenge_token" validate:"required" example:"kP8k2..."`
|
|
Credential json.RawMessage `json:"credential" validate:"required"`
|
|
Name string `json:"name,omitempty" validate:"omitempty,max=100" example:"MacBook Touch ID"`
|
|
}
|
|
|
|
type WebAuthnRegisterFinishData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_webauthn_register_finish" example:"auth_webauthn_register_finish"`
|
|
Attributes WebAuthnRegisterFinishAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type WebAuthnRegisterFinishRequest struct {
|
|
Data WebAuthnRegisterFinishData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// WebAuthn login begin
|
|
type WebAuthnLoginBeginAttributes struct {
|
|
Email string `json:"email" validate:"required,email" example:"user@example.com"`
|
|
}
|
|
|
|
type WebAuthnLoginBeginData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_webauthn_login_begin" example:"auth_webauthn_login_begin"`
|
|
Attributes WebAuthnLoginBeginAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type WebAuthnLoginBeginRequest struct {
|
|
Data WebAuthnLoginBeginData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// WebAuthn login finish
|
|
type WebAuthnLoginFinishAttributes struct {
|
|
ChallengeToken string `json:"challenge_token" validate:"required" example:"kP8k2..."`
|
|
Credential json.RawMessage `json:"credential" validate:"required"`
|
|
}
|
|
|
|
type WebAuthnLoginFinishData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_webauthn_login_finish" example:"auth_webauthn_login_finish"`
|
|
Attributes WebAuthnLoginFinishAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type WebAuthnLoginFinishRequest struct {
|
|
Data WebAuthnLoginFinishData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Sensitive-action re-auth attributes
|
|
type ReauthAttributes struct {
|
|
Method string `json:"method" validate:"required,oneof=pin password" example:"pin"`
|
|
Password string `json:"password,omitempty" validate:"omitempty,min=1" example:"StrongP@ssw0rd"`
|
|
}
|
|
|
|
// WebAuthn reset setup
|
|
type WebAuthnResetSetupData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_webauthn_reset_setup" example:"auth_webauthn_reset_setup"`
|
|
Attributes ReauthAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type WebAuthnResetSetupRequest struct {
|
|
Data WebAuthnResetSetupData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type WebAuthnResetSetupResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_webauthn_reset_setup"`
|
|
Attributes struct {
|
|
Reset bool `json:"reset" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Login response when TOTP required
|
|
type LoginTOTPRequiredResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_totp_required"`
|
|
Attributes struct {
|
|
RequiresTOTP bool `json:"requires_totp" example:"true"`
|
|
ChallengeToken string `json:"challenge_token" example:"kP8k2..."`
|
|
TOTPEnabled bool `json:"totp_enabled" example:"true"`
|
|
EmailOTPEnabled bool `json:"email_otp_enabled" example:"false"`
|
|
EmailOTPChallengeToken string `json:"email_otp_challenge_token,omitempty" example:"qA9j1..."`
|
|
EmailOTPResendCooldownSec int `json:"email_otp_resend_cooldown_seconds,omitempty" example:"60"`
|
|
EmailOTPMaxResendPerHour int `json:"email_otp_max_resend_per_hour,omitempty" example:"5"`
|
|
WebAuthnConfigured bool `json:"webauthn_configured" example:"false"`
|
|
LinkedSSO bool `json:"linked_sso" example:"false"`
|
|
PINConfigured bool `json:"pin_configured" example:"false"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type LoginEmailOTPRequiredResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_email_otp_required"`
|
|
Attributes struct {
|
|
RequiresEmailOTP bool `json:"requires_email_otp" example:"true"`
|
|
ChallengeToken string `json:"challenge_token" example:"kP8k2..."`
|
|
ResendCooldownSeconds int `json:"resend_cooldown_seconds" example:"60"`
|
|
MaxResendPerHour int `json:"max_resend_per_hour" example:"5"`
|
|
RequiresTOTPSetup bool `json:"requires_totp_setup" example:"true"`
|
|
WebAuthnConfigured bool `json:"webauthn_configured" example:"false"`
|
|
LinkedSSO bool `json:"linked_sso" example:"false"`
|
|
PINConfigured bool `json:"pin_configured" example:"false"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type EmailOTPSendAttributes struct {
|
|
ChallengeToken string `json:"challenge_token" validate:"required" example:"kP8k2..."`
|
|
}
|
|
|
|
type EmailOTPSendData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_email_otp_send" example:"auth_email_otp_send"`
|
|
Attributes EmailOTPSendAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type EmailOTPSendRequest struct {
|
|
Data EmailOTPSendData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type EmailOTPVerifyAttributes struct {
|
|
ChallengeToken string `json:"challenge_token" validate:"required" example:"kP8k2..."`
|
|
Code string `json:"code" validate:"required,len=6,numeric" example:"123456"`
|
|
}
|
|
|
|
type EmailOTPVerifyData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_email_otp_verify" example:"auth_email_otp_verify"`
|
|
Attributes EmailOTPVerifyAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type EmailOTPVerifyRequest struct {
|
|
Data EmailOTPVerifyData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type EmailOTPSendResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_email_otp_send"`
|
|
Attributes struct {
|
|
Sent bool `json:"sent" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type EmailOTPVerifyResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_email_otp_verify"`
|
|
Attributes struct {
|
|
Verified bool `json:"verified" example:"true"`
|
|
RequiresTOTPSetup bool `json:"requires_totp_setup" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Email verify response
|
|
type VerifyEmailResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_verify_email"`
|
|
Attributes struct {
|
|
Verified bool `json:"verified" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Microsoft login
|
|
type MicrosoftLoginResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_microsoft_url"`
|
|
Attributes struct {
|
|
URL string `json:"url" example:"https://login.microsoftonline.com/..."`
|
|
RedirectURL string `json:"redirect_url" example:"https://login.microsoftonline.com/..."`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Microsoft callback
|
|
type MicrosoftCallbackResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_identity"`
|
|
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
Attributes struct {
|
|
Provider string `json:"provider" example:"microsoft"`
|
|
ProviderSubject string `json:"provider_subject" example:"00000000-0000-0000-0000-000000000000"`
|
|
Email string `json:"email" example:"user@example.com"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type SSOLinkAttributes struct {
|
|
Provider string `json:"provider" validate:"required,eq=microsoft" example:"microsoft"`
|
|
Code string `json:"code" validate:"required" example:"0.AXkA..."`
|
|
}
|
|
|
|
type SSOLinkData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_sso_link" example:"auth_sso_link"`
|
|
Attributes SSOLinkAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type SSOLinkRequest struct {
|
|
Data SSOLinkData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type SSOLinkResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_sso_link"`
|
|
Attributes struct {
|
|
Provider string `json:"provider" example:"microsoft"`
|
|
ProviderSubject string `json:"provider_subject" example:"00000000-0000-0000-0000-000000000000"`
|
|
Email string `json:"email" example:"user@example.com"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type SSOUnlinkAttributes struct {
|
|
Provider string `json:"provider" validate:"required,eq=microsoft" example:"microsoft"`
|
|
}
|
|
|
|
type SSOUnlinkData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_sso_unlink" example:"auth_sso_unlink"`
|
|
Attributes SSOUnlinkAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type SSOUnlinkRequest struct {
|
|
Data SSOUnlinkData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type SSOUnlinkResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_sso_unlink"`
|
|
Attributes struct {
|
|
Provider string `json:"provider" example:"microsoft"`
|
|
Unlinked bool `json:"unlinked" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// WebAuthn begin response
|
|
type WebAuthnBeginResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_webauthn_register_options"`
|
|
Attributes struct {
|
|
ChallengeToken string `json:"challenge_token" example:"kP8k2..."`
|
|
ChallengeTTLMS int64 `json:"challenge_ttl_ms" example:"300000"`
|
|
PublicKey map[string]interface{} `json:"public_key"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// TOTP setup
|
|
type TOTPSetupAttributes struct {
|
|
UserID string `json:"user_id" validate:"required" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
Email string `json:"email" validate:"required,email" example:"user@example.com"`
|
|
}
|
|
|
|
type TOTPSetupData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_totp_setup" example:"auth_totp_setup"`
|
|
Attributes TOTPSetupAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type TOTPSetupRequest struct {
|
|
Data TOTPSetupData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type TOTPSetupResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_totp_setup"`
|
|
Attributes struct {
|
|
Secret string `json:"secret" example:"JBSWY3DPEHPK3PXP"`
|
|
OtpauthURL string `json:"otpauth_url" example:"otpauth://totp/Wucher:user@example.com?..."`
|
|
Issuer string `json:"issuer" example:"Wucher"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// TOTP verify
|
|
type TOTPVerifyAttributes struct {
|
|
ChallengeToken string `json:"challenge_token" validate:"required" example:"kP8k2..."`
|
|
Code string `json:"code" validate:"required,len=6" example:"123456"`
|
|
}
|
|
|
|
type TOTPVerifyData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_totp_verify" example:"auth_totp_verify"`
|
|
Attributes TOTPVerifyAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type TOTPVerifyRequest struct {
|
|
Data TOTPVerifyData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// TOTP confirm (enable)
|
|
type TOTPConfirmAttributes struct {
|
|
UserID string `json:"user_id" validate:"required" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
Code string `json:"code" validate:"required,len=6" example:"123456"`
|
|
}
|
|
|
|
type TOTPConfirmData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_totp_confirm" example:"auth_totp_confirm"`
|
|
Attributes TOTPConfirmAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type TOTPConfirmRequest struct {
|
|
Data TOTPConfirmData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Disable TOTP
|
|
type TOTPDisableAttributes struct {
|
|
UserID string `json:"user_id" validate:"required" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
}
|
|
|
|
type TOTPDisableData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_totp_disable" example:"auth_totp_disable"`
|
|
Attributes TOTPDisableAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type TOTPDisableRequest struct {
|
|
Data TOTPDisableData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// TOTP reset setup
|
|
type TOTPResetSetupData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_totp_reset_setup" example:"auth_totp_reset_setup"`
|
|
Attributes ReauthAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type TOTPResetSetupRequest struct {
|
|
Data TOTPResetSetupData `json:"data" validate:"required"`
|
|
}
|
|
|
|
type TOTPResetSetupResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_totp_reset_setup"`
|
|
Attributes struct {
|
|
Reset bool `json:"reset" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type AuthSessionItem struct {
|
|
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
DeviceName string `json:"device_name" example:"Chrome on macOS"`
|
|
UserAgent string `json:"user_agent,omitempty" example:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ..."`
|
|
IPAddress string `json:"ip_address,omitempty" example:"127.0.0.1"`
|
|
CreatedAt string `json:"created_at" example:"2026-03-13T12:00:00Z"`
|
|
LastActiveAt string `json:"last_active_at" example:"2026-03-13T12:10:00Z"`
|
|
ActiveNow bool `json:"active_now" example:"true"`
|
|
}
|
|
|
|
type AuthSessionsResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_sessions"`
|
|
Attributes struct {
|
|
Sessions []AuthSessionItem `json:"sessions"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type AuthSessionDeleteResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_session_delete"`
|
|
Attributes struct {
|
|
Deleted bool `json:"deleted" example:"true"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Update timezone
|
|
type TimezoneUpdateAttributes struct {
|
|
Timezone string `json:"timezone" validate:"required" example:"Asia/Jakarta"`
|
|
}
|
|
|
|
type TimezoneUpdateData struct {
|
|
Type string `json:"type" validate:"required,eq=auth_timezone_update" example:"auth_timezone_update"`
|
|
Attributes TimezoneUpdateAttributes `json:"attributes" validate:"required"`
|
|
}
|
|
|
|
type TimezoneUpdateRequest struct {
|
|
Data TimezoneUpdateData `json:"data" validate:"required"`
|
|
}
|
|
|
|
// Token response
|
|
type TokenResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"auth_tokens"`
|
|
Attributes struct {
|
|
AccessTokenExpiresIn int64 `json:"access_expires_in" example:"900"`
|
|
RefreshTokenExpiresIn int64 `json:"refresh_expires_in" example:"2592000"`
|
|
} `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// User response
|
|
type UserAttributes struct {
|
|
Email string `json:"email" example:"user@example.com"`
|
|
Username string `json:"username,omitempty" example:"john.doe"`
|
|
FirstName string `json:"first_name" example:"John"`
|
|
LastName string `json:"last_name" example:"Doe"`
|
|
MobilePhone string `json:"mobile_phone,omitempty" example:"+628123456789"`
|
|
Timezone string `json:"timezone" example:"Asia/Jakarta"`
|
|
ProfilePicture *UserImage `json:"profile_picture,omitempty"`
|
|
RoleID string `json:"role_id,omitempty" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
RoleIDs []string `json:"role_ids,omitempty" example:"[\"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d\",\"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9e\"]"`
|
|
CreatedBy string `json:"created_by,omitempty" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
EmailVerifiedAt string `json:"email_verified_at,omitempty" example:"2026-02-05T10:00:00Z"`
|
|
TOTPEnabled bool `json:"totp_enabled" example:"false"`
|
|
IsPreviouslyConfigured bool `json:"is_previously_configured" example:"false"`
|
|
WebAuthnConfigured bool `json:"webauthn_configured" example:"false"`
|
|
LinkedSSO bool `json:"linked_sso" example:"false"`
|
|
PINConfigured bool `json:"pin_configured" example:"false"`
|
|
Role RoleMini `json:"role,omitempty"`
|
|
Roles []RoleMini `json:"roles,omitempty"`
|
|
}
|
|
|
|
type UserImage struct {
|
|
UUID string `json:"uuid,omitempty" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9f"`
|
|
DownloadURL string `json:"download_url,omitempty" example:"https://example.com/presigned-url"`
|
|
ThumbnailDownloadURL string `json:"thumbnail_download_url,omitempty" example:"https://example.com/presigned-thumb-url"`
|
|
OriginalSizeBytes *int64 `json:"original_size_bytes,omitempty" example:"1024000"`
|
|
}
|
|
|
|
type UserFoto struct {
|
|
UUID string `json:"uuid,omitempty" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9f"`
|
|
DownloadURL string `json:"download_url,omitempty" example:"https://storage.example.com/base/lude.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Signature=abc123"`
|
|
ThumbnailDownloadURL string `json:"thumbnail_download_url,omitempty" example:"https://storage.example.com/base/lude.thumb.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Signature=abc123"`
|
|
OriginalSizeBytes *int64 `json:"original_size_bytes,omitempty" example:"1024000"`
|
|
}
|
|
|
|
type RoleMini struct {
|
|
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
Name string `json:"name" example:"admin"`
|
|
Description string `json:"description,omitempty" example:"Full access to all resources."`
|
|
}
|
|
|
|
type PermissionMini struct {
|
|
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9a"`
|
|
Name string `json:"name" example:"View Users"`
|
|
Key string `json:"key" example:"users.read"`
|
|
Description string `json:"description,omitempty" example:"Permission to view users."`
|
|
RequiresPIN bool `json:"requires_pin" example:"false"`
|
|
}
|
|
|
|
// Auth current-user payload used by /auth/login and /auth/me endpoints.
|
|
type AuthCurrentUserAttributes struct {
|
|
Email string `json:"email" example:"user@example.com"`
|
|
EmailSSO string `json:"email_sso,omitempty" example:"user.sso@example.com"`
|
|
FirstName string `json:"first_name" example:"John"`
|
|
LastName string `json:"last_name" example:"Doe"`
|
|
MobilePhone string `json:"mobile_phone,omitempty" example:"+628123456789"`
|
|
Timezone string `json:"timezone" example:"Asia/Jakarta"`
|
|
Foto *UserFoto `json:"foto,omitempty"`
|
|
EmailVerifiedAt string `json:"email_verified_at,omitempty" example:"2026-02-05T10:00:00Z"`
|
|
Roles []RoleMini `json:"roles,omitempty"`
|
|
Permissions []PermissionMini `json:"permissions,omitempty"`
|
|
PermissionModules []PermissionGroupResource `json:"permission_modules,omitempty"`
|
|
TOTPEnabled bool `json:"totp_enabled" example:"false"`
|
|
IsPreviouslyConfigured bool `json:"is_previously_configured" example:"false"`
|
|
WebAuthnConfigured bool `json:"webauthn_configured" example:"false"`
|
|
LinkedSSO bool `json:"linked_sso" example:"false"`
|
|
PINConfigured bool `json:"pin_configured" example:"false"`
|
|
PINBlocked bool `json:"pin_blocked" example:"false"`
|
|
LoginMethod string `json:"login_method,omitempty" example:"email"`
|
|
AuthProvider string `json:"auth_provider,omitempty" example:"email"`
|
|
MicrosoftScope string `json:"microsoft_scope,omitempty" example:"openid profile email offline_access User.Read"`
|
|
DULBases []DULBase `json:"dul_bases,omitempty"`
|
|
}
|
|
|
|
type AuthCurrentUserResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"user"`
|
|
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
Attributes AuthCurrentUserAttributes `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type UserResponse struct {
|
|
Data struct {
|
|
Type string `json:"type" example:"user"`
|
|
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
|
|
Attributes UserAttributes `json:"attributes"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
// Error response for Swagger
|
|
type ErrorResponse struct {
|
|
Errors []struct {
|
|
Status string `json:"status" example:"422"`
|
|
Title string `json:"title" example:"Validation error"`
|
|
Detail string `json:"detail" example:"email is required"`
|
|
Source struct {
|
|
Pointer string `json:"pointer" example:"/data/attributes/email"`
|
|
} `json:"source"`
|
|
} `json:"errors"`
|
|
}
|