auth

Main authentication module for my projects
git clone git://git.finwo.net/app/auth
Log | Files | Refs

api.ts (3902B)


      1 export interface RealmInfo {
      2   slug: string;
      3   display_name: string;
      4   branding: Record<string, string>;
      5   allow_session_duration_choice: boolean;
      6 }
      7 
      8 export interface ClientDiscovery {
      9   issuer: string;
     10   client_id: string;
     11   client_name: string;
     12   realm: string;
     13   display_name: string;
     14   branding: Record<string, string>;
     15   access_mode: string;
     16   virtual: boolean;
     17   require_pkce: boolean;
     18   allow_session_duration_choice: boolean;
     19 }
     20 
     21 export interface LoginResolution {
     22   realm: RealmInfo;
     23   next: 'password' | 'oidc';
     24   provider?: {
     25     slug: string;
     26     display_name: string;
     27   };
     28 }
     29 
     30 export interface PasswordLoginResult {
     31   realm: RealmInfo;
     32   user: {
     33     id: string;
     34     username: string;
     35     display_name: string | null;
     36   };
     37   expires_at: number;
     38   pending_auth_request: boolean;
     39 }
     40 
     41 export interface SessionScope {
     42   type: 'global' | 'realm' | 'client';
     43   host: string;
     44   realm_id: string | null;
     45   client_id: string | null;
     46 }
     47 
     48 export interface SessionAccount {
     49   public_id: string;
     50   active: boolean;
     51   user: {
     52     id: string;
     53     username: string;
     54     display_name: string | null;
     55   };
     56   created_at: number;
     57   expires_at: number;
     58 }
     59 
     60 export interface SessionInfo {
     61   scope: SessionScope;
     62   realm: RealmInfo | null;
     63   user: {
     64     id: string;
     65     username: string;
     66     display_name: string | null;
     67   };
     68   roles: string[];
     69   is_system_admin: boolean;
     70   expires_at: number;
     71   accounts: SessionAccount[];
     72 }
     73 
     74 export interface SelectSessionResult {
     75   ok: boolean;
     76   user: {
     77     id: string;
     78     username: string;
     79     display_name: string | null;
     80   };
     81   expires_at: number;
     82   pending_auth_request: boolean;
     83 }
     84 
     85 export interface ApiError extends Error {
     86   code?: string;
     87   status?: number;
     88 }
     89 
     90 async function request<T>(path: string, options: RequestInit = {}): Promise<T> {
     91   const response = await fetch(path, {
     92     credentials: 'same-origin',
     93     headers: {
     94       'content-type': 'application/json',
     95     },
     96     ...options,
     97   });
     98 
     99   let payload: any = null;
    100   try {
    101     payload = await response.json();
    102   } catch {
    103     payload = null;
    104   }
    105 
    106   if (!response.ok) {
    107     const error = new Error(payload?.error?.message || response.statusText) as ApiError;
    108     error.code = payload?.error?.code;
    109     error.status = response.status;
    110     throw error;
    111   }
    112 
    113   return payload as T;
    114 }
    115 
    116 export function getRealm(realm?: string | null): Promise<RealmInfo> {
    117   const query = realm ? `?realm=${encodeURIComponent(realm)}` : '';
    118   return request<RealmInfo>(`/api/v1/realm${query}`);
    119 }
    120 
    121 export function getClientDiscovery(clientId?: string | null): Promise<ClientDiscovery> {
    122   if (clientId) {
    123     return request<ClientDiscovery>(`/oidc/${encodeURIComponent(clientId)}/openid-configuration`);
    124   }
    125   return request<ClientDiscovery>('/oidc/openid-configuration');
    126 }
    127 
    128 export function resolveLogin(
    129   clientId: string,
    130   identifier: string
    131 ): Promise<LoginResolution> {
    132   return request<LoginResolution>('/api/v1/login/resolve', {
    133     method: 'POST',
    134     body: JSON.stringify({ client_id: clientId, identifier }),
    135   });
    136 }
    137 
    138 export function signInPassword(
    139   clientId: string,
    140   identifier: string,
    141   password: string,
    142   longSession: boolean
    143 ): Promise<PasswordLoginResult> {
    144   return request<PasswordLoginResult>('/api/v1/login/password', {
    145     method: 'POST',
    146     body: JSON.stringify({
    147       client_id: clientId,
    148       identifier,
    149       password,
    150       long_session: longSession,
    151     }),
    152   });
    153 }
    154 
    155 export function getSession(): Promise<SessionInfo> {
    156   return request<SessionInfo>('/api/v1/session');
    157 }
    158 
    159 export function selectSession(
    160   publicId: string,
    161   clientId?: string | null
    162 ): Promise<SelectSessionResult> {
    163   return request<SelectSessionResult>('/api/v1/session/select', {
    164     method: 'POST',
    165     body: JSON.stringify({
    166       public_id: publicId,
    167       client_id: clientId || undefined,
    168     }),
    169   });
    170 }
    171 
    172 export function signOut(): Promise<{ ok: boolean }> {
    173   return request('/api/v1/logout', { method: 'POST' });
    174 }