{"version":3,"file":"composable.cjs","names":["defaultConfigValues: AuthenticationConfig","refreshPromise: Promise<AuthenticationData> | null","refreshTimeout: ReturnType<typeof setTimeout> | null","memoryStorage","fetchOptions: RequestInit","body: Record<string, string>","request","getRequestUrl","authData: Record<string, string>","getAuthEndpoint"],"sources":["../../src/auth/composable.ts"],"sourcesContent":["import { getAuthEndpoint } from '../rest/utils/get-auth-endpoint.js';\nimport type { DirectusClient } from '../types/client.js';\nimport { getRequestUrl } from '../utils/get-request-url.js';\nimport { request } from '../utils/request.js';\nimport type {\n\tAuthenticationClient,\n\tAuthenticationConfig,\n\tAuthenticationData,\n\tAuthenticationMode,\n\tLDAPLoginPayload,\n\tLocalLoginPayload,\n\tLoginOptions,\n\tLoginPayload,\n\tLogoutOptions,\n\tRefreshOptions,\n} from './types.js';\nimport { memoryStorage } from './utils/memory-storage.js';\n\nconst defaultConfigValues: AuthenticationConfig = {\n\tmsRefreshBeforeExpires: 30000, // 30 seconds\n\tautoRefresh: true,\n};\n\n/**\n * setTimeout breaks with numbers bigger than 32bits.\n * This ensures that we don't try refreshing for tokens that last > 24 days.\n * Ref #4054\n */\nconst MAX_INT32 = 2 ** 31 - 1;\n\n/**\n * Creates a client to authenticate with Directus.\n *\n * @param mode AuthenticationMode\n * @param config The optional configuration.\n *\n * @returns A Directus authentication client.\n */\nexport const authentication = (mode: AuthenticationMode = 'cookie', config: Partial<AuthenticationConfig> = {}) => {\n\treturn <Schema>(client: DirectusClient<Schema>): AuthenticationClient<Schema> => {\n\t\tconst authConfig = { ...defaultConfigValues, ...config };\n\t\tlet refreshPromise: Promise<AuthenticationData> | null = null;\n\t\tlet refreshTimeout: ReturnType<typeof setTimeout> | null = null;\n\t\tconst storage = authConfig.storage ?? memoryStorage();\n\n\t\tconst resetStorage = async () =>\n\t\t\tstorage.set({ access_token: null, refresh_token: null, expires: null, expires_at: null });\n\n\t\tconst activeRefresh = async () => {\n\t\t\ttry {\n\t\t\t\tawait refreshPromise;\n\t\t\t} finally {\n\t\t\t\trefreshPromise = null;\n\t\t\t}\n\t\t};\n\n\t\tconst refreshIfExpired = async () => {\n\t\t\tconst authData = await storage.get();\n\n\t\t\tif (refreshPromise || !authData?.expires_at) {\n\t\t\t\treturn activeRefresh();\n\t\t\t}\n\n\t\t\tif (authData.expires_at < new Date().getTime() + authConfig.msRefreshBeforeExpires) {\n\t\t\t\trefresh().catch((_err) => {\n\t\t\t\t\t/* throw err; */\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn activeRefresh();\n\t\t};\n\n\t\tconst setCredentials = async (data: AuthenticationData) => {\n\t\t\tconst expires = data.expires ?? 0;\n\t\t\tdata.expires_at = new Date().getTime() + expires;\n\t\t\tawait storage.set(data);\n\n\t\t\tif (authConfig.autoRefresh && expires > authConfig.msRefreshBeforeExpires && expires < MAX_INT32) {\n\t\t\t\tif (refreshTimeout) clearTimeout(refreshTimeout);\n\n\t\t\t\trefreshTimeout = setTimeout(() => {\n\t\t\t\t\trefreshTimeout = null;\n\n\t\t\t\t\trefresh().catch((_err) => {\n\t\t\t\t\t\t/* throw err; */\n\t\t\t\t\t});\n\t\t\t\t}, expires - authConfig.msRefreshBeforeExpires);\n\t\t\t}\n\t\t};\n\n\t\tconst refresh = async (options: Omit<RefreshOptions, 'refresh_token'> = {}) => {\n\t\t\tconst awaitRefresh = async () => {\n\t\t\t\tconst authData = await storage.get();\n\n\t\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tif ('credentials' in authConfig) {\n\t\t\t\t\tfetchOptions.credentials = authConfig.credentials;\n\t\t\t\t}\n\n\t\t\t\tconst body: Record<string, string> = { mode: options.mode ?? mode };\n\n\t\t\t\tif (mode === 'json' && authData?.refresh_token) {\n\t\t\t\t\tbody['refresh_token'] = authData.refresh_token;\n\t\t\t\t}\n\n\t\t\t\tfetchOptions.body = JSON.stringify(body);\n\n\t\t\t\tconst requestUrl = getRequestUrl(client.url, '/auth/refresh');\n\n\t\t\t\tconst data = await request<AuthenticationData>(requestUrl.toString(), fetchOptions, client.globals.fetch);\n\n\t\t\t\tawait resetStorage();\n\t\t\t\tawait setCredentials(data);\n\n\t\t\t\treturn data;\n\t\t\t};\n\n\t\t\trefreshPromise = awaitRefresh();\n\n\t\t\treturn refreshPromise;\n\t\t};\n\n\t\tfunction login(payload: LocalLoginPayload, options?: LoginOptions): Promise<AuthenticationData>;\n\t\tfunction login(payload: LDAPLoginPayload, options?: LoginOptions): Promise<AuthenticationData>;\n\t\tasync function login(payload: LoginPayload, options: LoginOptions = {}) {\n\t\t\tconst authData: Record<string, string> = payload;\n\t\t\tif ('otp' in options) authData['otp'] = options.otp;\n\t\t\tauthData['mode'] = options.mode ?? mode;\n\n\t\t\tconst path = getAuthEndpoint(options.provider);\n\t\t\tconst requestUrl = getRequestUrl(client.url, path);\n\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(authData),\n\t\t\t};\n\n\t\t\tif ('credentials' in authConfig) {\n\t\t\t\tfetchOptions.credentials = authConfig.credentials;\n\t\t\t}\n\n\t\t\tconst data = await request<AuthenticationData>(requestUrl.toString(), fetchOptions, client.globals.fetch);\n\n\t\t\tawait resetStorage();\n\t\t\tawait setCredentials(data);\n\n\t\t\treturn data;\n\t\t}\n\n\t\treturn {\n\t\t\trefresh,\n\t\t\tlogin,\n\t\t\tasync logout(options: Omit<LogoutOptions, 'refresh_token'> = {}) {\n\t\t\t\tconst authData = await storage.get();\n\n\t\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tif ('credentials' in authConfig) {\n\t\t\t\t\tfetchOptions.credentials = authConfig.credentials;\n\t\t\t\t}\n\n\t\t\t\tconst body: Record<string, string> = { mode: options.mode ?? mode };\n\n\t\t\t\tif (mode === 'json' && authData?.refresh_token) {\n\t\t\t\t\tbody['refresh_token'] = authData.refresh_token;\n\t\t\t\t}\n\n\t\t\t\tfetchOptions.body = JSON.stringify(body);\n\n\t\t\t\tconst requestUrl = getRequestUrl(client.url, '/auth/logout');\n\t\t\t\tawait request(requestUrl.toString(), fetchOptions, client.globals.fetch);\n\n\t\t\t\tthis.stopRefreshing();\n\t\t\t\tawait resetStorage();\n\t\t\t},\n\t\t\tstopRefreshing() {\n\t\t\t\tif (refreshTimeout) {\n\t\t\t\t\tclearTimeout(refreshTimeout);\n\t\t\t\t}\n\t\t\t},\n\t\t\tasync getToken() {\n\t\t\t\tawait refreshIfExpired().catch(() => {\n\t\t\t\t\t/* fail gracefully */\n\t\t\t\t});\n\n\t\t\t\tconst data = await storage.get();\n\t\t\t\treturn data?.access_token ?? null;\n\t\t\t},\n\t\t\tasync setToken(access_token: string | null) {\n\t\t\t\treturn storage.set({\n\t\t\t\t\taccess_token,\n\t\t\t\t\trefresh_token: null,\n\t\t\t\t\texpires: null,\n\t\t\t\t\texpires_at: null,\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t};\n};\n"],"mappings":"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"}