aui-auth 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/accounts.d.ts +2 -2
- package/dist/accounts.js +1 -1
- package/dist/cache-Cw1PrZ8f.js +1 -0
- package/dist/database/index.d.ts +2 -2
- package/dist/database/index.js +1 -1
- package/dist/database/pg.d.ts +1 -1
- package/dist/database/pg.js +1 -1
- package/dist/database/redis.d.ts +1 -1
- package/dist/database/redis.js +1 -1
- package/dist/device.d.ts +2 -70
- package/dist/device.js +1 -1
- package/dist/errors-369IR3ml.d.ts +16 -0
- package/dist/errors-CLA_uQFw.js +1 -0
- package/dist/fetch-BTZqr_UF.d.ts +3 -0
- package/dist/fetch-n3F2M2nn.js +1 -0
- package/dist/{index-CNcSwzgU.d.ts → index-ByH9jmJH.d.ts} +16 -17
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/next.d.ts +2 -2
- package/dist/next.js +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/{types-B13HPcs5.d.ts → types-BSF1k96p.d.ts} +3 -12
- package/dist/verify.d.ts +2 -51
- package/dist/verify.js +1 -1
- package/package.json +4 -1
- package/dist/cache-vq-5GFN7.js +0 -1
- package/dist/encoding-BhmNmloC.js +0 -1
- package/dist/errors-C7IxbL16.js +0 -1
- package/dist/errors-DpQsDn4O.d.ts +0 -30
- package/dist/fetch-C0ojJu8c.d.ts +0 -9
- package/dist/fetch-CM1mVzPm.js +0 -1
- package/dist/oidc-qInr-2mE.js +0 -1
package/README.md
CHANGED
|
@@ -2,4 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Server-side sessions for web apps that sign in through assistant-ui accounts: OpenID Connect with PKCE, tokens kept in the app's own database, single-flight refresh, and an encrypted cache cookie. Internal to assistant-ui; the manual is `docs/first-party-auth.md` and the design is `packages/aui-auth/ARCHITECTURE.md` in the assistant-internal repository.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The device grant, token verification and the token client under the sessions come from [authical](https://www.npmjs.com/package/authical), re-exported under the accounts names. An application outside assistant-ui uses authical itself.
|
|
6
|
+
|
|
7
|
+
Entry points: `aui-auth`, `aui-auth/accounts`, `aui-auth/next`, `aui-auth/device`, `aui-auth/verify`, `aui-auth/database`, `aui-auth/database/pg`, `aui-auth/database/redis`, `aui-auth/testing`.
|
package/dist/accounts.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as RevalidateInput, m as SignInInput } from "./types-
|
|
2
|
-
import { t as AccountsFetchOptions } from "./fetch-
|
|
1
|
+
import { f as RevalidateInput, m as SignInInput } from "./types-BSF1k96p.js";
|
|
2
|
+
import { t as AccountsFetchOptions } from "./fetch-BTZqr_UF.js";
|
|
3
3
|
//#region src/accounts/organizations.d.ts
|
|
4
4
|
type AccountsOrganization = {
|
|
5
5
|
id: string;
|
package/dist/accounts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,t}from"./errors-
|
|
1
|
+
import{i as e,t}from"./errors-CLA_uQFw.js";import{n}from"./fetch-n3F2M2nn.js";async function r(e,r){let i=await n(e,`/api/oidc/organizations`,{headers:{Authorization:`Bearer ${r}`}});if(!i.ok)throw new t(`Failed to load organizations: ${i.status}`,i.status);return await i.json()}function i(e,t){if(t){let n=e.find(e=>e.slug===t);if(n)return n}return e[0]??null}function a(e){let[,t]=new URL(e,`http://localhost`).pathname.split(`/`);return t&&t!==`org`?t:null}function o(t){let n=t.preferredSlug??a;async function o(e){return{activeOrganization:i(await r(t,e.accessToken),n(e.redirectPath))}}async function s(n){let a;try{a=await r(t,n.accessToken)}catch(t){if(e(t))return null;throw t}let o=n.session.data.activeOrganization;if(!o)return{activeOrganization:i(a)};let s=a.find(e=>e.id===o.id)??null;return s?{activeOrganization:s}:null}return{onSignIn:o,onRevalidate:s}}function s(e){return e===`owner`||e===`admin`}async function c(e,t,n){let r=t=>t.slug===e||t.id===e;return e===void 0||t&&r(t)?t:(await n()).find(r)??null}function l(e){return`id`in e?`org_id=${encodeURIComponent(e.id)}`:`org_slug=${encodeURIComponent(e.slug)}`}function u(e){let n=e,r=e=>{let r=n?.[e];if(typeof r!=`string`)throw new t(`Accounts project has no ${e}`,502);return r},i=e=>{let n=new Date(r(e));if(Number.isNaN(n.getTime()))throw new t(`Accounts project has no ${e}`,502);return n};return{id:r(`id`),organizationId:r(`organizationId`),slug:r(`slug`),name:r(`name`),color:r(`color`),icon:typeof n?.icon==`string`?n.icon:null,plan:r(`plan`),createdBy:r(`createdBy`),updatedBy:r(`updatedBy`),createdAt:i(`createdAt`),updatedAt:i(`updatedAt`),viewerRole:typeof n?.viewerRole==`string`?n.viewerRole:null}}async function d(e,r,i,a={},o=[]){let s=await n(e,i,{method:a.method,headers:{Authorization:`Bearer ${r}`,...a.body===void 0?void 0:{"Content-Type":`application/json`}},body:a.body===void 0?void 0:JSON.stringify(a.body)});if(s.ok||o.includes(s.status))return s;throw new t(`Accounts request ${i} failed: ${s.status}`,s.status)}async function f(e,t,n){let r=await d(e,t,`/api/projects?${l(n)}`,{},[403,404]);return r.ok?(await r.json()).map(u):[]}async function p(e,t,n,r){let i=await d(e,t,`/api/projects/${encodeURIComponent(r)}?${l(n)}`,{},[403,404]);return i.ok?u(await i.json()):null}async function m(e,t,n,r){let i=await d(e,t,`/api/projects`,{method:`POST`,body:{...`id`in n?{org_id:n.id}:{org_slug:n.slug},name:r.name,slug:r.slug}},[409]);return i.status===409?{reason:`duplicate`}:u(await i.json())}async function h(e,t,n,r,i){let a=await d(e,t,`/api/projects/${encodeURIComponent(r)}?${l(n)}`,{method:`PATCH`,body:i},[404,409]);return a.status===409?{reason:`duplicate`}:a.status===404?null:u(await a.json())}export{m as createProject,r as fetchOrganizations,p as fetchProject,f as fetchProjects,s as isOrganizationAdmin,o as organizationHooks,a as preferredOrganizationSlug,c as resolveRouteOrganization,i as selectOrganization,h as updateProject};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as e}from"./errors-CLA_uQFw.js";function t(e){if(!e)return;let t=e.split(`,`);return t[t.length-1].trim()||void 0}function n(e){let n=new URL(e.url);return`${t(e.headers.get(`x-forwarded-proto`))||n.protocol.replace(`:`,``)}://${t(e.headers.get(`x-forwarded-host`))||e.headers.get(`host`)||n.host}`}function r(e){return new URL(e).protocol===`https:`}function i(e,t){return t?`__Secure-${e}`:e}function a(e){let t=new Map;if(!e)return t;for(let n of e.split(`;`)){let e=n.indexOf(`=`);if(e===-1)continue;let r=n.slice(0,e).trim();!r||t.has(r)||t.set(r,n.slice(e+1).trim())}return t}function o(e,t){let n=a(e.headers.get(`cookie`));return n.get(i(t,!0))||n.get(i(t,!1))||null}function s(e,t,n,r){let i=[`${e}=${t}`,`Path=/`,`HttpOnly`,`SameSite=Lax`,`Max-Age=${r}`];return n&&i.push(`Secure`),i.join(`; `)}function c(e){let[t,...n]=e.split(`;`).map(e=>e.trim()),r=t.indexOf(`=`);if(r<1)return null;let i=new Map(n.map(e=>{let[t,n=``]=e.split(`=`);return[t.toLowerCase(),n]}));return{name:t.slice(0,r),value:t.slice(r+1),options:{path:i.get(`path`)||`/`,httpOnly:i.has(`httponly`),sameSite:`lax`,secure:i.has(`secure`),maxAge:Number(i.get(`max-age`)??0)}}}function l(e,t,n,a,o){let c=r(a);e.append(`set-cookie`,s(i(t,c),n,c,Math.floor(o/1e3)))}function u(e,t){if(t.length===0)return;let n=a(e.get(`cookie`));for(let e of t){let t=c(e);t&&(t.value?n.set(t.name,t.value):n.delete(t.name))}e.set(`cookie`,[...n].map(([e,t])=>`${e}=${t}`).join(`; `))}function d(e,t){let n=t===void 0||r(t);return[n,!n].map(t=>s(i(e,t),``,t,0))}function f(e,t,n){for(let r of d(t,n))e.append(`set-cookie`,r)}function p(e,t=307){return new Response(null,{status:t,headers:{location:e.toString()}})}function m(e,t){return`${e}_flow_${t}`}function h(e){return btoa(JSON.stringify(e)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function g(e){if(!e)return null;try{let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=JSON.parse(atob(t));return typeof n.verifier==`string`?{verifier:n.verifier,redirectPath:typeof n.redirectPath==`string`?n.redirectPath:`/`,silent:n.silent===!0}:null}catch{return null}}function _(e,t){if(!e)return`/`;let n;try{n=new URL(e,t)}catch{return`/`}return n.origin!==t||n.pathname.startsWith(`//`)?`/`:`${n.pathname}${n.search}${n.hash}`}function v(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function y(e){return v(crypto.getRandomValues(new Uint8Array(e)))}async function b(e){let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return v(new Uint8Array(t))}const x=4096;function S(e){return`${e}_cache`}function C(e,t,n){if(!e.cache)return 0;let{lifetimes:r}=e,i=Math.min(t.lastValidatedAt+r.revalidateIntervalMs,t.tokens.accessTokenExpiresAt-r.refreshBeforeExpiryMs);return Math.min(e.cache.maxAgeMs,(i>n?i:n+r.retryIntervalMs)-n,t.createdAt+r.absoluteMaxAgeMs-n,t.lastValidatedAt+r.idleMaxAgeMs-n)}async function w(e,t,n){if(!e.cache)return null;let r=C(e,t,n);if(r<1e3)return null;let i={v:1,id:t.id,u:t.user,d:t.data,at:t.tokens.accessToken,ate:t.tokens.accessTokenExpiresAt,ca:t.createdAt,lv:t.lastValidatedAt,exp:n+r};return{value:await(await e.cache.codec()).encrypt(JSON.stringify(i)),maxAgeMs:r}}async function T(e,t,n,r){if(!e.cache||!t||!n)return null;let i;try{let n=await e.cache.codec();i=JSON.parse(await n.decrypt(t))}catch{return null}return i.v!==1||typeof i.exp!=`number`||i.exp<=r||i.id!==await b(n)?null:{id:i.id,user:i.u,tokens:{accessToken:i.at,refreshToken:null,idToken:null,accessTokenExpiresAt:i.ate},data:i.d,createdAt:i.ca,lastValidatedAt:i.lv,refreshLeaseUntil:null}}async function E(t,n,a,o){try{let e=await w(t,n,o);if(!e)return null;let c=r(a),l=s(i(S(t.cookieName),c),e.value,c,Math.floor(e.maxAgeMs/1e3));if(l.length>x)throw Error(`Cache cookie is ${l.length} bytes and browsers drop cookies over ${x}; the session data is too large to cache`);return l}catch(n){return e(t,`cache_cookie`,n),null}}function D(e,t){return e.cache?d(S(e.cookieName),t):[]}export{p as _,y as a,s as b,d as c,h as d,m as f,o as g,c as h,T as i,i as l,a as m,S as n,b as o,u as p,E as r,f as s,D as t,g as u,n as v,l as x,_ as y};
|
package/dist/database/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { n as createAesGcmCodec, t as SessionCodec } from "../codec-BPnk_EfF.js";
|
|
2
|
-
import { c as AccountsSessionPatch, d as AccountsUser, l as AccountsSessionStore, p as SessionSweepCutoffs, s as AccountsSession, u as AccountsTokens } from "../types-
|
|
3
|
-
import { r as SessionDecodeError } from "../errors-
|
|
2
|
+
import { c as AccountsSessionPatch, d as AccountsUser, l as AccountsSessionStore, p as SessionSweepCutoffs, s as AccountsSession, u as AccountsTokens } from "../types-BSF1k96p.js";
|
|
3
|
+
import { r as SessionDecodeError } from "../errors-369IR3ml.js";
|
|
4
4
|
export { type AccountsSession, type AccountsSessionPatch, type AccountsSessionStore, type AccountsTokens, type AccountsUser, type SessionCodec, SessionDecodeError, type SessionSweepCutoffs, createAesGcmCodec };
|
package/dist/database/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"../errors-
|
|
1
|
+
import{r as e}from"../errors-CLA_uQFw.js";import{t}from"../codec-IJ2JySkR.js";export{e as SessionDecodeError,t as createAesGcmCodec};
|
package/dist/database/pg.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as SessionCodec } from "../codec-BPnk_EfF.js";
|
|
2
|
-
import { l as AccountsSessionStore } from "../types-
|
|
2
|
+
import { l as AccountsSessionStore } from "../types-BSF1k96p.js";
|
|
3
3
|
//#region src/database/pg.d.ts
|
|
4
4
|
type PgQuery = (text: string, values?: unknown[]) => Promise<{
|
|
5
5
|
rows: Record<string, unknown>[];
|
package/dist/database/pg.js
CHANGED
package/dist/database/redis.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as SessionCodec } from "../codec-BPnk_EfF.js";
|
|
2
|
-
import { l as AccountsSessionStore } from "../types-
|
|
2
|
+
import { l as AccountsSessionStore } from "../types-BSF1k96p.js";
|
|
3
3
|
//#region src/database/redis.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* The slice of a Redis client this store uses, so the package takes no Redis
|
package/dist/database/redis.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"../errors-
|
|
1
|
+
import{r as e}from"../errors-CLA_uQFw.js";const t=`refreshLeaseUntil`,n=`
|
|
2
2
|
local key, checkLease, expectedLease, ttl = KEYS[1], ARGV[1], ARGV[2], ARGV[3]
|
|
3
3
|
if redis.call('EXISTS', key) == 0 then return 0 end
|
|
4
4
|
if checkLease == '1' then
|
package/dist/device.d.ts
CHANGED
|
@@ -1,70 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/device/index.d.ts
|
|
4
|
-
declare const DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
|
|
5
|
-
type DeviceLoginConfig = {
|
|
6
|
-
issuer: string;
|
|
7
|
-
clientId: string;
|
|
8
|
-
scope?: string;
|
|
9
|
-
/**
|
|
10
|
-
* The resource the tokens are minted for; `<issuer>/api/auth` unless set,
|
|
11
|
-
* `false` for opaque tokens. Sent with the device code request, so the
|
|
12
|
-
* approval binds it, and again when the code is redeemed.
|
|
13
|
-
*/
|
|
14
|
-
audience?: string | false;
|
|
15
|
-
/** How close to expiry `ensureFresh` refreshes; five minutes by default. */
|
|
16
|
-
refreshBeforeExpiryMs?: number;
|
|
17
|
-
requestTimeoutMs?: number;
|
|
18
|
-
fetch?: typeof fetch;
|
|
19
|
-
now?: () => number;
|
|
20
|
-
/** The wait between polls, for tests; a plain timer otherwise. */
|
|
21
|
-
sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
22
|
-
};
|
|
23
|
-
type DeviceAuthorization = {
|
|
24
|
-
deviceCode: string;
|
|
25
|
-
userCode: string;
|
|
26
|
-
verificationUri: string;
|
|
27
|
-
verificationUriComplete: string;
|
|
28
|
-
expiresAt: number;
|
|
29
|
-
intervalMs: number;
|
|
30
|
-
/** The resource the approval binds; null when the provider refused it. */
|
|
31
|
-
resource: string | null;
|
|
32
|
-
};
|
|
33
|
-
type DeviceCredentials = {
|
|
34
|
-
user: AccountsUser;
|
|
35
|
-
tokens: AccountsTokens;
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* The RFC 8628 device authorization grant against accounts, for a CLI or any
|
|
39
|
-
* process without a browser of its own: `start` asks for a code, the person
|
|
40
|
-
* approves it on the accounts device page, `wait` polls the token endpoint
|
|
41
|
-
* until the approval lands, and `refresh` and `ensureFresh` keep the token set
|
|
42
|
-
* alive afterwards. The credentials the flow hands back belong to the device,
|
|
43
|
-
* not to the browser session that approved them, so they outlive it. Where
|
|
44
|
-
* they are stored is the app's decision.
|
|
45
|
-
*/
|
|
46
|
-
declare function createDeviceLogin(config: DeviceLoginConfig): {
|
|
47
|
-
/** Asks accounts for a device code and the user code to show. */
|
|
48
|
-
start(): Promise<DeviceAuthorization>;
|
|
49
|
-
/**
|
|
50
|
-
* Polls until the person approves, at the interval accounts asked for
|
|
51
|
-
* (`slow_down` adds five seconds), and resolves with the token set and the
|
|
52
|
-
* profile from userinfo. Rejects with `OAuthTokenError` `access_denied`
|
|
53
|
-
* when the person refuses and `expired_token` when nobody answers in time.
|
|
54
|
-
*/
|
|
55
|
-
wait(authorization: DeviceAuthorization, options?: {
|
|
56
|
-
signal?: AbortSignal;
|
|
57
|
-
}): Promise<DeviceCredentials>;
|
|
58
|
-
/**
|
|
59
|
-
* Spends the refresh token for a new token set. accounts rotates the
|
|
60
|
-
* refresh token on every use, so the credentials this resolves with
|
|
61
|
-
* replace the ones passed in. A rejection that `isAccessDenied` accepts
|
|
62
|
-
* means the login is over; anything else says nothing about it.
|
|
63
|
-
*/
|
|
64
|
-
refresh(credentials: DeviceCredentials): Promise<DeviceCredentials>;
|
|
65
|
-
/** The credentials as they are while the access token has time left, refreshed otherwise. */
|
|
66
|
-
ensureFresh(credentials: DeviceCredentials): Promise<DeviceCredentials>;
|
|
67
|
-
};
|
|
68
|
-
type DeviceLogin = ReturnType<typeof createDeviceLogin>;
|
|
69
|
-
//#endregion
|
|
70
|
-
export { AccountsRequestError, type AccountsTokens, type AccountsUser, DEVICE_CODE_GRANT_TYPE, DeviceAuthorization, DeviceCredentials, DeviceLogin, DeviceLoginConfig, OAuthTokenError, createDeviceLogin, isAccessDenied };
|
|
1
|
+
import { DEVICE_CODE_GRANT_TYPE, DeviceAuthorization, DeviceCredentials, DeviceLogin, DeviceLoginConfig, OAuthTokenError, ProviderError as AccountsRequestError, TokenSet as AccountsTokens, User as AccountsUser, createDeviceLogin, isAccessDenied } from "authical/device";
|
|
2
|
+
export { AccountsRequestError, type AccountsTokens, type AccountsUser, DEVICE_CODE_GRANT_TYPE, type DeviceAuthorization, type DeviceCredentials, type DeviceLogin, type DeviceLoginConfig, OAuthTokenError, createDeviceLogin, isAccessDenied };
|
package/dist/device.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{DEVICE_CODE_GRANT_TYPE as e,OAuthTokenError as t,ProviderError as n,createDeviceLogin as r,isAccessDenied as i}from"authical/device";export{n as AccountsRequestError,e as DEVICE_CODE_GRANT_TYPE,t as OAuthTokenError,r as createDeviceLogin,i as isAccessDenied};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import "./types-BSF1k96p.js";
|
|
2
|
+
import { OAuthTokenError, ProviderError as AccountsRequestError, isAccessDenied } from "authical";
|
|
3
|
+
//#region src/core/errors.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A stored session that cannot be turned back into one: a token the codec
|
|
6
|
+
* cannot decrypt because another key wrote it, a column that does not hold
|
|
7
|
+
* what it should. The session manager reads it as the session being over,
|
|
8
|
+
* removes the row and sends the user back to sign in, so a store that decodes
|
|
9
|
+
* what it stored raises this rather than the failure underneath; every other
|
|
10
|
+
* store failure is a fault and propagates.
|
|
11
|
+
*/
|
|
12
|
+
declare class SessionDecodeError extends Error {
|
|
13
|
+
constructor(cause: unknown);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { isAccessDenied as i, OAuthTokenError as n, SessionDecodeError as r, AccountsRequestError as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{OAuthTokenError as e,ProviderError as t,isAccessDenied as n}from"authical";var r=class extends Error{constructor(e){super(`Stored session could not be decoded`,{cause:e}),this.name=`SessionDecodeError`}};function i({phase:e,error:t}){console.error(`[aui-auth] ${e}`,t)}function a(e,t,n){try{e.onError({phase:t,error:n})}catch{}}export{i as a,n as i,e as n,a as o,r,t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{apiBase as e,providerEndpoint as t,providerFetch as n}from"authical";function r(e){return{issuer:e.issuer,fetch:e.fetch,timeoutMs:e.lifetimes.requestTimeoutMs}}export{r as i,n,e as r,t};
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import { a as AccountsLifetimes,
|
|
2
|
-
import
|
|
1
|
+
import { a as AccountsLifetimes, l as AccountsSessionStore, s as AccountsSession, t as AccountsAuthConfig } from "./types-BSF1k96p.js";
|
|
2
|
+
import "./fetch-BTZqr_UF.js";
|
|
3
|
+
import "./errors-369IR3ml.js";
|
|
4
|
+
import { fetchUserInfo } from "authical";
|
|
5
|
+
//#region src/core/resolve.d.ts
|
|
6
|
+
type SessionResolution<Data> = {
|
|
7
|
+
session: AccountsSession<Data> | null;
|
|
8
|
+
/**
|
|
9
|
+
* The Set-Cookie headers to attach to the response: the cache cookie while
|
|
10
|
+
* the session is alive, the cookies that clear a session that is gone.
|
|
11
|
+
*/
|
|
12
|
+
cookies: string[];
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
3
15
|
//#region src/core/config.d.ts
|
|
4
16
|
declare const DEFAULT_LIFETIMES: AccountsLifetimes;
|
|
5
17
|
//#endregion
|
|
@@ -14,9 +26,6 @@ declare function requestOrigin(request: Request): string;
|
|
|
14
26
|
declare function forwardCookies(headers: Headers, issued: readonly string[]): void;
|
|
15
27
|
declare function sanitizeRedirectPath(rawRedirect: string | null | undefined, origin: string): string;
|
|
16
28
|
//#endregion
|
|
17
|
-
//#region src/core/oidc.d.ts
|
|
18
|
-
declare function fetchUserInfo(options: AccountsFetchOptions, accessToken: string): Promise<AccountsUser>;
|
|
19
|
-
//#endregion
|
|
20
29
|
//#region src/core/cache.d.ts
|
|
21
30
|
declare function cacheCookieBase(sessionCookie: string): string;
|
|
22
31
|
//#endregion
|
|
@@ -36,16 +45,6 @@ type GuardResult<Data> = {
|
|
|
36
45
|
response: Response;
|
|
37
46
|
};
|
|
38
47
|
//#endregion
|
|
39
|
-
//#region src/core/resolve.d.ts
|
|
40
|
-
type SessionResolution<Data> = {
|
|
41
|
-
session: AccountsSession<Data> | null;
|
|
42
|
-
/**
|
|
43
|
-
* The Set-Cookie headers to attach to the response: the cache cookie while
|
|
44
|
-
* the session is alive, the cookies that clear a session that is gone.
|
|
45
|
-
*/
|
|
46
|
-
cookies: string[];
|
|
47
|
-
};
|
|
48
|
-
//#endregion
|
|
49
48
|
//#region src/core/store/memory.d.ts
|
|
50
49
|
declare function createMemorySessionStore<Data>(): AccountsSessionStore<Data> & {
|
|
51
50
|
rows: Map<string, AccountsSession<Data>>;
|
|
@@ -69,9 +68,9 @@ declare function createAccountsAuth<Data>(input: AccountsAuthConfig<Data>): {
|
|
|
69
68
|
sessionFromRequest: (request: Request) => Promise<AccountsSession<Data> | null>;
|
|
70
69
|
accessTokenFromCookies: (cookies: SessionCookies) => Promise<string | null>;
|
|
71
70
|
accessTokenFromRequest: (request: Request) => Promise<string | null>;
|
|
72
|
-
updateSessionData: (cookies: SessionCookies, update: (data: Data) => Data) => Promise<
|
|
71
|
+
updateSessionData: (cookies: SessionCookies, update: (data: Data) => Data) => Promise<SessionResolution<Data>>;
|
|
73
72
|
sweepSessions: () => Promise<number>;
|
|
74
73
|
};
|
|
75
74
|
type AccountsAuth<Data> = ReturnType<typeof createAccountsAuth<Data>>;
|
|
76
75
|
//#endregion
|
|
77
|
-
export {
|
|
76
|
+
export { GuardOptions as a, fetchUserInfo as c, sanitizeRedirectPath as d, DEFAULT_LIFETIMES as f, createMemorySessionStore as i, forwardCookies as l, SessionCookies as n, GuardResult as o, SessionResolution as p, createAccountsAuth as r, cacheCookieBase as s, AccountsAuth as t, requestOrigin as u };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as AccountsLifetimes, c as AccountsSessionPatch, d as AccountsUser, f as RevalidateInput, i as AccountsErrorPhase, l as AccountsSessionStore, m as SignInInput, n as AccountsCacheConfig, o as AccountsPaths, p as SessionSweepCutoffs, r as AccountsErrorEvent, s as AccountsSession, t as AccountsAuthConfig, u as AccountsTokens } from "./types-
|
|
2
|
-
import { n as accountsEndpoint, t as AccountsFetchOptions } from "./fetch-
|
|
3
|
-
import { i as isAccessDenied, n as OAuthTokenError, r as SessionDecodeError, t as AccountsRequestError } from "./errors-
|
|
4
|
-
import { a as
|
|
1
|
+
import { a as AccountsLifetimes, c as AccountsSessionPatch, d as AccountsUser, f as RevalidateInput, i as AccountsErrorPhase, l as AccountsSessionStore, m as SignInInput, n as AccountsCacheConfig, o as AccountsPaths, p as SessionSweepCutoffs, r as AccountsErrorEvent, s as AccountsSession, t as AccountsAuthConfig, u as AccountsTokens } from "./types-BSF1k96p.js";
|
|
2
|
+
import { n as accountsEndpoint, t as AccountsFetchOptions } from "./fetch-BTZqr_UF.js";
|
|
3
|
+
import { i as isAccessDenied, n as OAuthTokenError, r as SessionDecodeError, t as AccountsRequestError } from "./errors-369IR3ml.js";
|
|
4
|
+
import { a as GuardOptions, c as fetchUserInfo, d as sanitizeRedirectPath, f as DEFAULT_LIFETIMES, i as createMemorySessionStore, l as forwardCookies, n as SessionCookies, o as GuardResult, p as SessionResolution, r as createAccountsAuth, s as cacheCookieBase, t as AccountsAuth, u as requestOrigin } from "./index-ByH9jmJH.js";
|
|
5
5
|
export { AccountsAuth, type AccountsAuthConfig, type AccountsCacheConfig, type AccountsErrorEvent, type AccountsErrorPhase, type AccountsFetchOptions, type AccountsLifetimes, type AccountsPaths, AccountsRequestError, type AccountsSession, type AccountsSessionPatch, type AccountsSessionStore, type AccountsTokens, type AccountsUser, DEFAULT_LIFETIMES, type GuardOptions, type GuardResult, OAuthTokenError, type RevalidateInput, SessionCookies, SessionDecodeError, type SessionResolution, type SessionSweepCutoffs, type SignInInput, accountsEndpoint, cacheCookieBase, createAccountsAuth, createMemorySessionStore, fetchUserInfo, forwardCookies, isAccessDenied, requestOrigin, sanitizeRedirectPath };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,t as m,u as h,v as g}from"./cache-vq-5GFN7.js";import{n as _,t as v}from"./encoding-BhmNmloC.js";import{i as y,n as b,o as x,r as S,t as C}from"./errors-C7IxbL16.js";import{a as w,i as T,o as E,r as D,t as O}from"./fetch-CM1mVzPm.js";import{a as k,i as A,l as j,n as M,r as N,t as P}from"./oidc-qInr-2mE.js";function F(e,t){return[...d(e.cookieName,t),...m(e,t)]}function I(e,t){return async function(n){let r=o(n),i=f(n,e.cookieName),a=f(n,u(e.cookieName)),c=await s(e,a,i,e.now());if(c)return{session:c,cookies:[]};let l={session:null,cookies:i!==null||a!==null?F(e,r):[]},d=await t.load(i);if(!d)return l;let{deferRevalidation:m}=e;if(m&&t.revalidationDue(d)&&L(e,m,t,d)){let t=await p(e,d,r,e.now());return{session:d,cookies:t?[t]:[]}}let h=d;try{let e=await t.revalidate(d);if(!e)return l;h=e}catch(t){x(e,`revalidate`,t)}let g=await p(e,h,r,e.now());return{session:h,cookies:g?[g]:[]}}}function L(e,t,n,r){try{return t(async()=>{try{await n.revalidate(r)}catch(t){x(e,`revalidate`,t)}}),!0}catch(t){return x(e,`revalidate`,t),!1}}function R(e,t){let n=I(e,t);return async function(t,i={}){let a=new URL(t.url);if([e.paths.login,e.paths.callback,e.paths.logout,e.paths.logoutComplete,e.paths.error,...i.publicPaths??[]].some(e=>a.pathname.startsWith(e)))return{kind:`ok`,session:null};let{session:o,cookies:s}=await n(t);return o?s.length>0?{kind:`ok`,session:o,cookies:s}:{kind:`ok`,session:o}:r(t,i,s)};function r(e,t,n){let r=n.length>0,a=new URL(e.url),o=(t.apiPaths??[`/api`,`/trpc`]).some(e=>a.pathname.startsWith(e))?Response.json({error:`Unauthorized`},{status:401}):l(i(e,t,r));for(let e of n)o.headers.append(`set-cookie`,e);return{kind:`response`,response:o}}function i(t,n,r){let i=new URL(t.url),a=new URL(e.paths.login,o(t));return a.searchParams.set(`redirect`,n.redirectPath?.(t)??`${i.pathname}${i.search}`),r&&a.searchParams.set(`silent`,`1`),a}}const z=/^[A-Za-z0-9_-]{1,128}$/,B=new Set([`login_required`,`consent_required`,`interaction_required`,`account_selection_required`]);function V(r,s){function u(e,t){let n=new URL(r.paths.login,e);return n.searchParams.set(`redirect`,t),n}function d(e,t,n){let i=new URL(r.paths.error,e);return i.searchParams.set(`reason`,t),n&&i.searchParams.set(`description`,n),i}function _(t,n){let a=h(r.cookieName,``),o=[...i(t.headers.get(`cookie`)).keys()].filter(e=>e.replace(/^__Secure-/,``).startsWith(a)),s=o.length-4;for(let t of o.slice(0,Math.max(0,s)))n.headers.append(`set-cookie`,e(t,``,t.startsWith(`__Secure-`),0))}async function v(e){try{let t=await s.load(e);t&&await s.end(t)}catch(e){x(r,`session_store`,e)}}async function y(e){let t=o(e),n=new URL(e.url).searchParams,i=a(n.get(`redirect`),t),s=n.get(`silent`)===`1`,{url:u,state:d,verifier:f}=await P(r,{origin:t,silent:s}),p=l(u);return _(e,p),g(p.headers,h(r.cookieName,d),c({verifier:f,redirectPath:i,silent:s}),t,r.lifetimes.flowMaxAgeMs),p}async function S(e){let i=o(e),c=new URL(e.url).searchParams,_=c.get(`state`),y=_&&z.test(_)?h(r.cookieName,_):null,S=y?n(f(e,y)):null,C=e=>(y&&t(e.headers,y,i),e);if(!S)return C(l(d(i,`invalid_state`,null)));let w=a(S.redirectPath,i),E=c.get(`iss`);if(E!==null&&E!==D(r.issuer))return C(l(d(i,`invalid_issuer`,null)));let O=c.get(`error`);if(O)return S.silent&&B.has(O)?C(l(u(i,w))):C(l(d(i,O,c.get(`error_description`))));let k=c.get(`code`);if(!k)return C(l(d(i,`invalid_request`,null)));let M,P,F;try{let e=await N(r,{code:k,verifier:S.verifier,redirectUri:new URL(r.paths.callback,i).toString()});M=j(e,null,r.now()),P=await A(T(r),M.accessToken),F=await r.onSignIn({user:P,accessToken:M.accessToken,redirectPath:w,previous:null})}catch(e){return x(r,`sign_in`,e),e instanceof b?C(l(d(i,e.code,e.description||null))):C(l(d(i,`accounts_unavailable`,null)))}let I=f(e,r.cookieName);if(F===null){let e=l(d(i,`access_denied`,null));I!==null&&(await v(I),t(e.headers,r.cookieName,i));for(let t of m(r,i))e.headers.append(`set-cookie`,t);return C(e)}let L,R;try{({cookieValue:L,session:R}=await s.start({user:P,tokens:M,data:F}))}catch(e){return x(r,`session_store`,e),C(l(d(i,`session_store_error`,null)))}I!==null&&await v(I);let V=l(new URL(w,i));g(V.headers,r.cookieName,L,i,r.lifetimes.absoluteMaxAgeMs);let H=await p(r,R,i,r.now());return H&&V.headers.append(`set-cookie`,H),C(V)}async function C(e){let t=o(e),n=await s.load(f(e,r.cookieName));n&&await s.end(n);let i=n?.tokens.idToken&&r.logout===`global`?M(r,{origin:t,idToken:n.tokens.idToken}):new URL(r.paths.logoutComplete,t).toString(),a=l(i,303);for(let e of F(r,t))a.headers.append(`set-cookie`,e);return a}return{login:y,callback:S,logout:C}}const H=e=>new Promise(t=>setTimeout(t,e));function U(e){let{store:t,lifetimes:n}=e;function r(e,t){return t-e.createdAt>=n.absoluteMaxAgeMs||t-e.lastValidatedAt>=n.idleMaxAgeMs}function i(e,t){return e.accessTokenExpiresAt-t<=n.refreshBeforeExpiryMs}function a(t){let r=e.now();return!i(t.tokens,r)&&r-t.lastValidatedAt>=n.revalidateIntervalMs}async function o(n){if(!n)return null;let i=await _(n),a;try{a=await t.read(i)}catch(n){if(!(n instanceof S))throw n;return x(e,`session_store`,n),await t.delete(i),null}return a?r(a,e.now())?(await t.delete(a.id),null):a:null}async function s(n){let r=v(32),i=e.now(),a={id:await _(r),user:n.user,tokens:n.tokens,data:n.data,createdAt:i,lastValidatedAt:i,refreshLeaseUntil:null};return await t.create(a),{session:a,cookieValue:r}}async function c(r){let a=e.now();if(!i(r.tokens,a))return r;if(!r.tokens.refreshToken)return await t.delete(r.id),null;let o=await t.claimRefreshLease(r.id,a+n.refreshLeaseMs,a);if(!o)return l(r.id,a);let s=o.refreshLeaseUntil??void 0;if(!i(o.tokens,a))return await t.update(o.id,{refreshLeaseUntil:null},s)??t.read(o.id);try{let r=await k(e,o.tokens.refreshToken,Math.max(n.refreshLeaseMs-1e3,n.refreshLeaseMs/2));return await t.update(o.id,{tokens:j(r,o.tokens,e.now()),refreshLeaseUntil:null},s)??t.read(o.id)}catch(n){if(y(n))return await t.delete(o.id,s)?null:await t.read(o.id)??null;let r=await t.update(o.id,{refreshLeaseUntil:null},s);if(o.tokens.accessTokenExpiresAt>e.now())return x(e,`refresh`,n),r??o;throw n}}async function l(r,a){for(;;){await H(100);let o=await t.read(r);if(!o)return null;let s=e.now();if(!i(o.tokens,s))return o;if(o.refreshLeaseUntil===null||o.refreshLeaseUntil<=s)return c(o);if(s-a>=n.leaseWaitMs){if(o.tokens.accessTokenExpiresAt>s)return o;throw new C(`Timed out waiting for the session refresh lease`,0)}}}async function u(r){let i;try{i=await c(r)}catch(t){x(e,`refresh`,t),i=r}if(!i)return null;if(e.now()-i.lastValidatedAt<n.revalidateIntervalMs||!d(i.tokens))return i;let a=e.revalidateUser?await p(i):i.user;if(!a)return f(i);if(!d(i.tokens))return i;let o=await e.onRevalidate({session:i,accessToken:i.tokens.accessToken,user:a});if(o===null)return f(i);let s={data:o,lastValidatedAt:e.now()};return a!==i.user&&(s.user=a),t.update(i.id,s)}function d(t){return t.accessTokenExpiresAt-e.now()>n.requestTimeoutMs}async function f(n){return n.tokens.accessTokenExpiresAt<=e.now()?n:(await t.delete(n.id),null)}async function p(t){try{return await A(T(e),t.tokens.accessToken)}catch(n){return y(n)?null:(x(e,`revalidate`,n),t.user)}}async function m(e){await t.delete(e.id)}async function h(){if(!t.sweep)return 0;let r=e.now();return t.sweep({createdBefore:r-n.absoluteMaxAgeMs,validatedBefore:r-n.idleMaxAgeMs})}return{load:o,start:s,ensureFreshTokens:c,revalidate:u,revalidationDue:a,end:m,sweep:h}}function W(){let e=new Map;return{rows:e,async create(t){e.set(t.id,structuredClone(t))},async read(t){let n=e.get(t);return n?structuredClone(n):null},async update(t,n,r){let i=e.get(t);if(!i||r!==void 0&&i.refreshLeaseUntil!==r)return null;let a=structuredClone({...i,...n});return e.set(t,a),structuredClone(a)},async claimRefreshLease(t,n,r){let i=e.get(t);if(!i||i.refreshLeaseUntil!==null&&i.refreshLeaseUntil>r)return null;let a={...i,refreshLeaseUntil:n};return e.set(t,a),structuredClone(a)},async delete(t,n){let r=e.get(t);return!r||n!==void 0&&r.refreshLeaseUntil!==n?!1:(e.delete(t),!0)},async sweep(t){let n=0;for(let[r,i]of e)(i.createdAt<t.createdBefore||i.lastValidatedAt<t.validatedBefore)&&(e.delete(r),n+=1);return n}}}function G(e){let t=E(e),n=U(t),r=V(t,n),i=R(t,n),a=I(t,n);function o(e){return{session:f(e,t.cookieName),cache:f(e,u(t.cookieName))}}async function c(e){return await s(t,e.cache,e.session,t.now())??n.load(e.session)}async function l(e){return c(o(e))}async function d(e){let r=await s(t,e.cache,e.session,t.now());if(r&&r.tokens.accessTokenExpiresAt>t.now())return r.tokens.accessToken;let i=await n.load(e.session);return i?(await n.ensureFreshTokens(i))?.tokens.accessToken??null:null}async function p(e){return d(o(e))}async function m(e,r){let i=await n.load(e.session);return i?t.store.update(i.id,{data:r(i.data)}):null}function h(){return n.sweep()}return{cookieName:t.cookieName,handlers:r,guard:i,resolveSession:a,sessionFromCookies:c,sessionFromRequest:l,accessTokenFromCookies:d,accessTokenFromRequest:p,updateSessionData:m,sweepSessions:h}}export{C as AccountsRequestError,w as DEFAULT_LIFETIMES,b as OAuthTokenError,S as SessionDecodeError,O as accountsEndpoint,u as cacheCookieBase,G as createAccountsAuth,W as createMemorySessionStore,A as fetchUserInfo,r as forwardCookies,y as isAccessDenied,o as requestOrigin,a as sanitizeRedirectPath};
|
|
1
|
+
import{_ as e,a as t,b as n,c as r,d as i,f as a,g as o,i as s,m as c,n as l,o as u,p as d,r as f,s as p,t as m,u as h,v as g,x as _,y as v}from"./cache-Cw1PrZ8f.js";import{a as y,i as b,n as x,o as S,r as C,t as w}from"./errors-CLA_uQFw.js";import{i as T,r as E,t as D}from"./fetch-n3F2M2nn.js";import{n as O}from"./codec-IJ2JySkR.js";import{fetchUserInfo as k,requestToken as A,tokensFromResponse as j}from"authical";function M(e,t){return[...r(e.cookieName,t),...m(e,t)]}function N(e,t){return async function(n){let r=g(n),i=o(n,e.cookieName),a=o(n,l(e.cookieName)),c=await s(e,a,i,e.now());if(c)return{session:c,cookies:[]};let u={session:null,cookies:i!==null||a!==null?M(e,r):[]},d=await t.load(i);if(!d)return u;let{deferRevalidation:p}=e;if(p&&t.revalidationDue(d)&&P(e,p,t,d)){let t=await f(e,d,r,e.now());return{session:d,cookies:t?[t]:[]}}let m=d;try{let e=await t.revalidate(d);if(!e)return u;m=e}catch(t){S(e,`revalidate`,t)}let h=await f(e,m,r,e.now());return{session:m,cookies:h?[h]:[]}}}function P(e,t,n,r){try{return t(async()=>{try{await n.revalidate(r)}catch(t){S(e,`revalidate`,t)}}),!0}catch(t){return S(e,`revalidate`,t),!1}}function F(t,n){let r=N(t,n);return async function(e,n={}){let a=new URL(e.url);if([t.paths.login,t.paths.callback,t.paths.logout,t.paths.logoutComplete,t.paths.error,...n.publicPaths??[]].some(e=>a.pathname.startsWith(e)))return{kind:`ok`,session:null};let{session:o,cookies:s}=await r(e);return o?s.length>0?{kind:`ok`,session:o,cookies:s}:{kind:`ok`,session:o}:i(e,n,s)};function i(t,n,r){let i=r.length>0,o=new URL(t.url),s=(n.apiPaths??[`/api`,`/trpc`]).some(e=>o.pathname.startsWith(e))?Response.json({error:`Unauthorized`},{status:401}):e(a(t,n,i));for(let e of r)s.headers.append(`set-cookie`,e);return{kind:`response`,response:s}}function a(e,n,r){let i=new URL(e.url),a=new URL(t.paths.login,g(e));return a.searchParams.set(`redirect`,n.redirectPath?.(e)??`${i.pathname}${i.search}`),r&&a.searchParams.set(`silent`,`1`),a}}async function I(e,n){let r=t(24),i=t(32),a=new URL(D(e.issuer,`/api/auth/oauth2/authorize`));return a.searchParams.set(`client_id`,e.clientId),a.searchParams.set(`redirect_uri`,new URL(e.paths.callback,n.origin).toString()),a.searchParams.set(`response_type`,`code`),a.searchParams.set(`scope`,e.scope),a.searchParams.set(`state`,r),a.searchParams.set(`code_challenge`,await u(i)),a.searchParams.set(`code_challenge_method`,`S256`),n.silent&&a.searchParams.set(`prompt`,`none`),{url:a.toString(),state:r,verifier:i}}function L(e,t){let n=new URL(D(e.issuer,`/api/auth/oauth2/end-session`));return n.searchParams.set(`id_token_hint`,t.idToken),n.searchParams.set(`client_id`,e.clientId),n.searchParams.set(`post_logout_redirect_uri`,new URL(e.paths.logoutComplete,t.origin).toString()),n.toString()}function R(e){return{...T(e),clientId:e.clientId,clientSecret:e.clientSecret,audience:e.audience}}function z(e,t){return A(R(e),{grant_type:`authorization_code`,code:t.code,code_verifier:t.verifier,redirect_uri:t.redirectUri})}function B(e,t,n){return A(R(e),{grant_type:`refresh_token`,refresh_token:t},n===void 0?void 0:Date.now()+n)}const V=/^[A-Za-z0-9_-]{1,128}$/,H=new Set([`login_required`,`consent_required`,`interaction_required`,`account_selection_required`]);function U(t,r){function s(e,n){let r=new URL(t.paths.login,e);return r.searchParams.set(`redirect`,n),r}function l(e,n,r){let i=new URL(t.paths.error,e);return i.searchParams.set(`reason`,n),r&&i.searchParams.set(`description`,r),i}function u(e,r){let i=a(t.cookieName,``),o=[...c(e.headers.get(`cookie`)).keys()].filter(e=>e.replace(/^__Secure-/,``).startsWith(i)),s=o.length-4;for(let e of o.slice(0,Math.max(0,s)))r.headers.append(`set-cookie`,n(e,``,e.startsWith(`__Secure-`),0))}async function d(e){try{let t=await r.load(e);t&&await r.end(t)}catch(e){S(t,`session_store`,e)}}async function y(n){let r=g(n),o=new URL(n.url).searchParams,s=v(o.get(`redirect`),r),c=o.get(`silent`)===`1`,{url:l,state:d,verifier:f}=await I(t,{origin:r,silent:c}),p=e(l);return u(n,p),_(p.headers,a(t.cookieName,d),i({verifier:f,redirectPath:s,silent:c}),r,t.lifetimes.flowMaxAgeMs),p}async function b(n){let i=g(n),c=new URL(n.url).searchParams,u=c.get(`state`),y=u&&V.test(u)?a(t.cookieName,u):null,b=y?h(o(n,y)):null,C=e=>(y&&p(e.headers,y,i),e);if(!b)return C(e(l(i,`invalid_state`,null)));let w=v(b.redirectPath,i),D=c.get(`iss`);if(D!==null&&D!==E(t.issuer))return C(e(l(i,`invalid_issuer`,null)));let O=c.get(`error`);if(O)return b.silent&&H.has(O)?C(e(s(i,w))):C(e(l(i,O,c.get(`error_description`))));let A=c.get(`code`);if(!A)return C(e(l(i,`invalid_request`,null)));let M,N,P;try{let e=await z(t,{code:A,verifier:b.verifier,redirectUri:new URL(t.paths.callback,i).toString()});M=j(e,null,t.now()),N=await k(T(t),M.accessToken),P=await t.onSignIn({user:N,accessToken:M.accessToken,redirectPath:w,previous:null})}catch(n){return S(t,`sign_in`,n),n instanceof x?C(e(l(i,n.code,n.description||null))):C(e(l(i,`accounts_unavailable`,null)))}let F=o(n,t.cookieName);if(P===null){let n=e(l(i,`access_denied`,null));F!==null&&(await d(F),p(n.headers,t.cookieName,i));for(let e of m(t,i))n.headers.append(`set-cookie`,e);return C(n)}let I,L;try{({cookieValue:I,session:L}=await r.start({user:N,tokens:M,data:P}))}catch(n){return S(t,`session_store`,n),C(e(l(i,`session_store_error`,null)))}F!==null&&await d(F);let R=e(new URL(w,i));_(R.headers,t.cookieName,I,i,t.lifetimes.absoluteMaxAgeMs);let B=await f(t,L,i,t.now());return B&&R.headers.append(`set-cookie`,B),C(R)}async function C(n){let i=g(n),a=await r.load(o(n,t.cookieName));a&&await r.end(a);let s=a?.tokens.idToken&&t.logout===`global`?L(t,{origin:i,idToken:a.tokens.idToken}):new URL(t.paths.logoutComplete,i).toString(),c=e(s,303);for(let e of M(t,i))c.headers.append(`set-cookie`,e);return c}return{login:y,callback:b,logout:C}}const W=e=>new Promise(t=>setTimeout(t,e));function G(e){let{store:n,lifetimes:r}=e;function i(e,t){return t-e.createdAt>=r.absoluteMaxAgeMs||t-e.lastValidatedAt>=r.idleMaxAgeMs}function a(e,t){return e.accessTokenExpiresAt-t<=r.refreshBeforeExpiryMs}function o(t){let n=e.now();return!a(t.tokens,n)&&n-t.lastValidatedAt>=r.revalidateIntervalMs}async function s(t){if(!t)return null;let r=await u(t),a;try{a=await n.read(r)}catch(t){if(!(t instanceof C))throw t;return S(e,`session_store`,t),await n.delete(r),null}return a?i(a,e.now())?(await n.delete(a.id),null):a:null}async function c(r){let i=t(32),a=e.now(),o={id:await u(i),user:r.user,tokens:r.tokens,data:r.data,createdAt:a,lastValidatedAt:a,refreshLeaseUntil:null};return await n.create(o),{session:o,cookieValue:i}}async function l(t){let i=e.now();if(!a(t.tokens,i))return t;if(!t.tokens.refreshToken)return await n.delete(t.id),null;let o=await n.claimRefreshLease(t.id,i+r.refreshLeaseMs,i);if(!o)return d(t.id,i);let s=o.refreshLeaseUntil??void 0;if(!a(o.tokens,i))return await n.update(o.id,{refreshLeaseUntil:null},s)??n.read(o.id);try{let t=await B(e,o.tokens.refreshToken,Math.max(r.refreshLeaseMs-1e3,r.refreshLeaseMs/2));return await n.update(o.id,{tokens:j(t,o.tokens,e.now()),refreshLeaseUntil:null},s)??n.read(o.id)}catch(t){if(b(t))return await n.delete(o.id,s)?null:await n.read(o.id)??null;let r=await n.update(o.id,{refreshLeaseUntil:null},s);if(o.tokens.accessTokenExpiresAt>e.now())return S(e,`refresh`,t),r??o;throw t}}async function d(t,i){for(;;){await W(100);let o=await n.read(t);if(!o)return null;let s=e.now();if(!a(o.tokens,s))return o;if(o.refreshLeaseUntil===null||o.refreshLeaseUntil<=s)return l(o);if(s-i>=r.leaseWaitMs){if(o.tokens.accessTokenExpiresAt>s)return o;throw new w(`Timed out waiting for the session refresh lease`,0)}}}async function f(t){let i;try{i=await l(t)}catch(n){S(e,`refresh`,n),i=t}if(!i)return null;if(e.now()-i.lastValidatedAt<r.revalidateIntervalMs||!p(i.tokens))return i;let a=e.revalidateUser?await h(i):i.user;if(!a)return m(i);if(!p(i.tokens))return i;let o=await e.onRevalidate({session:i,accessToken:i.tokens.accessToken,user:a});if(o===null)return m(i);let s={data:o,lastValidatedAt:e.now()};return a!==i.user&&(s.user=a),n.update(i.id,s)}function p(t){return t.accessTokenExpiresAt-e.now()>r.requestTimeoutMs}async function m(t){return t.tokens.accessTokenExpiresAt<=e.now()?t:(await n.delete(t.id),null)}async function h(t){try{return await k(T(e),t.tokens.accessToken)}catch(n){return b(n)?null:(S(e,`revalidate`,n),t.user)}}async function g(e){await n.delete(e.id)}async function _(){if(!n.sweep)return 0;let t=e.now();return n.sweep({createdBefore:t-r.absoluteMaxAgeMs,validatedBefore:t-r.idleMaxAgeMs})}return{load:s,start:c,ensureFreshTokens:l,revalidate:f,revalidationDue:o,end:g,sweep:_}}const K={login:`/api/auth/login`,callback:`/api/auth/callback`,logout:`/api/auth/logout`,logoutComplete:`/api/auth/logout-complete`,error:`/auth/error`},q={absoluteMaxAgeMs:2592e6,idleMaxAgeMs:6048e5,revalidateIntervalMs:12e4,refreshBeforeExpiryMs:3e5,flowMaxAgeMs:6e5,refreshLeaseMs:2e4,leaseWaitMs:5e3,requestTimeoutMs:1e4,retryIntervalMs:1e4},J=Object.freeze({});function Y(e){return{...e,scope:e.scope??`openid profile email offline_access`,onSignIn:e.onSignIn??(async()=>J),onRevalidate:e.onRevalidate??(async()=>J),onError:e.onError??y,revalidateUser:e.revalidateUser??!1,logout:e.logout??`global`,paths:{...K,...e.paths},lifetimes:{...q,...e.lifetimes},fetch:e.fetch??globalThis.fetch.bind(globalThis),now:e.now??Date.now,cache:e.cache?{codec:O(e.cache.secret),maxAgeMs:e.cache.maxAgeMs??6e4}:null,audience:e.audience===!1?null:e.audience??new URL(`/api/auth`,e.issuer).toString()}}function X(){let e=new Map;return{rows:e,async create(t){e.set(t.id,structuredClone(t))},async read(t){let n=e.get(t);return n?structuredClone(n):null},async update(t,n,r){let i=e.get(t);if(!i||r!==void 0&&i.refreshLeaseUntil!==r)return null;let a=structuredClone({...i,...n});return e.set(t,a),structuredClone(a)},async claimRefreshLease(t,n,r){let i=e.get(t);if(!i||i.refreshLeaseUntil!==null&&i.refreshLeaseUntil>r)return null;let a={...i,refreshLeaseUntil:n};return e.set(t,a),structuredClone(a)},async delete(t,n){let r=e.get(t);return!r||n!==void 0&&r.refreshLeaseUntil!==n?!1:(e.delete(t),!0)},async sweep(t){let n=0;for(let[r,i]of e)(i.createdAt<t.createdBefore||i.lastValidatedAt<t.validatedBefore)&&(e.delete(r),n+=1);return n}}}function Z(e){let t=Y(e),n=G(t),r=U(t,n),i=F(t,n),a=N(t,n);function c(e){return{session:o(e,t.cookieName),cache:o(e,l(t.cookieName))}}async function u(e){return await s(t,e.cache,e.session,t.now())??n.load(e.session)}async function d(e){return u(c(e))}async function f(e){let r=await s(t,e.cache,e.session,t.now());if(r&&r.tokens.accessTokenExpiresAt>t.now())return r.tokens.accessToken;let i=await n.load(e.session);return i?(await n.ensureFreshTokens(i))?.tokens.accessToken??null:null}async function p(e){return f(c(e))}async function h(e,r){let i=await n.load(e.session),a=i&&await t.store.update(i.id,{data:r(i.data)});return a?{session:a,cookies:m(t)}:{session:null,cookies:[]}}function g(){return n.sweep()}return{cookieName:t.cookieName,handlers:r,guard:i,resolveSession:a,sessionFromCookies:u,sessionFromRequest:d,accessTokenFromCookies:f,accessTokenFromRequest:p,updateSessionData:h,sweepSessions:g}}export{w as AccountsRequestError,q as DEFAULT_LIFETIMES,x as OAuthTokenError,C as SessionDecodeError,D as accountsEndpoint,l as cacheCookieBase,Z as createAccountsAuth,X as createMemorySessionStore,k as fetchUserInfo,d as forwardCookies,b as isAccessDenied,g as requestOrigin,v as sanitizeRedirectPath};
|
package/dist/next.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { s as AccountsSession } from "./types-
|
|
2
|
-
import { t as AccountsAuth } from "./index-
|
|
1
|
+
import { s as AccountsSession } from "./types-BSF1k96p.js";
|
|
2
|
+
import { t as AccountsAuth } from "./index-ByH9jmJH.js";
|
|
3
3
|
import { NextRequest, NextResponse } from "next/server";
|
|
4
4
|
//#region src/next/index.d.ts
|
|
5
5
|
/**
|
package/dist/next.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{h as e,l as t,n,p as r}from"./cache-Cw1PrZ8f.js";import{io as i}from"next/cache.js";import{cookies as a}from"next/headers";import{NextResponse as o}from"next/server";function s(e,t=[]){r(e.headers,t);let n=o.next({request:{headers:e.headers}});for(let e of t)n.headers.append(`set-cookie`,e);return n}async function c(e){await i();let r=await a(),o=e=>r.get(t(e,!0))?.value||r.get(t(e,!1))?.value||null;return{session:o(e),cache:o(n(e))}}async function l(t){let n=await a();for(let r of t){let t=e(r);if(t)try{n.set(t.name,t.value,t.options)}catch{}}}function u(e){let t=e.cookieName;return{async getSession(){return e.sessionFromCookies(await c(t))},async getAccessToken(){return e.accessTokenFromCookies(await c(t))},async updateSessionData(n){let r=await e.updateSessionData(await c(t),n);return await l(r.cookies),r.session}}}export{s as continueRequest,u as withNextRequestScope};
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
+
import { TokenSet, User } from "authical";
|
|
1
2
|
//#region src/core/types.d.ts
|
|
2
|
-
type AccountsUser =
|
|
3
|
-
|
|
4
|
-
email: string;
|
|
5
|
-
name: string;
|
|
6
|
-
image: string | null;
|
|
7
|
-
};
|
|
8
|
-
type AccountsTokens = {
|
|
9
|
-
accessToken: string;
|
|
10
|
-
refreshToken: string | null;
|
|
11
|
-
idToken: string | null;
|
|
12
|
-
accessTokenExpiresAt: number;
|
|
13
|
-
};
|
|
3
|
+
type AccountsUser = User;
|
|
4
|
+
type AccountsTokens = TokenSet;
|
|
14
5
|
type AccountsSession<Data> = {
|
|
15
6
|
id: string;
|
|
16
7
|
user: AccountsUser;
|
package/dist/verify.d.ts
CHANGED
|
@@ -1,51 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type AccountsTokenClaims = {
|
|
4
|
-
iss: string;
|
|
5
|
-
sub: string;
|
|
6
|
-
aud: string | string[];
|
|
7
|
-
exp: number;
|
|
8
|
-
iat?: number;
|
|
9
|
-
nbf?: number;
|
|
10
|
-
scope?: string;
|
|
11
|
-
client_id?: string;
|
|
12
|
-
email?: string;
|
|
13
|
-
name?: string;
|
|
14
|
-
picture?: string;
|
|
15
|
-
sid?: string;
|
|
16
|
-
} & Record<string, unknown>;
|
|
17
|
-
type TokenVerifierConfig = {
|
|
18
|
-
issuer: string;
|
|
19
|
-
/** The audience the token must name: the resource for an access token, the client id for an id token. */
|
|
20
|
-
audience: string | string[];
|
|
21
|
-
/** How long a fetched key set is served before it is read again; ten minutes by default. */
|
|
22
|
-
keysMaxAgeMs?: number;
|
|
23
|
-
/** How soon after a read for an unknown key id the next such read may happen; thirty seconds by default. */
|
|
24
|
-
keysRetryMs?: number;
|
|
25
|
-
/** Tolerance on `exp` and `nbf`; thirty seconds by default. */
|
|
26
|
-
clockSkewMs?: number;
|
|
27
|
-
requestTimeoutMs?: number;
|
|
28
|
-
fetch?: typeof fetch;
|
|
29
|
-
now?: () => number;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Verifies a JWT accounts issued, for a server that receives one as a bearer
|
|
33
|
-
* token: the EdDSA signature against the accounts key set, then `iss`, `aud`,
|
|
34
|
-
* `exp`, `nbf` and `sub`. A token that fails any of them answers null; only a
|
|
35
|
-
* key set that cannot be read at all, with nothing cached to fall back on,
|
|
36
|
-
* throws, because that is the verifier's outage rather than the caller's bad
|
|
37
|
-
* token. Keys are cached and re-read once when a token names a key id the
|
|
38
|
-
* cache does not hold, which is how a rotation shows up.
|
|
39
|
-
*/
|
|
40
|
-
declare function createTokenVerifier(config: TokenVerifierConfig): {
|
|
41
|
-
/**
|
|
42
|
-
* The claims of a token accounts issued, or null. `scopes` names the
|
|
43
|
-
* scopes the endpoint needs; a token missing any of them is null as well.
|
|
44
|
-
*/
|
|
45
|
-
verify(token: string, options?: {
|
|
46
|
-
scopes?: string[];
|
|
47
|
-
}): Promise<AccountsTokenClaims | null>;
|
|
48
|
-
};
|
|
49
|
-
type TokenVerifier = ReturnType<typeof createTokenVerifier>;
|
|
50
|
-
//#endregion
|
|
51
|
-
export { AccountsRequestError, AccountsTokenClaims, TokenVerifier, TokenVerifierConfig, createTokenVerifier };
|
|
1
|
+
import { ProviderError as AccountsRequestError, TokenClaims as AccountsTokenClaims, TokenVerifier, TokenVerifierConfig, createTokenVerifier } from "authical/verify";
|
|
2
|
+
export { AccountsRequestError, type AccountsTokenClaims, type TokenVerifier, type TokenVerifierConfig, createTokenVerifier };
|
package/dist/verify.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ProviderError as e,createTokenVerifier as t}from"authical/verify";export{e as AccountsRequestError,t as createTokenVerifier};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aui-auth",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "Sign in through assistant-ui accounts: server side sessions for web apps (OIDC code flow with PKCE, tokens kept in the app's store, single flight refresh), the device grant for CLIs, and token verification for resource servers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -46,6 +46,9 @@
|
|
|
46
46
|
"default": "./dist/testing.js"
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"authical": "^0.0.1"
|
|
51
|
+
},
|
|
49
52
|
"peerDependencies": {
|
|
50
53
|
"next": ">=16.3"
|
|
51
54
|
},
|
package/dist/cache-vq-5GFN7.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./encoding-BhmNmloC.js";import{o as t}from"./errors-C7IxbL16.js";function n(e){if(!e)return;let t=e.split(`,`);return t[t.length-1].trim()||void 0}function r(e){let t=new URL(e.url);return`${n(e.headers.get(`x-forwarded-proto`))||t.protocol.replace(`:`,``)}://${n(e.headers.get(`x-forwarded-host`))||e.headers.get(`host`)||t.host}`}function i(e){return new URL(e).protocol===`https:`}function a(e,t){return t?`__Secure-${e}`:e}function o(e){let t=new Map;if(!e)return t;for(let n of e.split(`;`)){let e=n.indexOf(`=`);if(e===-1)continue;let r=n.slice(0,e).trim();!r||t.has(r)||t.set(r,n.slice(e+1).trim())}return t}function s(e,t){let n=o(e.headers.get(`cookie`));return n.get(a(t,!0))||n.get(a(t,!1))||null}function c(e,t,n,r){let i=[`${e}=${t}`,`Path=/`,`HttpOnly`,`SameSite=Lax`,`Max-Age=${r}`];return n&&i.push(`Secure`),i.join(`; `)}function l(e,t,n,r,o){let s=i(r);e.append(`set-cookie`,c(a(t,s),n,s,Math.floor(o/1e3)))}function u(e,t){if(t.length===0)return;let n=o(e.get(`cookie`));for(let e of t){let t=e.split(`;`)[0],r=t.indexOf(`=`);if(r<1)continue;let i=t.slice(0,r).trim(),a=t.slice(r+1).trim();a?n.set(i,a):n.delete(i)}e.set(`cookie`,[...n].map(([e,t])=>`${e}=${t}`).join(`; `))}function d(e,t){let n=i(t);return[n,!n].map(t=>c(a(e,t),``,t,0))}function f(e,t,n){for(let r of d(t,n))e.append(`set-cookie`,r)}function p(e,t=307){return new Response(null,{status:t,headers:{location:e.toString()}})}function m(e,t){return`${e}_flow_${t}`}function h(e){return btoa(JSON.stringify(e)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function g(e){if(!e)return null;try{let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=JSON.parse(atob(t));return typeof n.verifier==`string`?{verifier:n.verifier,redirectPath:typeof n.redirectPath==`string`?n.redirectPath:`/`,silent:n.silent===!0}:null}catch{return null}}function _(e,t){if(!e)return`/`;let n;try{n=new URL(e,t)}catch{return`/`}return n.origin!==t||n.pathname.startsWith(`//`)?`/`:`${n.pathname}${n.search}${n.hash}`}const v=4096;function y(e){return`${e}_cache`}function b(e,t,n){if(!e.cache)return 0;let{lifetimes:r}=e,i=Math.min(t.lastValidatedAt+r.revalidateIntervalMs,t.tokens.accessTokenExpiresAt-r.refreshBeforeExpiryMs);return Math.min(e.cache.maxAgeMs,(i>n?i:n+r.retryIntervalMs)-n,t.createdAt+r.absoluteMaxAgeMs-n,t.lastValidatedAt+r.idleMaxAgeMs-n)}async function x(e,t,n){if(!e.cache)return null;let r=b(e,t,n);if(r<1e3)return null;let i={v:1,id:t.id,u:t.user,d:t.data,at:t.tokens.accessToken,ate:t.tokens.accessTokenExpiresAt,ca:t.createdAt,lv:t.lastValidatedAt,exp:n+r};return{value:await(await e.cache.codec()).encrypt(JSON.stringify(i)),maxAgeMs:r}}async function S(t,n,r,i){if(!t.cache||!n||!r)return null;let a;try{let e=await t.cache.codec();a=JSON.parse(await e.decrypt(n))}catch{return null}return a.v!==1||typeof a.exp!=`number`||a.exp<=i||a.id!==await e(r)?null:{id:a.id,user:a.u,tokens:{accessToken:a.at,refreshToken:null,idToken:null,accessTokenExpiresAt:a.ate},data:a.d,createdAt:a.ca,lastValidatedAt:a.lv,refreshLeaseUntil:null}}async function C(e,n,r,o){try{let t=await x(e,n,o);if(!t)return null;let s=i(r),l=c(a(y(e.cookieName),s),t.value,s,Math.floor(t.maxAgeMs/1e3));if(l.length>v)throw Error(`Cache cookie is ${l.length} bytes and browsers drop cookies over ${v}; the session data is too large to cache`);return l}catch(n){return t(e,`cache_cookie`,n),null}}function w(e,t){return e.cache?d(y(e.cookieName),t):[]}export{c as _,f as a,g as c,u as d,o as f,_ as g,r as h,S as i,h as l,p as m,y as n,d as o,s as p,C as r,a as s,w as t,m as u,l as v};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function e(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function t(t){return e(crypto.getRandomValues(new Uint8Array(t)))}async function n(t){let n=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(t));return e(new Uint8Array(n))}export{n,t};
|
package/dist/errors-C7IxbL16.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=class extends Error{status;constructor(e,t){super(e),this.name=`AccountsRequestError`,this.status=t}},t=class extends Error{constructor(e){super(`Stored session could not be decoded`,{cause:e}),this.name=`SessionDecodeError`}},n=class extends e{code;description;constructor(e,t,n){super(`Token request failed: ${e} ${t} ${n}`,e),this.name=`OAuthTokenError`,this.code=t,this.description=n}};const r=new Set([408,425,429]);function i(t){return t instanceof e&&t.status>=400&&t.status<500&&!r.has(t.status)}function a({phase:e,error:t}){console.error(`[aui-auth] ${e}`,t)}function o(e,t,n){try{e.onError({phase:t,error:n})}catch{}}export{a,i,n,o,t as r,e as t};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
//#region src/core/errors.d.ts
|
|
2
|
-
declare class AccountsRequestError extends Error {
|
|
3
|
-
readonly status: number;
|
|
4
|
-
constructor(message: string, status: number);
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* A stored session that cannot be turned back into one: a token the codec
|
|
8
|
-
* cannot decrypt because another key wrote it, a column that does not hold
|
|
9
|
-
* what it should. The session manager reads it as the session being over,
|
|
10
|
-
* removes the row and sends the user back to sign in, so a store that decodes
|
|
11
|
-
* what it stored raises this rather than the failure underneath; every other
|
|
12
|
-
* store failure is a fault and propagates.
|
|
13
|
-
*/
|
|
14
|
-
declare class SessionDecodeError extends Error {
|
|
15
|
-
constructor(cause: unknown);
|
|
16
|
-
}
|
|
17
|
-
declare class OAuthTokenError extends AccountsRequestError {
|
|
18
|
-
readonly code: string;
|
|
19
|
-
readonly description: string;
|
|
20
|
-
constructor(status: number, code: string, description: string);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Whether accounts rejected the token, the client, or the user, which ends
|
|
24
|
-
* the session, as opposed to failing to answer, which keeps it. Any 4xx but a
|
|
25
|
-
* timeout or a rate limit counts: the provider answers a revoked token or a
|
|
26
|
-
* disabled client with 400 as readily as with 401.
|
|
27
|
-
*/
|
|
28
|
-
declare function isAccessDenied(error: unknown): boolean;
|
|
29
|
-
//#endregion
|
|
30
|
-
export { isAccessDenied as i, OAuthTokenError as n, SessionDecodeError as r, AccountsRequestError as t };
|
package/dist/fetch-C0ojJu8c.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
//#region src/core/fetch.d.ts
|
|
2
|
-
type AccountsFetchOptions = {
|
|
3
|
-
issuer: string;
|
|
4
|
-
fetch?: typeof fetch;
|
|
5
|
-
timeoutMs?: number;
|
|
6
|
-
};
|
|
7
|
-
declare function accountsEndpoint(issuer: string, path: string): string;
|
|
8
|
-
//#endregion
|
|
9
|
-
export { accountsEndpoint as n, AccountsFetchOptions as t };
|
package/dist/fetch-CM1mVzPm.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e,t}from"./errors-C7IxbL16.js";import{n}from"./codec-IJ2JySkR.js";const r={login:`/api/auth/login`,callback:`/api/auth/callback`,logout:`/api/auth/logout`,logoutComplete:`/api/auth/logout-complete`,error:`/auth/error`},i={absoluteMaxAgeMs:2592e6,idleMaxAgeMs:6048e5,revalidateIntervalMs:12e4,refreshBeforeExpiryMs:3e5,flowMaxAgeMs:6e5,refreshLeaseMs:2e4,leaseWaitMs:5e3,requestTimeoutMs:1e4,retryIntervalMs:1e4},a=Object.freeze({});function o(t){return{...t,scope:t.scope??`openid profile email offline_access`,onSignIn:t.onSignIn??(async()=>a),onRevalidate:t.onRevalidate??(async()=>a),onError:t.onError??e,revalidateUser:t.revalidateUser??!1,logout:t.logout??`global`,paths:{...r,...t.paths},lifetimes:{...i,...t.lifetimes},fetch:t.fetch??globalThis.fetch.bind(globalThis),now:t.now??Date.now,cache:t.cache?{codec:n(t.cache.secret),maxAgeMs:t.cache.maxAgeMs??6e4}:null,audience:t.audience===!1?null:t.audience??new URL(`/api/auth`,t.issuer).toString()}}function s(e,t){return new URL(t,e).toString()}function c(e){return s(e,`/api/auth`)}function l(e){return{issuer:e.issuer,fetch:e.fetch,timeoutMs:e.lifetimes.requestTimeoutMs}}async function u(e,n,r={},a){let o=e.fetch??globalThis.fetch.bind(globalThis),c=e.timeoutMs??i.requestTimeoutMs,l=a===void 0?c:Math.min(c,a-Date.now());if(l<=0)throw new t(`Accounts request deadline passed`,0);return o(s(e.issuer,n),{...r,cache:`no-store`,signal:AbortSignal.timeout(l)})}export{i as a,l as i,u as n,o,c as r,s as t};
|
package/dist/oidc-qInr-2mE.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e,t}from"./encoding-BhmNmloC.js";import{n,t as r}from"./errors-C7IxbL16.js";import{i,n as a,t as o}from"./fetch-CM1mVzPm.js";async function s(n,r){let i=t(24),a=t(32),s=new URL(o(n.issuer,`/api/auth/oauth2/authorize`));return s.searchParams.set(`client_id`,n.clientId),s.searchParams.set(`redirect_uri`,new URL(n.paths.callback,r.origin).toString()),s.searchParams.set(`response_type`,`code`),s.searchParams.set(`scope`,n.scope),s.searchParams.set(`state`,i),s.searchParams.set(`code_challenge`,await e(a)),s.searchParams.set(`code_challenge_method`,`S256`),r.silent&&s.searchParams.set(`prompt`,`none`),{url:s.toString(),state:i,verifier:a}}function c(e,t){let n=new URL(o(e.issuer,`/api/auth/oauth2/end-session`));return n.searchParams.set(`id_token_hint`,t.idToken),n.searchParams.set(`client_id`,e.clientId),n.searchParams.set(`post_logout_redirect_uri`,new URL(e.paths.logoutComplete,t.origin).toString()),n.toString()}function l(e){return{...i(e),clientId:e.clientId,clientSecret:e.clientSecret,audience:e.audience}}async function u(e){let t=await e.text().catch(()=>``),r=`unknown_error`,i=t;try{let e=JSON.parse(t);r=e.error??r,i=e.error_description??i}catch{}return new n(e.status,r,i)}function d(e){return e.code===`invalid_target`||e.code===`invalid_request`&&/resource/i.test(e.description)}async function f(e,t,n,r=!0){let i=new URLSearchParams({client_id:e.clientId,...t});e.clientSecret&&i.set(`client_secret`,e.clientSecret),e.audience&&r&&i.set(`resource`,e.audience);let o=await a(e,`/api/auth/oauth2/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:i},n);if(!o.ok){let i=await u(o);if(r&&e.audience&&d(i))return f(e,t,n,!1);throw i}return await o.json()}function p(e,t){return f(l(e),{grant_type:`authorization_code`,code:t.code,code_verifier:t.verifier,redirect_uri:t.redirectUri})}function m(e,t,n){return f(l(e),{grant_type:`refresh_token`,refresh_token:t},n===void 0?void 0:Date.now()+n)}async function h(e,t){let n=await a(e,`/api/auth/oauth2/userinfo`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)throw new r(`Failed to load user info: ${n.status}`,n.status);let i=await n.json();return{id:i.sub,email:i.email??``,name:i.name??i.email??i.sub,image:i.picture??null}}function g(e,t,n){return{accessToken:e.access_token,refreshToken:e.refresh_token??t?.refreshToken??null,idToken:e.id_token??t?.idToken??null,accessTokenExpiresAt:typeof e.expires_at==`number`?e.expires_at*1e3:n+(e.expires_in??3600)*1e3}}export{m as a,u as c,h as i,g as l,c as n,d as o,p as r,f as s,s as t};
|