1e13f35219
/v1/auth/web-ticket(需登录):签发一次性票据(crypto/rand 32B, Redis GETDEL 单用, 60s)。 /v1/auth/web-ticket/exchange(公开):票换与 /auth/login 同款 token pair。镜像 jiu。含 6 测试。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
96 lines
3.6 KiB
Go
96 lines
3.6 KiB
Go
package auth
|
|
|
|
import "github.com/wangjia/pangolin/server/internal/apierr"
|
|
|
|
// Auth-module error values. Codes use the dotted `auth.*` namespace documented
|
|
// in the OpenAPI contract (components.schemas.Error). All messages are bilingual
|
|
// and desensitised (no destination / traffic wording, no enumeration leaks).
|
|
var (
|
|
// ErrInvalidRequest — malformed body or failed field validation.
|
|
ErrInvalidRequest = &apierr.Error{
|
|
Code: "auth.invalid_request",
|
|
MessageZH: "请求参数有误,请检查后重试",
|
|
MessageEn: "Invalid request parameters, please verify and try again",
|
|
}
|
|
|
|
// ErrEmailDisposable — the email domain is on the disposable-domain blocklist.
|
|
ErrEmailDisposable = &apierr.Error{
|
|
Code: "auth.email_disposable",
|
|
MessageZH: "暂不支持该邮箱服务商,请更换邮箱",
|
|
MessageEn: "This email provider is not supported, please use another address",
|
|
}
|
|
|
|
// ErrCodeInvalid — verification code wrong, expired, or already used.
|
|
// Intentionally generic to avoid distinguishing the three cases.
|
|
ErrCodeInvalid = &apierr.Error{
|
|
Code: "auth.code_invalid",
|
|
MessageZH: "验证码无效或已过期,请重新获取",
|
|
MessageEn: "Verification code is invalid or expired, please request a new one",
|
|
}
|
|
|
|
// ErrEmailExists — the email is already registered.
|
|
ErrEmailExists = &apierr.Error{
|
|
Code: "auth.email_exists",
|
|
MessageZH: "该邮箱已注册,请直接登录",
|
|
MessageEn: "This email is already registered, please sign in",
|
|
}
|
|
|
|
// ErrRateLimited — rate-limit window exceeded. Carries a Retry-After header.
|
|
ErrRateLimited = &apierr.Error{
|
|
Code: "auth.rate_limited",
|
|
MessageZH: "操作过于频繁,请稍后再试",
|
|
MessageEn: "Too many attempts, please try again later",
|
|
}
|
|
|
|
// ErrInvalidCredentials — wrong email or password (login).
|
|
ErrInvalidCredentials = &apierr.Error{
|
|
Code: "auth.invalid_credentials",
|
|
MessageZH: "邮箱或密码不正确",
|
|
MessageEn: "Incorrect email or password",
|
|
}
|
|
|
|
// ErrAccountLocked — too many failed logins; temporarily locked.
|
|
ErrAccountLocked = &apierr.Error{
|
|
Code: "auth.account_locked",
|
|
MessageZH: "登录失败次数过多,账户已临时锁定,请稍后再试",
|
|
MessageEn: "Too many failed sign-in attempts, account temporarily locked",
|
|
}
|
|
|
|
// ErrAccountBanned — the account has been disabled.
|
|
ErrAccountBanned = &apierr.Error{
|
|
Code: "auth.account_banned",
|
|
MessageZH: "该账户已被停用",
|
|
MessageEn: "This account has been disabled",
|
|
}
|
|
|
|
// ErrInvalidToken — refresh token absent from whitelist, malformed, or expired.
|
|
ErrInvalidToken = &apierr.Error{
|
|
Code: "auth.invalid_token",
|
|
MessageZH: "登录已失效,请重新登录",
|
|
MessageEn: "Your session has expired, please sign in again",
|
|
}
|
|
|
|
// ErrUnauthorized — missing or invalid bearer access token (middleware).
|
|
ErrUnauthorized = &apierr.Error{
|
|
Code: "auth.unauthorized",
|
|
MessageZH: "请先登录",
|
|
MessageEn: "Authentication required",
|
|
}
|
|
|
|
// ErrInternal — unexpected server-side failure.
|
|
ErrInternal = &apierr.Error{
|
|
Code: "auth.internal",
|
|
MessageZH: "服务器内部错误,请稍后重试",
|
|
MessageEn: "Internal server error, please try again later",
|
|
}
|
|
|
|
// ErrTicketInvalid — the web-ticket (App→网页免登录一次性票据) is missing,
|
|
// already used, or expired. Intentionally generic (mirrors ErrCodeInvalid) so
|
|
// the three cases can't be distinguished from the response.
|
|
ErrTicketInvalid = &apierr.Error{
|
|
Code: "auth.ticket_invalid",
|
|
MessageZH: "登录票据无效或已过期,请重新从 App 打开",
|
|
MessageEn: "Login ticket is invalid or expired, please reopen from the app",
|
|
}
|
|
)
|