feat: implement TASK-WP1-02 login sessions
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// Generated from openapi/openapi.json. Do not edit by hand.
|
||||
|
||||
import type { RegistrationCompleteResponse, RegistrationCompleteRequest, UserSessionResponse, RegistrationSendResponse, RegistrationSendRequest } from "./types.gen.js";
|
||||
import type { LoginCompleteResponse, LoginCompleteRequest, RegistrationCompleteResponse, RegistrationCompleteRequest, UserSessionResponse, LogoutResponse, RegistrationSendResponse, LoginSendRequest, RegistrationSendRequest } from "./types.gen.js";
|
||||
|
||||
export interface ClientOptions { baseUrl?: string; fetch?: typeof globalThis.fetch; headers?: HeadersInit; }
|
||||
|
||||
@@ -45,6 +45,15 @@ export async function checkBrowserSupport(body: {
|
||||
}>;
|
||||
}
|
||||
|
||||
export async function completeLogin(body: LoginCompleteRequest, options: ClientOptions = {}): Promise<LoginCompleteResponse> {
|
||||
const request = options.fetch ?? globalThis.fetch;
|
||||
const headers = new Headers(options.headers);
|
||||
headers.set("Content-Type", "application/json");
|
||||
const response = await request(`${options.baseUrl ?? ""}/api/v1/auth/login/complete`, { body: JSON.stringify(body), method: "POST", headers });
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
return response.json() as Promise<LoginCompleteResponse>;
|
||||
}
|
||||
|
||||
export async function completeRegistration(body: RegistrationCompleteRequest, options: ClientOptions = {}): Promise<RegistrationCompleteResponse> {
|
||||
const request = options.fetch ?? globalThis.fetch;
|
||||
const headers = new Headers(options.headers);
|
||||
@@ -104,6 +113,22 @@ export async function getUserSession(options: ClientOptions = {}): Promise<UserS
|
||||
return response.json() as Promise<UserSessionResponse>;
|
||||
}
|
||||
|
||||
export async function logoutUser(options: ClientOptions = {}): Promise<LogoutResponse> {
|
||||
const request = options.fetch ?? globalThis.fetch;
|
||||
const response = await request(`${options.baseUrl ?? ""}/api/v1/auth/logout`, { method: "POST", headers: options.headers ?? {} });
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
return response.json() as Promise<LogoutResponse>;
|
||||
}
|
||||
|
||||
export async function sendLoginCode(body: LoginSendRequest, options: ClientOptions = {}): Promise<RegistrationSendResponse> {
|
||||
const request = options.fetch ?? globalThis.fetch;
|
||||
const headers = new Headers(options.headers);
|
||||
headers.set("Content-Type", "application/json");
|
||||
const response = await request(`${options.baseUrl ?? ""}/api/v1/auth/login/send`, { body: JSON.stringify(body), method: "POST", headers });
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
return response.json() as Promise<RegistrationSendResponse>;
|
||||
}
|
||||
|
||||
export async function sendRegistrationCode(body: RegistrationSendRequest, options: ClientOptions = {}): Promise<RegistrationSendResponse> {
|
||||
const request = options.fetch ?? globalThis.fetch;
|
||||
const headers = new Headers(options.headers);
|
||||
|
||||
@@ -78,7 +78,7 @@ export type ErrorDetails = {
|
||||
|
||||
export type ErrorEnvelope = {
|
||||
"error": {
|
||||
"code": "BROWSER_UNSUPPORTED" | "MODEL_CONFIG_VERSION_CONFLICT" | "MODEL_DEFAULT_REPLACEMENT_REQUIRED" | "MODEL_DEFAULT_REPLACEMENT_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_CONFLICT" | "PRIVATE_CONTENT_NOTICE_ACK_REQUIRED" | "ASSET_HISTORY_REFERENCE_CONFLICT" | "ASSET_CLEANUP_CANDIDATE_STALE" | "STORAGE_CAPACITY_EXCEEDED" | "REGISTRATION_REJECTED" | "REGISTRATION_REQUEST_INVALID" | "IDEMPOTENCY_KEY_CONFLICT" | "AUTH_SESSION_INVALID" | "AUTH_SERVICE_UNAVAILABLE";
|
||||
"code": "BROWSER_UNSUPPORTED" | "MODEL_CONFIG_VERSION_CONFLICT" | "MODEL_DEFAULT_REPLACEMENT_REQUIRED" | "MODEL_DEFAULT_REPLACEMENT_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_CONFLICT" | "PRIVATE_CONTENT_NOTICE_ACK_REQUIRED" | "ASSET_HISTORY_REFERENCE_CONFLICT" | "ASSET_CLEANUP_CANDIDATE_STALE" | "STORAGE_CAPACITY_EXCEEDED" | "REGISTRATION_REJECTED" | "REGISTRATION_REQUEST_INVALID" | "IDEMPOTENCY_KEY_CONFLICT" | "AUTH_SESSION_INVALID" | "AUTH_SERVICE_UNAVAILABLE" | "AUTH_ENTRY_REJECTED" | "AUTH_RATE_LIMITED" | "AUTH_CSRF_INVALID";
|
||||
"correlation_id": string;
|
||||
"details": {
|
||||
"capacity_status"?: "normal" | "warning" | "critical" | "full" | "unavailable";
|
||||
@@ -102,6 +102,32 @@ export type ErrorEnvelope = {
|
||||
|
||||
export type GenerationErrorCategory = "upstream_timeout" | "upstream_failed" | "safety_rejected" | "model_disabled" | "gateway_balance_insufficient" | "gateway_contract_invalid" | "reference_invalid" | "unknown_retryable" | "unknown_non_retryable";
|
||||
|
||||
export type LoginCompleteRequest = {
|
||||
"registration_id": string;
|
||||
"verification_code": string;
|
||||
};
|
||||
|
||||
export type LoginCompleteResponse = {
|
||||
"audience": "user";
|
||||
"credits": CreditSummary;
|
||||
"session_expires_at": string;
|
||||
"status": "authenticated";
|
||||
"user": AuthenticatedUser;
|
||||
};
|
||||
|
||||
export type LoginSendRequest = {
|
||||
"email": string;
|
||||
};
|
||||
|
||||
export type LogoutHeaders = {
|
||||
"idempotency-key": string;
|
||||
"x-csrf-token": string;
|
||||
};
|
||||
|
||||
export type LogoutResponse = {
|
||||
"status": "logged_out";
|
||||
};
|
||||
|
||||
export type ModelConfigSseEvent = {
|
||||
"config_set_version": number;
|
||||
"entity_ref": string;
|
||||
@@ -170,7 +196,7 @@ export type SseEvent = {
|
||||
"runtime_availability_version": number;
|
||||
};
|
||||
|
||||
export type StableEngineeringErrorCode = "BROWSER_UNSUPPORTED" | "MODEL_CONFIG_VERSION_CONFLICT" | "MODEL_DEFAULT_REPLACEMENT_REQUIRED" | "MODEL_DEFAULT_REPLACEMENT_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_CONFLICT" | "PRIVATE_CONTENT_NOTICE_ACK_REQUIRED" | "ASSET_HISTORY_REFERENCE_CONFLICT" | "ASSET_CLEANUP_CANDIDATE_STALE" | "STORAGE_CAPACITY_EXCEEDED" | "REGISTRATION_REJECTED" | "REGISTRATION_REQUEST_INVALID" | "IDEMPOTENCY_KEY_CONFLICT" | "AUTH_SESSION_INVALID" | "AUTH_SERVICE_UNAVAILABLE";
|
||||
export type StableEngineeringErrorCode = "BROWSER_UNSUPPORTED" | "MODEL_CONFIG_VERSION_CONFLICT" | "MODEL_DEFAULT_REPLACEMENT_REQUIRED" | "MODEL_DEFAULT_REPLACEMENT_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_INVALID" | "MODEL_RECOMMENDATION_PRIORITY_CONFLICT" | "PRIVATE_CONTENT_NOTICE_ACK_REQUIRED" | "ASSET_HISTORY_REFERENCE_CONFLICT" | "ASSET_CLEANUP_CANDIDATE_STALE" | "STORAGE_CAPACITY_EXCEEDED" | "REGISTRATION_REJECTED" | "REGISTRATION_REQUEST_INVALID" | "IDEMPOTENCY_KEY_CONFLICT" | "AUTH_SESSION_INVALID" | "AUTH_SERVICE_UNAVAILABLE" | "AUTH_ENTRY_REJECTED" | "AUTH_RATE_LIMITED" | "AUTH_CSRF_INVALID";
|
||||
|
||||
export type StateSseEvent = {
|
||||
"entity_ref": string;
|
||||
|
||||
Reference in New Issue
Block a user