aui-auth 0.0.5 → 0.0.6
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/dist/accounts.d.ts +2 -2
- package/dist/accounts.js +1 -1
- package/dist/cache-kH1-Y-mz.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 +2 -2
- package/dist/database/redis.d.ts +1 -1
- package/dist/database/redis.js +9 -9
- package/dist/{index-oUN8Ug-7.d.ts → index-wc8vz71h.d.ts} +9 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/next.d.ts +11 -3
- package/dist/next.js +1 -1
- package/dist/{oidc-D-qX1b25.d.ts → oidc-CaYOiMFO.d.ts} +1 -1
- package/dist/oidc-D2VwAdd3.js +1 -0
- package/dist/testing.d.ts +1 -1
- package/dist/{types-C5wNLE3i.d.ts → types-CEuhm7Nv.d.ts} +24 -1
- package/dist/types-ICH7-e-H.js +1 -0
- package/package.json +1 -1
- package/dist/cache-BlNb0qE2.js +0 -1
- package/dist/codec-D-31dtWO.js +0 -1
- package/dist/oidc-Dmqfk0L9.js +0 -1
package/dist/accounts.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as AccountsFetchOptions } from "./oidc-
|
|
1
|
+
import { h as RevalidateInput, v as SignInInput } from "./types-CEuhm7Nv.js";
|
|
2
|
+
import { t as AccountsFetchOptions } from "./oidc-CaYOiMFO.js";
|
|
3
3
|
//#region src/accounts/index.d.ts
|
|
4
4
|
type AccountsOrganization = {
|
|
5
5
|
id: string;
|
package/dist/accounts.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{a as e,t}from"./types-ICH7-e-H.js";import{n}from"./oidc-D2VwAdd3.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}}export{r as fetchOrganizations,o as organizationHooks,a as preferredOrganizationSlug,i as selectOrganization};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as e}from"./types-ICH7-e-H.js";import{u as t}from"./oidc-D2VwAdd3.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(e,n,r,i){if(!e.cache||!n||!r)return null;let a;try{let t=await e.cache.codec();a=JSON.parse(await t.decrypt(n))}catch{return null}return a.v!==1||typeof a.exp!=`number`||a.exp<=i||a.id!==await t(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(t,n,r,o){try{let e=await x(t,n,o);if(!e)return null;let s=i(r),l=c(a(y(t.cookieName),s),e.value,s,Math.floor(e.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 e(t,`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};
|
package/dist/database/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as createAesGcmCodec, t as SessionCodec } from "../codec-BPnk_EfF.js";
|
|
2
|
-
import { c as AccountsSession, d as AccountsTokens, f as AccountsUser, g as
|
|
3
|
-
export { type AccountsSession, type AccountsSessionPatch, type AccountsSessionStore, type AccountsTokens, type AccountsUser, type SessionCodec, type SessionSweepCutoffs, createAesGcmCodec };
|
|
2
|
+
import { _ as SessionSweepCutoffs, c as AccountsSession, d as AccountsTokens, f as AccountsUser, g as SessionDecodeError, l as AccountsSessionPatch, u as AccountsSessionStore } from "../types-CEuhm7Nv.js";
|
|
3
|
+
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{
|
|
1
|
+
import{c as e,i as t}from"../types-ICH7-e-H.js";export{t as SessionDecodeError,e 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 { u as AccountsSessionStore } from "../types-
|
|
2
|
+
import { u as AccountsSessionStore } from "../types-CEuhm7Nv.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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{i as e}from"../types-ICH7-e-H.js";const t=`CREATE TABLE "accounts_sessions" (
|
|
2
2
|
"id" text PRIMARY KEY,
|
|
3
3
|
"user_id" text NOT NULL,
|
|
4
4
|
"user" jsonb NOT NULL,
|
|
@@ -11,4 +11,4 @@ const e=`CREATE TABLE "accounts_sessions" (
|
|
|
11
11
|
"last_validated_at" timestamp with time zone NOT NULL,
|
|
12
12
|
"refresh_lease_until" timestamp with time zone
|
|
13
13
|
);
|
|
14
|
-
CREATE INDEX "accounts_sessions_user_id_idx" ON "accounts_sessions" ("user_id");`,
|
|
14
|
+
CREATE INDEX "accounts_sessions_user_id_idx" ON "accounts_sessions" ("user_id");`,n={encrypt:async e=>e,decrypt:async e=>e};function r(e){if(e instanceof Date)return e.getTime();if(typeof e==`string`)return new Date(e).getTime();if(typeof e==`number`)return e;throw Error(`Unexpected timestamp value in accounts session row`)}function i(e){return new Date(e)}function a(t){let a=t.table??`accounts_sessions`;if(!/^[a-z_][a-z0-9_]*$/.test(a))throw Error(`Invalid accounts session table name: ${a}`);let o=`"${a}"`,s=t.codec??n;async function c(e){return{accessToken:await s.encrypt(e.accessToken),refreshToken:e.refreshToken?await s.encrypt(e.refreshToken):null,idToken:e.idToken?await s.encrypt(e.idToken):null}}async function l(t){try{return{id:t.id,user:t.user,tokens:{accessToken:await s.decrypt(t.access_token),refreshToken:t.refresh_token?await s.decrypt(t.refresh_token):null,idToken:t.id_token?await s.decrypt(t.id_token):null,accessTokenExpiresAt:r(t.access_token_expires_at)},data:t.data,createdAt:r(t.created_at),lastValidatedAt:r(t.last_validated_at),refreshLeaseUntil:t.refresh_lease_until===null||t.refresh_lease_until===void 0?null:r(t.refresh_lease_until)}}catch(t){throw new e(t)}}return{async create(e){let n=await c(e.tokens);await t.query(`INSERT INTO ${o} ("id", "user_id", "user", "access_token", "refresh_token", "id_token", "access_token_expires_at", "data", "created_at", "last_validated_at", "refresh_lease_until") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, NULL)`,[e.id,e.user.id,e.user,n.accessToken,n.refreshToken,n.idToken,i(e.tokens.accessTokenExpiresAt),e.data,i(e.createdAt),i(e.lastValidatedAt)])},async read(e){let{rows:n}=await t.query(`SELECT * FROM ${o} WHERE "id" = $1`,[e]);return n[0]?l(n[0]):null},async update(e,n,r){let a=[],s=[e],u=(e,t)=>{s.push(t),a.push(`"${e}" = $${s.length}`)};if(n.user!==void 0&&(u(`user_id`,n.user.id),u(`user`,n.user)),n.tokens!==void 0){let e=await c(n.tokens);u(`access_token`,e.accessToken),u(`refresh_token`,e.refreshToken),u(`id_token`,e.idToken),u(`access_token_expires_at`,i(n.tokens.accessTokenExpiresAt))}if(n.data!==void 0&&u(`data`,n.data),n.lastValidatedAt!==void 0&&u(`last_validated_at`,i(n.lastValidatedAt)),n.refreshLeaseUntil!==void 0&&u(`refresh_lease_until`,n.refreshLeaseUntil===null?null:i(n.refreshLeaseUntil)),a.length===0){if(r===void 0)return this.read(e);let n=await t.query(`SELECT * FROM ${o} WHERE "id" = $1 AND "refresh_lease_until" = $2`,[e,i(r)]);return n.rows[0]?l(n.rows[0]):null}let d=`"id" = $1`;r!==void 0&&(s.push(i(r)),d+=` AND "refresh_lease_until" = $${s.length}`);let{rows:f}=await t.query(`UPDATE ${o} SET ${a.join(`, `)} WHERE ${d} RETURNING *`,s);return f[0]?l(f[0]):null},async claimRefreshLease(e,n,r){let{rows:a}=await t.query(`UPDATE ${o} SET "refresh_lease_until" = $2 WHERE "id" = $1 AND ("refresh_lease_until" IS NULL OR "refresh_lease_until" <= $3) RETURNING *`,[e,i(n),i(r)]);return a[0]?l(a[0]):null},async delete(e,n){if(n===void 0){let{rows:n}=await t.query(`DELETE FROM ${o} WHERE "id" = $1 RETURNING "id"`,[e]);return n.length>0}let{rows:r}=await t.query(`DELETE FROM ${o} WHERE "id" = $1 AND "refresh_lease_until" = $2 RETURNING "id"`,[e,i(n)]);return r.length>0},async sweep(e){let{rows:n}=await t.query(`WITH "removed" AS (DELETE FROM ${o} WHERE "created_at" < $1 OR "last_validated_at" < $2 RETURNING 1) SELECT count(*)::int AS "count" FROM "removed"`,[i(e.createdBefore),i(e.validatedBefore)]);return Number(n[0]?.count??0)}}}export{t as PG_SESSION_TABLE_SQL,a as createPgSessionStore};
|
package/dist/database/redis.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as SessionCodec } from "../codec-BPnk_EfF.js";
|
|
2
|
-
import { u as AccountsSessionStore } from "../types-
|
|
2
|
+
import { u as AccountsSessionStore } from "../types-CEuhm7Nv.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,8 +1,8 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{i as e}from"../types-ICH7-e-H.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
|
|
5
|
-
local current = redis.call('HGET', key, '${
|
|
5
|
+
local current = redis.call('HGET', key, '${t}')
|
|
6
6
|
if (current or '') ~= expectedLease then return 0 end
|
|
7
7
|
end
|
|
8
8
|
for index = 4, #ARGV, 2 do
|
|
@@ -14,30 +14,30 @@ for index = 4, #ARGV, 2 do
|
|
|
14
14
|
end
|
|
15
15
|
redis.call('PEXPIRE', key, ttl)
|
|
16
16
|
return 1
|
|
17
|
-
`,
|
|
17
|
+
`,r=`
|
|
18
18
|
local key, leaseUntil, now, ttl = KEYS[1], ARGV[1], ARGV[2], ARGV[3]
|
|
19
19
|
if redis.call('EXISTS', key) == 0 then return nil end
|
|
20
|
-
local current = redis.call('HGET', key, '${
|
|
20
|
+
local current = redis.call('HGET', key, '${t}')
|
|
21
21
|
if current and current ~= '' and tonumber(current) > tonumber(now) then
|
|
22
22
|
return nil
|
|
23
23
|
end
|
|
24
|
-
redis.call('HSET', key, '${
|
|
24
|
+
redis.call('HSET', key, '${t}', leaseUntil)
|
|
25
25
|
redis.call('PEXPIRE', key, ttl)
|
|
26
26
|
return redis.call('HGETALL', key)
|
|
27
|
-
`,
|
|
27
|
+
`,i=`
|
|
28
28
|
local key, checkLease, expectedLease = KEYS[1], ARGV[1], ARGV[2]
|
|
29
29
|
if redis.call('EXISTS', key) == 0 then return 0 end
|
|
30
30
|
if checkLease == '1' then
|
|
31
|
-
local current = redis.call('HGET', key, '${
|
|
31
|
+
local current = redis.call('HGET', key, '${t}')
|
|
32
32
|
if (current or '') ~= expectedLease then return 0 end
|
|
33
33
|
end
|
|
34
34
|
redis.call('DEL', key)
|
|
35
35
|
return 1
|
|
36
|
-
`,
|
|
36
|
+
`,a={encrypt:async e=>e,decrypt:async e=>e};function o(e){return e==null||e===``?null:typeof e==`string`?e:JSON.stringify(e)}function s(e){let t=o(e),n=t===null?NaN:Number(t);if(!Number.isFinite(n))throw Error(`Unexpected timestamp in accounts session hash`);return n}function c(e){if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{return e}}function l(e){if(!e)return null;if(Array.isArray(e)){if(e.length===0)return null;let t={};for(let n=0;n<e.length;n+=2)t[String(e[n])]=e[n+1];return t}let t=e;return Object.keys(t).length>0?t:null}function u(u){let{redis:d}=u,f=u.codec??a,p=u.prefix??`accounts_sessions:`,m=u.ttlMs??26784e5,h=e=>`${p}${e}`;async function g(e){let n={};if(e.user&&(n.user=JSON.stringify(e.user)),e.data!==void 0&&(n.data=JSON.stringify(e.data)),e.lastValidatedAt!==void 0&&(n.lastValidatedAt=String(e.lastValidatedAt)),e.refreshLeaseUntil!==void 0&&(n[t]=e.refreshLeaseUntil===null?``:String(e.refreshLeaseUntil)),e.tokens){let{accessToken:t,refreshToken:r,idToken:i,accessTokenExpiresAt:a}=e.tokens;n.accessToken=await f.encrypt(t),n.refreshToken=r?await f.encrypt(r):``,n.idToken=i?await f.encrypt(i):``,n.accessTokenExpiresAt=String(a)}return n}async function _(n,r){try{let e=o(r.refreshToken),i=o(r.idToken),a=o(r[t]);return{id:n,user:c(r.user),tokens:{accessToken:await f.decrypt(o(r.accessToken)??``),refreshToken:e?await f.decrypt(e):null,idToken:i?await f.decrypt(i):null,accessTokenExpiresAt:s(r.accessTokenExpiresAt)},data:c(r.data),createdAt:s(r.createdAt),lastValidatedAt:s(r.lastValidatedAt),refreshLeaseUntil:a===null?null:Number(a)}}catch(t){throw new e(t)}}async function v(e){let t=l(await d.hgetall(h(e)));return t?_(e,t):null}return{async create(e){let t=await g(e);t.createdAt=String(e.createdAt);let n=Object.entries(t).filter(([,e])=>e!==``);await d.eval(`
|
|
37
37
|
local key, ttl = KEYS[1], ARGV[1]
|
|
38
38
|
for index = 2, #ARGV, 2 do
|
|
39
39
|
redis.call('HSET', key, ARGV[index], ARGV[index + 1])
|
|
40
40
|
end
|
|
41
41
|
redis.call('PEXPIRE', key, ttl)
|
|
42
42
|
return 1
|
|
43
|
-
`,[
|
|
43
|
+
`,[h(e.id)],[String(m),...n.flat()])},read:v,async update(e,t,r){let i=await g(t),a=await d.eval(n,[h(e)],[r===void 0?`0`:`1`,r===void 0?``:String(r),String(m),...Object.entries(i).flat()]);return Number(a)===1?v(e):null},async claimRefreshLease(e,t,n){let i=l(await d.eval(r,[h(e)],[String(t),String(n),String(m)]));return i?_(e,i):null},async delete(e,t){let n=await d.eval(i,[h(e)],[t===void 0?`0`:`1`,t===void 0?``:String(t)]);return Number(n)===1}}}export{u as createRedisSessionStore};
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import { c as AccountsSession, t as AccountsAuthConfig, u as AccountsSessionStore } from "./types-
|
|
1
|
+
import { c as AccountsSession, t as AccountsAuthConfig, u as AccountsSessionStore } from "./types-CEuhm7Nv.js";
|
|
2
2
|
//#region src/core/cookies.d.ts
|
|
3
3
|
declare function requestOrigin(request: Request): string;
|
|
4
|
+
/**
|
|
5
|
+
* Rewrites a request's `cookie` header to what the browser would send once it
|
|
6
|
+
* has applied the given Set-Cookie headers. A proxy that resolved a session
|
|
7
|
+
* hands the cookies it issued to the render this way, so the render reads
|
|
8
|
+
* what the next request would carry instead of going back to the store.
|
|
9
|
+
*/
|
|
10
|
+
declare function forwardCookies(headers: Headers, issued: readonly string[]): void;
|
|
4
11
|
declare function sanitizeRedirectPath(rawRedirect: string | null | undefined, origin: string): string;
|
|
5
12
|
//#endregion
|
|
6
13
|
//#region src/core/cache.d.ts
|
|
@@ -60,4 +67,4 @@ declare function createAccountsAuth<Data>(input: AccountsAuthConfig<Data>): {
|
|
|
60
67
|
};
|
|
61
68
|
type AccountsAuth<Data> = ReturnType<typeof createAccountsAuth<Data>>;
|
|
62
69
|
//#endregion
|
|
63
|
-
export { SessionResolution as a, cacheCookieBase as c, createMemorySessionStore as i,
|
|
70
|
+
export { SessionResolution as a, cacheCookieBase as c, sanitizeRedirectPath as d, createMemorySessionStore as i, forwardCookies as l, SessionCookies as n, GuardOptions as o, createAccountsAuth as r, GuardResult as s, AccountsAuth as t, requestOrigin as u };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { n as accountsEndpoint, r as fetchUserInfo, t as AccountsFetchOptions } from "./oidc-
|
|
3
|
-
import { a as SessionResolution, c as cacheCookieBase, i as createMemorySessionStore, l as
|
|
4
|
-
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, type SessionResolution, type SessionSweepCutoffs, type SignInInput, accountsEndpoint, cacheCookieBase, createAccountsAuth, createMemorySessionStore, fetchUserInfo, isAccessDenied, requestOrigin, sanitizeRedirectPath };
|
|
1
|
+
import { _ as SessionSweepCutoffs, a as AccountsLifetimes, c as AccountsSession, d as AccountsTokens, f as AccountsUser, g as SessionDecodeError, h as RevalidateInput, i as AccountsErrorPhase, l as AccountsSessionPatch, m as OAuthTokenError, n as AccountsCacheConfig, o as AccountsPaths, p as DEFAULT_LIFETIMES, r as AccountsErrorEvent, s as AccountsRequestError, t as AccountsAuthConfig, u as AccountsSessionStore, v as SignInInput, y as isAccessDenied } from "./types-CEuhm7Nv.js";
|
|
2
|
+
import { n as accountsEndpoint, r as fetchUserInfo, t as AccountsFetchOptions } from "./oidc-CaYOiMFO.js";
|
|
3
|
+
import { a as SessionResolution, c as cacheCookieBase, d as sanitizeRedirectPath, i as createMemorySessionStore, l as forwardCookies, n as SessionCookies, o as GuardOptions, r as createAccountsAuth, s as GuardResult, t as AccountsAuth, u as requestOrigin } from "./index-wc8vz71h.js";
|
|
4
|
+
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}from"./cache-
|
|
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-kH1-Y-mz.js";import{a as _,i as v,n as y,o as b,r as x,s as S,t as C}from"./types-ICH7-e-H.js";import{a as w,c as T,d as E,i as D,l as O,o as k,r as A,s as j,t as M,u as N}from"./oidc-D2VwAdd3.js";function P(e,t){return[...d(e.cookieName,t),...m(e,t)]}function F(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?P(e,r):[]},d=await t.load(i);if(!d)return l;let{deferRevalidation:m}=e;if(m&&t.revalidationDue(d)&&I(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){b(e,`revalidate`,t)}let g=await p(e,h,r,e.now());return{session:h,cookies:g?[g]:[]}}}function I(e,t,n,r){try{return t(async()=>{try{await n.revalidate(r)}catch(t){b(e,`revalidate`,t)}}),!0}catch(t){return b(e,`revalidate`,t),!1}}function L(e,t){let n=F(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 R=/^[A-Za-z0-9_-]{1,128}$/,z=new Set([`login_required`,`consent_required`,`interaction_required`,`account_selection_required`]);function B(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){b(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 A(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=_&&R.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 T=a(S.redirectPath,i),D=c.get(`error`);if(D)return S.silent&&z.has(D)?C(l(u(i,T))):C(l(d(i,D,c.get(`error_description`))));let O=c.get(`code`);if(!O)return C(l(d(i,`invalid_request`,null)));let A,M,N;try{let e=await w(r,{code:O,verifier:S.verifier,redirectUri:new URL(r.paths.callback,i).toString()});A=E(e,null,r.now()),M=await j(k(r),A.accessToken),N=await r.onSignIn({user:M,accessToken:A.accessToken,redirectPath:T,previous:null})}catch(e){return b(r,`sign_in`,e),e instanceof x?C(l(d(i,e.code,e.description||null))):C(l(d(i,`accounts_unavailable`,null)))}let P=f(e,r.cookieName);if(N===null){let e=l(d(i,`access_denied`,null));P!==null&&(await v(P),t(e.headers,r.cookieName,i));for(let t of m(r,i))e.headers.append(`set-cookie`,t);return C(e)}let F,I;try{({cookieValue:F,session:I}=await s.start({user:M,tokens:A,data:N}))}catch(e){return b(r,`session_store`,e),C(l(d(i,`session_store_error`,null)))}P!==null&&await v(P);let L=l(new URL(T,i));g(L.headers,r.cookieName,F,i,r.lifetimes.absoluteMaxAgeMs);let B=await p(r,I,i,r.now());return B&&L.headers.append(`set-cookie`,B),C(L)}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?D(r,{origin:t,idToken:n.tokens.idToken}):new URL(r.paths.logoutComplete,t).toString(),a=l(i,303);for(let e of P(r,t))a.headers.append(`set-cookie`,e);return a}return{login:y,callback:S,logout:C}}const V=e=>new Promise(t=>setTimeout(t,e));function H(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(n),a;try{a=await t.read(i)}catch(n){if(!(n instanceof v))throw n;return b(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=T(32),i=e.now(),a={id:await N(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 O(e,o.tokens.refreshToken,Math.max(n.refreshLeaseMs-1e3,n.refreshLeaseMs/2));return await t.update(o.id,{tokens:E(r,o.tokens,e.now()),refreshLeaseUntil:null},s)??t.read(o.id)}catch(n){if(n instanceof x&&n.code===`invalid_grant`)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 b(e,`refresh`,n),r??o;throw n}}async function l(r,a){for(;;){await V(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){b(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 j(k(e),t.tokens.accessToken)}catch(n){return _(n)?null:(b(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 U(){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 W(e){let t=S(e),n=H(t),r=B(t,n),i=L(t,n),a=F(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,y as DEFAULT_LIFETIMES,x as OAuthTokenError,v as SessionDecodeError,M as accountsEndpoint,u as cacheCookieBase,W as createAccountsAuth,U as createMemorySessionStore,j as fetchUserInfo,r as forwardCookies,_ as isAccessDenied,o as requestOrigin,a as sanitizeRedirectPath};
|
package/dist/next.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import { c as AccountsSession } from "./types-
|
|
2
|
-
import { t as AccountsAuth } from "./index-
|
|
1
|
+
import { c as AccountsSession } from "./types-CEuhm7Nv.js";
|
|
2
|
+
import { t as AccountsAuth } from "./index-wc8vz71h.js";
|
|
3
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
3
4
|
//#region src/next/index.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The response a proxy returns to let a request through with the cookies the
|
|
7
|
+
* guard or the resolver issued: appended for the browser, and applied to the
|
|
8
|
+
* request as well, so the render reads the session the proxy just resolved
|
|
9
|
+
* instead of going back to the store for it.
|
|
10
|
+
*/
|
|
11
|
+
declare function continueRequest(request: NextRequest, issued?: readonly string[]): NextResponse;
|
|
4
12
|
declare function withNextRequestScope<Data>(auth: AccountsAuth<Data>): {
|
|
5
13
|
getSession(): Promise<AccountsSession<Data> | null>;
|
|
6
14
|
getAccessToken(): Promise<string | null>;
|
|
7
15
|
updateSessionData(update: (data: Data) => Data): Promise<AccountsSession<Data> | null>;
|
|
8
16
|
};
|
|
9
17
|
//#endregion
|
|
10
|
-
export { withNextRequestScope };
|
|
18
|
+
export { continueRequest, withNextRequestScope };
|
package/dist/next.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{d as e,n as t,s as n}from"./cache-kH1-Y-mz.js";import{cookies as r}from"next/headers";import{NextResponse as i,connection as a}from"next/server";function o(t,n=[]){e(t.headers,n);let r=i.next({request:{headers:t.headers}});for(let e of n)r.headers.append(`set-cookie`,e);return r}async function s(e){await a();let i=await r(),o=e=>i.get(n(e,!0))?.value||i.get(n(e,!1))?.value||null;return{session:o(e),cache:o(t(e))}}async function c(e){let i=await r(),a=t(e);for(let e of[n(a,!0),n(a,!1)])try{i.delete(e)}catch{}}function l(e){let t=e.cookieName;return{async getSession(){return e.sessionFromCookies(await s(t))},async getAccessToken(){return e.accessTokenFromCookies(await s(t))},async updateSessionData(n){let r=await e.updateSessionData(await s(t),n);return r&&await c(t),r}}}export{o as continueRequest,l as withNextRequestScope};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,r as t,t as n}from"./types-ICH7-e-H.js";function r(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function i(e){return r(crypto.getRandomValues(new Uint8Array(e)))}async function a(e){let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return r(new Uint8Array(t))}function o(e,t){return new URL(t,e).toString()}function s(e){return{issuer:e.issuer,fetch:e.fetch,timeoutMs:e.lifetimes.requestTimeoutMs}}async function c(t,r,i={},a){let s=t.fetch??globalThis.fetch.bind(globalThis),c=t.timeoutMs??e.requestTimeoutMs,l=a===void 0?c:Math.min(c,a-Date.now());if(l<=0)throw new n(`Accounts request deadline passed`,0);return s(o(t.issuer,r),{...i,cache:`no-store`,signal:AbortSignal.timeout(l)})}async function l(e,t){let n=i(24),r=i(32),s=new URL(o(e.issuer,`/api/auth/oauth2/authorize`));return s.searchParams.set(`client_id`,e.clientId),s.searchParams.set(`redirect_uri`,new URL(e.paths.callback,t.origin).toString()),s.searchParams.set(`response_type`,`code`),s.searchParams.set(`scope`,e.scope),s.searchParams.set(`state`,n),s.searchParams.set(`code_challenge`,await a(r)),s.searchParams.set(`code_challenge_method`,`S256`),t.silent&&s.searchParams.set(`prompt`,`none`),{url:s.toString(),state:n,verifier:r}}function u(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()}async function d(e,n,r,i=!0){let a=new URLSearchParams({client_id:e.clientId,...n});e.clientSecret&&a.set(`client_secret`,e.clientSecret),e.audience&&i&&a.set(`resource`,e.audience);let o=await c(s(e),`/api/auth/oauth2/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:a},r);if(!o.ok){let a=await o.text().catch(()=>``),s=`unknown_error`,c=a;try{let e=JSON.parse(a);s=e.error??s,c=e.error_description??c}catch{}if(i&&e.audience&&s===`invalid_request`&&/resource/i.test(c))return d(e,n,r,!1);throw new t(o.status,s,c)}return await o.json()}function f(e,t){return d(e,{grant_type:`authorization_code`,code:t.code,code_verifier:t.verifier,redirect_uri:t.redirectUri})}function p(e,t,n){return d(e,{grant_type:`refresh_token`,refresh_token:t},n===void 0?void 0:Date.now()+n)}async function m(e,t){let r=await c(e,`/api/auth/oauth2/userinfo`,{headers:{Authorization:`Bearer ${t}`}});if(!r.ok)throw new n(`Failed to load user info: ${r.status}`,r.status);let i=await r.json();return{id:i.sub,email:i.email??``,name:i.name??i.email??i.sub,image:i.picture??null}}function h(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{f as a,i as c,h as d,u as i,p as l,c as n,s as o,l as r,m as s,o as t,a as u};
|
package/dist/testing.d.ts
CHANGED
|
@@ -122,6 +122,18 @@ type AccountsAuthConfig<Data> = {
|
|
|
122
122
|
* ends the session; any other failure keeps the captured copy.
|
|
123
123
|
*/
|
|
124
124
|
revalidateUser?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Runs a due revalidation after the response rather than in front of it,
|
|
127
|
+
* through the platform's own primitive: `after` from `next/server`, or
|
|
128
|
+
* `(task) => ctx.waitUntil(task())` on a Worker. The request is answered
|
|
129
|
+
* from the stored session with a cache cookie that lasts
|
|
130
|
+
* `lifetimes.retryIntervalMs`, and the first request after that reads the
|
|
131
|
+
* revalidated row, so no request waits on the accounts round trip and a
|
|
132
|
+
* session accounts has ended is honoured within one revalidation interval
|
|
133
|
+
* plus one retry interval. A token refresh is never deferred, and a
|
|
134
|
+
* scheduler that throws is answered by revalidating inline.
|
|
135
|
+
*/
|
|
136
|
+
deferRevalidation?(task: () => Promise<void>): void;
|
|
125
137
|
/**
|
|
126
138
|
* Reports a failure the flow handled rather than threw. Every one of them is
|
|
127
139
|
* invisible otherwise, which turns `session_store_error` into a redirect
|
|
@@ -143,6 +155,17 @@ declare class AccountsRequestError extends Error {
|
|
|
143
155
|
readonly status: number;
|
|
144
156
|
constructor(message: string, status: number);
|
|
145
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* A stored session that cannot be turned back into one: a token the codec
|
|
160
|
+
* cannot decrypt because another key wrote it, a column that does not hold
|
|
161
|
+
* what it should. The session manager reads it as the session being over,
|
|
162
|
+
* removes the row and sends the user back to sign in, so a store that decodes
|
|
163
|
+
* what it stored raises this rather than the failure underneath; every other
|
|
164
|
+
* store failure is a fault and propagates.
|
|
165
|
+
*/
|
|
166
|
+
declare class SessionDecodeError extends Error {
|
|
167
|
+
constructor(cause: unknown);
|
|
168
|
+
}
|
|
146
169
|
declare class OAuthTokenError extends AccountsRequestError {
|
|
147
170
|
readonly code: string;
|
|
148
171
|
readonly description: string;
|
|
@@ -156,4 +179,4 @@ declare class OAuthTokenError extends AccountsRequestError {
|
|
|
156
179
|
*/
|
|
157
180
|
declare function isAccessDenied(error: unknown): boolean;
|
|
158
181
|
//#endregion
|
|
159
|
-
export {
|
|
182
|
+
export { SessionSweepCutoffs as _, AccountsLifetimes as a, AccountsSession as c, AccountsTokens as d, AccountsUser as f, SessionDecodeError as g, RevalidateInput as h, AccountsErrorPhase as i, AccountsSessionPatch as l, OAuthTokenError as m, AccountsCacheConfig as n, AccountsPaths as o, DEFAULT_LIFETIMES as p, AccountsErrorEvent as r, AccountsRequestError as s, AccountsAuthConfig as t, AccountsSessionStore as u, SignInInput as v, isAccessDenied as y };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){let t=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2)t[n/2]=Number.parseInt(e.slice(n,n+2),16);return t}function t(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function n(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=t+`=`.repeat((4-t.length%4)%4),r;try{r=atob(n)}catch{throw Error(`Malformed encrypted value`)}let i=new Uint8Array(r.length);for(let e=0;e<r.length;e++)i[e]=r.charCodeAt(e);return i}function r(e){let r=null,i=()=>r??=crypto.subtle.importKey(`raw`,e,{name:`AES-GCM`},!1,[`encrypt`,`decrypt`]);return{async encrypt(e){let n=crypto.getRandomValues(new Uint8Array(12)),r=new Uint8Array(await crypto.subtle.encrypt({name:`AES-GCM`,iv:n},await i(),new TextEncoder().encode(e))),a=new Uint8Array(12+r.length);return a.set(n),a.set(r,12),t(a)},async decrypt(e){let t=n(e);if(t.length<28)throw Error(`Malformed encrypted value`);let r;try{r=await crypto.subtle.decrypt({name:`AES-GCM`,iv:t.subarray(0,12)},await i(),t.subarray(12))}catch{throw Error(`Malformed encrypted value`)}return new TextDecoder().decode(r)}}}function i(t){if(!/^[0-9a-fA-F]{64}$/.test(t))throw Error(`AES-GCM codec key must be 64 hex characters (32 bytes)`);return r(e(t))}function a(e){let t=null;return()=>t??=crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e)).then(e=>r(new Uint8Array(e)))}const o={login:`/api/auth/login`,callback:`/api/auth/callback`,logout:`/api/auth/logout`,logoutComplete:`/api/auth/logout-complete`,error:`/auth/error`},s={absoluteMaxAgeMs:2592e6,idleMaxAgeMs:6048e5,revalidateIntervalMs:12e4,refreshBeforeExpiryMs:3e5,flowMaxAgeMs:6e5,refreshLeaseMs:2e4,leaseWaitMs:5e3,requestTimeoutMs:1e4,retryIntervalMs:1e4},c=Object.freeze({});function l({phase:e,error:t}){console.error(`[aui-auth] ${e}`,t)}function u(e,t,n){try{e.onError({phase:t,error:n})}catch{}}function d(e){return{...e,scope:e.scope??`openid profile email offline_access`,onSignIn:e.onSignIn??(async()=>c),onRevalidate:e.onRevalidate??(async()=>c),onError:e.onError??l,revalidateUser:e.revalidateUser??!1,paths:{...o,...e.paths},lifetimes:{...s,...e.lifetimes},fetch:e.fetch??globalThis.fetch.bind(globalThis),now:e.now??Date.now,cache:e.cache?{codec:a(e.cache.secret),maxAgeMs:e.cache.maxAgeMs??6e4}:null,audience:e.audience===!1?null:e.audience??new URL(`/api/auth`,e.issuer).toString()}}var f=class extends Error{status;constructor(e,t){super(e),this.name=`AccountsRequestError`,this.status=t}},p=class extends Error{constructor(e){super(`Stored session could not be decoded`,{cause:e}),this.name=`SessionDecodeError`}},m=class extends f{code;description;constructor(e,t,n){super(`Token request failed: ${e} ${t} ${n}`,e),this.name=`OAuthTokenError`,this.code=t,this.description=n}};const h=new Set([408,425,429]);function g(e){return e instanceof f&&e.status>=400&&e.status<500&&!h.has(e.status)}export{g as a,i as c,p as i,s as n,u as o,m as r,d as s,f as t};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aui-auth",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Server side sessions for web apps that sign in through assistant-ui accounts: OIDC code flow with PKCE, tokens kept in the app's database, single flight refresh",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/dist/cache-BlNb0qE2.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{g as e,u as t}from"./oidc-Dmqfk0L9.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){let n=i(t);return[n,!n].map(t=>c(a(e,t),``,t,0))}function d(e,t,n){for(let r of u(t,n))e.append(`set-cookie`,r)}function f(e,t=307){return new Response(null,{status:t,headers:{location:e.toString()}})}function p(e,t){return`${e}_flow_${t}`}function m(e){return btoa(JSON.stringify(e)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function h(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 g(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 _=4096;function v(e){return`${e}_cache`}function y(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 b(e,t,n){if(!e.cache)return null;let r=y(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 x(e,n,r,i){if(!e.cache||!n||!r)return null;let a;try{let t=await e.cache.codec();a=JSON.parse(await t.decrypt(n))}catch{return null}return a.v!==1||typeof a.exp!=`number`||a.exp<=i||a.id!==await t(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 S(t,n,r,o){try{let e=await b(t,n,o);if(!e)return null;let s=i(r),l=c(a(v(t.cookieName),s),e.value,s,Math.floor(e.maxAgeMs/1e3));if(l.length>_)throw Error(`Cache cookie is ${l.length} bytes and browsers drop cookies over ${_}; the session data is too large to cache`);return l}catch(n){return e(t,`cache_cookie`,n),null}}function C(e,t){return e.cache?u(v(e.cookieName),t):[]}export{l as _,d as a,h as c,o as d,s as f,c as g,g as h,x as i,m as l,r as m,v as n,u as o,f as p,S as r,a as s,C as t,p as u};
|
package/dist/codec-D-31dtWO.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function e(e){let t=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2)t[n/2]=Number.parseInt(e.slice(n,n+2),16);return t}function t(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function n(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=t+`=`.repeat((4-t.length%4)%4),r;try{r=atob(n)}catch{throw Error(`Malformed encrypted value`)}let i=new Uint8Array(r.length);for(let e=0;e<r.length;e++)i[e]=r.charCodeAt(e);return i}function r(e){let r=null,i=()=>r??=crypto.subtle.importKey(`raw`,e,{name:`AES-GCM`},!1,[`encrypt`,`decrypt`]);return{async encrypt(e){let n=crypto.getRandomValues(new Uint8Array(12)),r=new Uint8Array(await crypto.subtle.encrypt({name:`AES-GCM`,iv:n},await i(),new TextEncoder().encode(e))),a=new Uint8Array(12+r.length);return a.set(n),a.set(r,12),t(a)},async decrypt(e){let t=n(e);if(t.length<28)throw Error(`Malformed encrypted value`);let r=await crypto.subtle.decrypt({name:`AES-GCM`,iv:t.subarray(0,12)},await i(),t.subarray(12));return new TextDecoder().decode(r)}}}function i(t){if(!/^[0-9a-fA-F]{64}$/.test(t))throw Error(`AES-GCM codec key must be 64 hex characters (32 bytes)`);return r(e(t))}function a(e){let t=null;return()=>t??=crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e)).then(e=>r(new Uint8Array(e)))}export{a as n,i as t};
|
package/dist/oidc-Dmqfk0L9.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./codec-D-31dtWO.js";const t={login:`/api/auth/login`,callback:`/api/auth/callback`,logout:`/api/auth/logout`,logoutComplete:`/api/auth/logout-complete`,error:`/auth/error`},n={absoluteMaxAgeMs:2592e6,idleMaxAgeMs:6048e5,revalidateIntervalMs:12e4,refreshBeforeExpiryMs:3e5,flowMaxAgeMs:6e5,refreshLeaseMs:2e4,leaseWaitMs:5e3,requestTimeoutMs:1e4,retryIntervalMs:1e4},r=Object.freeze({});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{}}function o(a){return{...a,scope:a.scope??`openid profile email offline_access`,onSignIn:a.onSignIn??(async()=>r),onRevalidate:a.onRevalidate??(async()=>r),onError:a.onError??i,revalidateUser:a.revalidateUser??!1,paths:{...t,...a.paths},lifetimes:{...n,...a.lifetimes},fetch:a.fetch??globalThis.fetch.bind(globalThis),now:a.now??Date.now,cache:a.cache?{codec:e(a.cache.secret),maxAgeMs:a.cache.maxAgeMs??6e4}:null,audience:a.audience===!1?null:a.audience??new URL(`/api/auth`,a.issuer).toString()}}var s=class extends Error{status;constructor(e,t){super(e),this.name=`AccountsRequestError`,this.status=t}},c=class extends s{code;description;constructor(e,t,n){super(`Token request failed: ${e} ${t} ${n}`,e),this.name=`OAuthTokenError`,this.code=t,this.description=n}};const l=new Set([408,425,429]);function u(e){return e instanceof s&&e.status>=400&&e.status<500&&!l.has(e.status)}function d(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function f(e){return d(crypto.getRandomValues(new Uint8Array(e)))}async function p(e){let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return d(new Uint8Array(t))}function m(e,t){return new URL(t,e).toString()}function h(e){return{issuer:e.issuer,fetch:e.fetch,timeoutMs:e.lifetimes.requestTimeoutMs}}async function g(e,t,r={},i){let a=e.fetch??globalThis.fetch.bind(globalThis),o=e.timeoutMs??n.requestTimeoutMs,c=i===void 0?o:Math.min(o,i-Date.now());if(c<=0)throw new s(`Accounts request deadline passed`,0);return a(m(e.issuer,t),{...r,cache:`no-store`,signal:AbortSignal.timeout(c)})}async function _(e,t){let n=f(24),r=f(32),i=new URL(m(e.issuer,`/api/auth/oauth2/authorize`));return i.searchParams.set(`client_id`,e.clientId),i.searchParams.set(`redirect_uri`,new URL(e.paths.callback,t.origin).toString()),i.searchParams.set(`response_type`,`code`),i.searchParams.set(`scope`,e.scope),i.searchParams.set(`state`,n),i.searchParams.set(`code_challenge`,await p(r)),i.searchParams.set(`code_challenge_method`,`S256`),t.silent&&i.searchParams.set(`prompt`,`none`),{url:i.toString(),state:n,verifier:r}}function v(e,t){let n=new URL(m(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()}async function y(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 a=await g(h(e),`/api/auth/oauth2/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:i},n);if(!a.ok){let i=await a.text().catch(()=>``),o=`unknown_error`,s=i;try{let e=JSON.parse(i);o=e.error??o,s=e.error_description??s}catch{}if(r&&e.audience&&o===`invalid_request`&&/resource/i.test(s))return y(e,t,n,!1);throw new c(a.status,o,s)}return await a.json()}function b(e,t){return y(e,{grant_type:`authorization_code`,code:t.code,code_verifier:t.verifier,redirect_uri:t.redirectUri})}function x(e,t,n){return y(e,{grant_type:`refresh_token`,refresh_token:t},n===void 0?void 0:Date.now()+n)}async function S(e,t){let n=await g(e,`/api/auth/oauth2/userinfo`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)throw new s(`Failed to load user info: ${n.status}`,n.status);let r=await n.json();return{id:r.sub,email:r.email??``,name:r.name??r.email??r.sub,image:r.picture??null}}function C(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{o as _,b as a,f as c,C as d,s as f,a as g,u as h,v as i,x as l,c as m,g as n,h as o,n as p,_ as r,S as s,m as t,p as u};
|