feat: implement TASK-WP1-02 login sessions

This commit is contained in:
suyx
2026-07-28 16:28:30 +08:00
parent f467e7c09f
commit ee70001d44
20 changed files with 2480 additions and 28 deletions
+6
View File
@@ -19,6 +19,9 @@ export const stableEngineeringErrors = {
IDEMPOTENCY_KEY_CONFLICT: { httpStatus: 409, messageKey: "request.idempotency_conflict" },
AUTH_SESSION_INVALID: { httpStatus: 401, messageKey: "auth.session.invalid" },
AUTH_SERVICE_UNAVAILABLE: { httpStatus: 503, messageKey: "auth.service.unavailable" },
AUTH_ENTRY_REJECTED: { httpStatus: 409, messageKey: "auth.entry.rejected" },
AUTH_RATE_LIMITED: { httpStatus: 429, messageKey: "auth.rate_limited" },
AUTH_CSRF_INVALID: { httpStatus: 403, messageKey: "auth.csrf.invalid" },
} as const;
export type StableEngineeringErrorCode = keyof typeof stableEngineeringErrors;
@@ -55,6 +58,9 @@ export const StableEngineeringErrorCodeSchema = Type.Union(
Type.Literal("IDEMPOTENCY_KEY_CONFLICT"),
Type.Literal("AUTH_SESSION_INVALID"),
Type.Literal("AUTH_SERVICE_UNAVAILABLE"),
Type.Literal("AUTH_ENTRY_REJECTED"),
Type.Literal("AUTH_RATE_LIMITED"),
Type.Literal("AUTH_CSRF_INVALID"),
],
{ $id: "StableEngineeringErrorCode" },
);
+41
View File
@@ -82,8 +82,49 @@ export const UserSessionResponseSchema = Type.Object(
{ additionalProperties: false, $id: "UserSessionResponse" },
);
export const LoginSendRequestSchema = Type.Object(
{
email: Type.String({ maxLength: 320, pattern: emailPattern }),
},
{ additionalProperties: false, $id: "LoginSendRequest" },
);
export const LoginCompleteRequestSchema = Type.Object(
{
registration_id: Type.String({ pattern: uuidPattern }),
verification_code: Type.String({ pattern: "^[0-9]{6}$" }),
},
{ additionalProperties: false, $id: "LoginCompleteRequest" },
);
export const LoginCompleteResponseSchema = Type.Object(
{
audience: Type.Literal("user"),
credits: Type.Ref(CreditSummarySchema),
session_expires_at: Type.String({ pattern: isoTimestampPattern }),
status: Type.Literal("authenticated"),
user: Type.Ref(AuthenticatedUserSchema),
},
{ additionalProperties: false, $id: "LoginCompleteResponse" },
);
export const LogoutHeadersSchema = Type.Object(
{
"idempotency-key": Type.String({ maxLength: 200, minLength: 32, pattern: "^[A-Za-z0-9_-]+$" }),
"x-csrf-token": Type.String({ maxLength: 64, minLength: 43, pattern: "^[A-Za-z0-9_-]+$" }),
},
{ additionalProperties: true, $id: "LogoutHeaders" },
);
export const LogoutResponseSchema = Type.Object(
{ status: Type.Literal("logged_out") },
{ additionalProperties: false, $id: "LogoutResponse" },
);
export type RegistrationSendRequest = Static<typeof RegistrationSendRequestSchema>;
export type RegistrationSendResponse = Static<typeof RegistrationSendResponseSchema>;
export type RegistrationCompleteRequest = Static<typeof RegistrationCompleteRequestSchema>;
export type RegistrationCompleteResponse = Static<typeof RegistrationCompleteResponseSchema>;
export type UserSessionResponse = Static<typeof UserSessionResponseSchema>;
export type LoginSendRequest = Static<typeof LoginSendRequestSchema>;
export type LoginCompleteRequest = Static<typeof LoginCompleteRequestSchema>;