diff --git a/frontend/src/lib/generated/api.ts b/frontend/src/lib/generated/api.ts index 3bf2833d..764adce9 100644 --- a/frontend/src/lib/generated/api.ts +++ b/frontend/src/lib/generated/api.ts @@ -180,6 +180,22 @@ export interface paths { patch?: never; trace?: never; }; + "/api/users/{id}/force-logout": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["forceLogout"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/users/me/password": { parameters: { query?: never; @@ -580,6 +596,38 @@ export interface paths { patch?: never; trace?: never; }; + "/api/auth/logout": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["logout"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/auth/login": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["login"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/auth/forgot-password": { parameters: { query?: never; @@ -1849,7 +1897,7 @@ export interface components { status: string; /** Format: date-time */ createdAt: string; - shareableUrl?: string; + shareableUrl: string; }; GroupDTO: { name?: string; @@ -2011,13 +2059,17 @@ export interface components { lastName?: string; notifyOnMention?: boolean; }; + LoginRequest: { + email?: string; + password?: string; + }; ForgotPasswordRequest: { email?: string; }; ImportStatus: { /** @enum {string} */ state?: "IDLE" | "RUNNING" | "DONE" | "FAILED"; - message?: string; + statusCode?: string; /** Format: int32 */ processed?: number; /** Format: date-time */ @@ -2255,14 +2307,14 @@ export interface components { /** Format: int32 */ totalPages?: number; pageable?: components["schemas"]["PageableObject"]; - first?: boolean; - last?: boolean; /** Format: int32 */ size?: number; content?: components["schemas"]["NotificationDTO"][]; /** Format: int32 */ number?: number; sort?: components["schemas"]["SortObject"]; + first?: boolean; + last?: boolean; /** Format: int32 */ numberOfElements?: number; empty?: boolean; @@ -2410,7 +2462,7 @@ export interface components { }; ActivityFeedItemDTO: { /** @enum {string} */ - kind: "FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED" | "USER_CREATED" | "USER_DELETED" | "GROUP_MEMBERSHIP_CHANGED"; + kind: "FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED" | "USER_CREATED" | "USER_DELETED" | "GROUP_MEMBERSHIP_CHANGED" | "LOGIN_SUCCESS" | "LOGIN_FAILED" | "LOGOUT" | "ADMIN_FORCE_LOGOUT" | "LOGIN_RATE_LIMITED"; actor?: components["schemas"]["ActivityActorDTO"]; /** Format: uuid */ documentId: string; @@ -2954,6 +3006,30 @@ export interface operations { }; }; }; + forceLogout: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "*/*": { + [key: string]: unknown; + }; + }; + }; + }; + }; changePassword: { parameters: { query?: never; @@ -3547,6 +3623,7 @@ export interface operations { query?: never; header?: never; path: { + documentId: string; blockId: string; }; cookie?: never; @@ -3597,6 +3674,7 @@ export interface operations { header?: never; path: { documentId: string; + blockId: string; commentId: string; }; cookie?: never; @@ -3791,6 +3869,48 @@ export interface operations { }; }; }; + logout: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + login: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["LoginRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "*/*": components["schemas"]["AppUser"]; + }; + }; + }; + }; forgotPassword: { parameters: { query?: never; @@ -4985,7 +5105,7 @@ export interface operations { [name: string]: unknown; }; content: { - "*/*": components["schemas"]["DocumentDensityResult"]; + "application/json": components["schemas"]["DocumentDensityResult"]; }; }; }; @@ -5061,7 +5181,7 @@ export interface operations { query?: { limit?: number; /** @description Filter by audit kinds; omit for all rollup-eligible kinds */ - kinds?: ("FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED" | "USER_CREATED" | "USER_DELETED" | "GROUP_MEMBERSHIP_CHANGED")[]; + kinds?: ("FILE_UPLOADED" | "STATUS_CHANGED" | "METADATA_UPDATED" | "TEXT_SAVED" | "BLOCK_REVIEWED" | "ANNOTATION_CREATED" | "COMMENT_ADDED" | "MENTION_CREATED" | "USER_CREATED" | "USER_DELETED" | "GROUP_MEMBERSHIP_CHANGED" | "LOGIN_SUCCESS" | "LOGIN_FAILED" | "LOGOUT" | "ADMIN_FORCE_LOGOUT" | "LOGIN_RATE_LIMITED")[]; }; header?: never; path?: never; diff --git a/frontend/src/routes/admin/invites/+page.server.ts b/frontend/src/routes/admin/invites/+page.server.ts index e16fc279..9123de94 100644 --- a/frontend/src/routes/admin/invites/+page.server.ts +++ b/frontend/src/routes/admin/invites/+page.server.ts @@ -4,21 +4,7 @@ import { getErrorMessage } from '$lib/shared/errors'; import type { Actions, PageServerLoad } from './$types'; import type { components } from '$lib/generated/api'; -// The spec marks shareableUrl optional but the backend always populates it. -// Keeping the required shape here avoids null-guarding throughout the page component. -export interface InviteListItem { - id: string; - code: string; - displayCode: string; - label?: string; - useCount: number; - maxUses?: number; - expiresAt?: string; - revoked: boolean; - status: string; - createdAt: string; - shareableUrl: string; -} +export type InviteListItem = components['schemas']['InviteListItemDTO']; export type UserGroup = components['schemas']['UserGroup']; const VALID_STATUSES = ['ACTIVE', 'REVOKED', 'EXPIRED'] as const; @@ -42,8 +28,7 @@ export const load: PageServerLoad = async ({ url, fetch }) => { const code = (invitesResult.error as unknown as { code?: string })?.code; loadError = code ?? 'INTERNAL_ERROR'; } else { - // TODO: remove cast after next npm run generate:api — shareableUrl is now @Schema(requiredMode=REQUIRED) - invites = (invitesResult.data ?? []) as unknown as InviteListItem[]; + invites = (invitesResult.data ?? []) as InviteListItem[]; } let groups: UserGroup[] = []; @@ -81,8 +66,7 @@ export const actions = { return fail(result.response.status, { createError: code ?? 'INTERNAL_ERROR' }); } - // TODO: remove cast after next npm run generate:api — shareableUrl is now @Schema(requiredMode=REQUIRED) - return { created: result.data! as unknown as InviteListItem }; + return { created: result.data! as InviteListItem }; }, revoke: async ({ request, fetch }) => {