import {z} from 'zod' export type UUID4 = unknown; export type AuditLogTypes = 'user_logged_out' | 'password_set_succeeded' | 'password_set_failed' | 'password_login_succeeded' | 'password_login_failed' | 'passcode_login_init_succeeded' | 'passcode_login_init_failed' | 'passcode_login_final_succeeded' | 'passcode_login_final_failed' | 'webauthn_registration_init_succeeded' | 'webauthn_registration_init_failed' | 'webauthn_registration_final_succeeded' | 'webauthn_registration_final_failed' | 'webauthn_authentication_init_succeeded' | 'webauthn_authentication_init_failed' | 'webauthn_authentication_final_succeeded' | 'webauthn_authentication_final_failed' | 'webauthn_credential_updated' | 'webauthn_credential_deleted' | 'thirdparty_signup_succeeded' | 'thirdparty_signin_succeeded' | 'thirdparty_linking_succeeded' | 'thirdparty_signin_signup_failed' | 'token_exchange_succeeded' | 'token_exchange_failed' | 'user_created' | 'email_created' | 'email_verified' | 'email_deleted' | 'primary_email_changed' | 'user_deleted' | 'login_success' | 'login_failure' | 'otp_created' | 'passkey_created' | 'passkey_deleted' | 'security_key_created' | 'username_changed' | 'username_deleted' | 'password_changed' | 'password_deleted'; export type GetApiAuditLogsArgs = {page?: number | undefined, per_page?: number | undefined, start_time?: string | undefined, end_time?: string | undefined, actor_user_id?: UUID4 | undefined, actor_email?: string | undefined, meta_source_ip?: (string | string) | undefined, q?: string | undefined, type?: Array | undefined}; export type GetApiAuditLogsOptions = {baseUrl?: string | undefined, BearerApiKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const uUID4 = z.string(); export const auditLogTypes = z.enum(["user_logged_out", "password_set_succeeded", "password_set_failed", "password_login_succeeded", "password_login_failed", "passcode_login_init_succeeded", "passcode_login_init_failed", "passcode_login_final_succeeded", "passcode_login_final_failed", "webauthn_registration_init_succeeded", "webauthn_registration_init_failed", "webauthn_registration_final_succeeded", "webauthn_registration_final_failed", "webauthn_authentication_init_succeeded", "webauthn_authentication_init_failed", "webauthn_authentication_final_succeeded", "webauthn_authentication_final_failed", "webauthn_credential_updated", "webauthn_credential_deleted", "thirdparty_signup_succeeded", "thirdparty_signin_succeeded", "thirdparty_linking_succeeded", "thirdparty_signin_signup_failed", "token_exchange_succeeded", "token_exchange_failed", "user_created", "email_created", "email_verified", "email_deleted", "primary_email_changed", "user_deleted", "login_success", "login_failure", "otp_created", "passkey_created", "passkey_deleted", "security_key_created", "username_changed", "username_deleted", "password_changed", "password_deleted"]); export const auditLog = z.object({id: uUID4, type: auditLogTypes, error: z.string().optional(), meta_http_request_id: z.string(), meta_source_ip: z.string(), meta_user_agent: z.string(), actor_user_id: uUID4.optional(), actor_email: z.string().optional(), created_at: z.string()}); export const getApiAuditLogsResponse = z.array(auditLog); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get a list of audit logs * * GET /audit_logs */ export const getApiAuditLogs = async (args: GetApiAuditLogsArgs, options?: GetApiAuditLogsOptions) => { const {baseUrl = "https://.hanko.io/admin", fetch: fetchFn = fetch, BearerApiKeyAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.page != null) query.append("page", String(args.page)) if (args.per_page != null) query.append("per_page", String(args.per_page)) if (args.start_time != null) query.append("start_time", String(args.start_time)) if (args.end_time != null) query.append("end_time", String(args.end_time)) if (args.actor_user_id != null) query.append("actor_user_id", String(args.actor_user_id)) if (args.actor_email != null) query.append("actor_email", String(args.actor_email)) if (args.meta_source_ip != null) query.append("meta_source_ip", String(args.meta_source_ip)) if (args.q != null) query.append("q", String(args.q)) for (const item of args.type ?? []) query.append("type", String(item)) if (BearerApiKeyAuth !== undefined) headers.set('authorization', `Bearer ${BearerApiKeyAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/audit_logs${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(getApiAuditLogsResponse, await res.json()) };