@iaurelius/accounts-nextjs 0.3.0 → 0.4.0
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 +13 -6
- package/dist/config.d.ts +13 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -6
- package/dist/config.js.map +1 -1
- package/dist/handlers.d.ts.map +1 -1
- package/dist/handlers.js +13 -7
- package/dist/handlers.js.map +1 -1
- package/dist/proxy.d.ts +2 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +25 -17
- package/dist/proxy.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +25 -5
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +31 -6
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +103 -22
- package/dist/session.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @iaurelius/accounts-nextjs
|
|
2
2
|
|
|
3
|
-
Accounts by iAurelius for Next.js (App Router, Next 15.
|
|
3
|
+
Accounts by iAurelius for Next.js (App Router, Next 15.5.24+ and 16.3.3+).
|
|
4
4
|
|
|
5
5
|
People sign in on your application's hosted page, on your domain with passkeys, email codes and Google, and come back signed in. In your app you get:
|
|
6
6
|
- `auth()` and `currentUser()` on the server;
|
|
@@ -24,14 +24,16 @@ Copy them from your application in the console, under Apps and APIs:
|
|
|
24
24
|
```sh
|
|
25
25
|
NEXT_PUBLIC_ACCOUNTS_PUBLISHABLE_KEY=pk_live_…
|
|
26
26
|
ACCOUNTS_CLIENT_ID=…
|
|
27
|
-
# Production (a web app, https): its secret.
|
|
27
|
+
# Production (a web app, https): its secret. The development app (localhost) has none.
|
|
28
28
|
ACCOUNTS_CLIENT_SECRET=…
|
|
29
|
-
#
|
|
30
|
-
|
|
29
|
+
# Always: your own random secret for the session cookie (openssl rand -base64 32), one per environment.
|
|
30
|
+
ACCOUNTS_COOKIE_SECRET=…
|
|
31
31
|
# Optional: your API's identifier, for getToken().
|
|
32
32
|
# ACCOUNTS_AUDIENCE=https://api.example.com
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
`ACCOUNTS_COOKIE_SECRET` is required, in development and in production. It is the key of the session cookie, so whoever has it can write a session for anyone: keep it on your app's servers only, and never reuse the client secret for it (the SDK refuses to start if you do). Changing it signs everyone out.
|
|
36
|
+
|
|
35
37
|
The development app is a public app, with no secret and PKCE only. It allows `http://localhost` redirects, which a web app cannot have. Register it with this callback, and use your real port:
|
|
36
38
|
- `http://localhost:3000/api/accounts/callback` as the redirect URI;
|
|
37
39
|
- `http://localhost:3000/` as the sign-out URI.
|
|
@@ -48,7 +50,7 @@ import { accountsMiddleware } from "@iaurelius/accounts-nextjs/server";
|
|
|
48
50
|
export default accountsMiddleware({ protect: ["/dashboard(.*)"] });
|
|
49
51
|
|
|
50
52
|
export const config = {
|
|
51
|
-
matcher: ["/((?!_next
|
|
53
|
+
matcher: ["/((?!_next/static/|_next/image$|favicon\\.ico$).*)"],
|
|
52
54
|
};
|
|
53
55
|
```
|
|
54
56
|
|
|
@@ -58,6 +60,10 @@ The proxy does four things:
|
|
|
58
60
|
- It sends people who are signed out of a protected page to the sign-in, and back to that page afterwards. Protected API routes answer `401` instead.
|
|
59
61
|
- It hands the session to the rest of the request.
|
|
60
62
|
|
|
63
|
+
Keep the matcher as it is: it runs the proxy on every path except Next's build output (`/_next/static/…` and `/_next/image`) and `/favicon.ico` itself, each matched exactly. A matcher that skips paths by their extension (`.png`, `.csv`…) also skips your own pages asked that way, such as `app/files/[name]/page.tsx` for `/files/a.png`; one that skips a prefix without anchoring it (`favicon.ico` instead of `favicon\.ico$`) skips `/favicon.ico-acme/dashboard` for `app/[team]/dashboard`.
|
|
64
|
+
|
|
65
|
+
`protect` is a redirect for people, not the lock on your data. Check who is asking where the data is read: `await auth.protect()` in the page or layout, and `auth()` in route handlers and server actions. That check reads the session itself, so it holds even for a request the proxy did not see.
|
|
66
|
+
|
|
61
67
|
### 3. `app/layout.tsx`
|
|
62
68
|
|
|
63
69
|
```tsx
|
|
@@ -123,10 +129,11 @@ Your API checks that token with [`@iaurelius/accounts`](https://www.npmjs.com/pa
|
|
|
123
129
|
- **Sign-in:**
|
|
124
130
|
- Authorization code with PKCE (S256), `state` and `nonce`, and RFC 9207's `iss` checked.
|
|
125
131
|
- The ID token is verified: signature, audience and nonce.
|
|
126
|
-
- **Session cookie:** encrypted (A256GCM) with a key derived from
|
|
132
|
+
- **Session cookie:** encrypted (A256GCM) with a key derived from `ACCOUNTS_COOKIE_SECRET` (never from the client secret), `HttpOnly` and `SameSite=Lax`. On https it is `__Host-accounts_session`, `Secure` and host-only, so another subdomain of your domain cannot plant or shadow it; the sign-in attempt's cookie is `__Host-` too. The plain `__accounts_session` of earlier versions is not read on https and is removed when it comes along. `auth()` on a request the proxy did not see reads the plain name only when the app is on http for sure (`ACCOUNTS_APP_URL`, or else the request's `x-forwarded-proto`, says http). Responses that set it are `Cache-Control: private, no-store`.
|
|
127
133
|
- **Redirects:** after sign-in the person only ever goes back to a path of your app.
|
|
128
134
|
- **Sign-out:** only from your app's own pages (Origin checked). The refresh token is revoked and the hosted session ends.
|
|
129
135
|
- **Revocation:** a person who is banned or signed out everywhere is out at the next refresh.
|
|
136
|
+
- **Refresh:** only a refusal for good signs the person out: a `4xx` with an OAuth error, such as `invalid_grant` (revoked, banned), `invalid_client`, `invalid_scope` or `invalid_target` (your audience changed). If the application answers `429` or `5xx`, does not answer, or a `4xx` comes without an OAuth error (a firewall's page), the session and its refresh token are kept and the access token serves while it lasts. After a `429` (or a `503` with `Retry-After`), no refresh of the app is tried before the server's `Retry-After`; after anything else, only that person's refresh waits a few seconds. A refreshed ID token must be the same person (`iss`, `sub`, `aud`), and userinfo's `sub` must match.
|
|
130
137
|
|
|
131
138
|
## License
|
|
132
139
|
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { FetchLike } from "@iaurelius/accounts";
|
|
2
|
+
import type { RefreshBackoff } from "@iaurelius/accounts/oidc";
|
|
3
|
+
import type { SessionPauses } from "./session.js";
|
|
2
4
|
export type AccountsOptions = {
|
|
3
5
|
/** pk_live_… Default: NEXT_PUBLIC_ACCOUNTS_PUBLISHABLE_KEY. */
|
|
4
6
|
publishableKey?: string;
|
|
@@ -6,9 +8,15 @@ export type AccountsOptions = {
|
|
|
6
8
|
clientId?: string;
|
|
7
9
|
/**
|
|
8
10
|
* Default: ACCOUNTS_CLIENT_SECRET. A production web app has one; the development app (localhost) is a
|
|
9
|
-
* public app without it, with PKCE.
|
|
11
|
+
* public app without it, with PKCE.
|
|
10
12
|
*/
|
|
11
13
|
clientSecret?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Default: ACCOUNTS_COOKIE_SECRET. Required: your own random secret (32+ characters, `openssl rand -base64 32`)
|
|
16
|
+
* that encrypts the session cookie. Never the client secret: whoever has the key to the cookie can write one
|
|
17
|
+
* for anyone, so it must be a secret that only your app's servers hold.
|
|
18
|
+
*/
|
|
19
|
+
cookieSecret?: string;
|
|
12
20
|
/** Your API's identifier: the access token (getToken()) is issued for it. Default: ACCOUNTS_AUDIENCE. */
|
|
13
21
|
audience?: string | string[];
|
|
14
22
|
/** Where the SDK answers: sign-in, sign-up, callback, sign-out, session, token. Default /api/accounts. */
|
|
@@ -31,6 +39,10 @@ export type AccountsConfig = Required<Pick<AccountsOptions, "basePath" | "afterS
|
|
|
31
39
|
audience: string[] | undefined;
|
|
32
40
|
appUrl: string | undefined;
|
|
33
41
|
fetch: FetchLike | undefined;
|
|
42
|
+
/** When refreshes may be tried again after a 429 or a 503 with Retry-After (shared by the proxy's requests). */
|
|
43
|
+
backoff?: RefreshBackoff;
|
|
44
|
+
/** When one session's refresh may be tried again after it got no answer or a 5xx (that session only). */
|
|
45
|
+
pauses?: SessionPauses;
|
|
34
46
|
};
|
|
35
47
|
/** The settings from the options, else the environment; says exactly which ones are missing. */
|
|
36
48
|
export declare function configOf(o?: AccountsOptions): AccountsConfig;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,MAAM,eAAe,GAAG;IAC5B,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+HAA+H;IAC/H,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,kBAAkB,GAAG,sBAAsB,GAAG,mBAAmB,CAAC,CAAC,GAAG;IAC7I,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,gHAAgH;IAChH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,yGAAyG;IACzG,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,CAAC;AAMF,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,CAAC,GAAE,eAAoB,GAAG,cAAc,CAuChE"}
|
package/dist/config.js
CHANGED
|
@@ -7,15 +7,15 @@ export function configOf(o = {}) {
|
|
|
7
7
|
const publishableKey = clean(o.publishableKey) ?? clean(env.NEXT_PUBLIC_ACCOUNTS_PUBLISHABLE_KEY) ?? clean(env.ACCOUNTS_PUBLISHABLE_KEY);
|
|
8
8
|
const clientId = clean(o.clientId) ?? clean(env.ACCOUNTS_CLIENT_ID);
|
|
9
9
|
const clientSecret = clean(o.clientSecret) ?? clean(env.ACCOUNTS_CLIENT_SECRET);
|
|
10
|
-
const
|
|
10
|
+
const cookieSecret = clean(o.cookieSecret) ?? clean(env.ACCOUNTS_COOKIE_SECRET);
|
|
11
11
|
const missing = [
|
|
12
12
|
!publishableKey && "NEXT_PUBLIC_ACCOUNTS_PUBLISHABLE_KEY",
|
|
13
13
|
!clientId && "ACCOUNTS_CLIENT_ID",
|
|
14
|
-
//
|
|
15
|
-
!
|
|
14
|
+
// The cookie's own key, in development and in production: never derived from the client secret.
|
|
15
|
+
!cookieSecret && "ACCOUNTS_COOKIE_SECRET (a random secret of your own: openssl rand -base64 32)",
|
|
16
16
|
].filter(Boolean);
|
|
17
17
|
if (missing.length)
|
|
18
|
-
throw new AccountsError("missing_configuration", `Accounts needs ${missing.join(", ")}. Run \`npx @iaurelius/accounts init
|
|
18
|
+
throw new AccountsError("missing_configuration", `Accounts needs ${missing.join(", ")}. Run \`npx @iaurelius/accounts init\` for development; in production, copy the app's keys from the console (Apps and APIs → your web app) and generate ACCOUNTS_COOKIE_SECRET.`);
|
|
19
19
|
const audience = o.audience ?? clean(env.ACCOUNTS_AUDIENCE)?.split(/[\s,]+/).filter(Boolean);
|
|
20
20
|
const basePath = (o.basePath ?? "/api/accounts").replace(/\/+$/, "");
|
|
21
21
|
if (!/^\/[A-Za-z0-9/_-]*$/.test(basePath))
|
|
@@ -24,14 +24,15 @@ export function configOf(o = {}) {
|
|
|
24
24
|
if (!afterSignOutPath.startsWith("/") || afterSignOutPath.startsWith("//"))
|
|
25
25
|
throw new AccountsError("invalid_configuration", "afterSignOutPath is a path of your app, such as /.");
|
|
26
26
|
const appUrl = clean(o.appUrl) ?? clean(env.ACCOUNTS_APP_URL);
|
|
27
|
-
const cookieSecret = cookieSecretEnv ?? clientSecret;
|
|
28
27
|
if (cookieSecret.length < 32)
|
|
29
28
|
throw new AccountsError("invalid_configuration", "ACCOUNTS_COOKIE_SECRET must be at least 32 characters.");
|
|
29
|
+
if (cookieSecret === clientSecret)
|
|
30
|
+
throw new AccountsError("invalid_configuration", "ACCOUNTS_COOKIE_SECRET must be a secret of its own, not the client secret: generate one with openssl rand -base64 32.");
|
|
30
31
|
return {
|
|
31
32
|
issuer: issuerFromPublishableKey(publishableKey),
|
|
32
33
|
clientId: clientId,
|
|
33
34
|
clientSecret,
|
|
34
|
-
cookieSecret,
|
|
35
|
+
cookieSecret: cookieSecret,
|
|
35
36
|
audience: audience === undefined ? undefined : Array.isArray(audience) ? audience : [audience],
|
|
36
37
|
basePath,
|
|
37
38
|
afterSignOutPath,
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/handlers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAYlD,eAAO,MAAM,QAAQ,QAAS,OAAO,OAAO,cAAc,WAA0C,CAAC;AACrG,eAAO,MAAM,QAAQ,WAAY,MAAM,YAAkC,CAAC;AAE1E,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAWvE;AAqGD,mFAAmF;AACnF,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAqBrG"}
|
package/dist/handlers.js
CHANGED
|
@@ -4,8 +4,13 @@ import { verifyIdToken } from "@iaurelius/accounts";
|
|
|
4
4
|
import { OAuthError, authorizationUrl, endSessionUrl, exchangeCode, pkce, randomString, revokeToken } from "@iaurelius/accounts/oidc";
|
|
5
5
|
import { parseCookies, seal, serialize, unseal } from "./cookies.js";
|
|
6
6
|
import { clearSession, infoOf, profileOf, readSession, resolveSession, writeSession } from "./session.js";
|
|
7
|
-
const TX_COOKIE = "__accounts_tx_";
|
|
8
7
|
const TX_MAX_AGE = 600;
|
|
8
|
+
/**
|
|
9
|
+
* One cookie per sign-in attempt. On https a __Host- cookie (Path=/, as the prefix requires): a sibling subdomain
|
|
10
|
+
* cannot plant an attempt of its own; on http (localhost), under basePath.
|
|
11
|
+
*/
|
|
12
|
+
const txCookie = (state, secure) => `${secure ? "__Host-" : "__"}accounts_tx_${state.slice(0, 16)}`;
|
|
13
|
+
const txPath = (cfg, secure) => (secure ? "/" : cfg.basePath);
|
|
9
14
|
export const originOf = (req, cfg) => cfg.appUrl ?? new URL(req.url).origin;
|
|
10
15
|
export const isSecure = (origin) => origin.startsWith("https://");
|
|
11
16
|
/** Only paths of this app: never another origin (no open redirect). */
|
|
@@ -55,7 +60,8 @@ async function signIn(req, cfg, prompt) {
|
|
|
55
60
|
const nonce = randomString(24);
|
|
56
61
|
const tx = await seal({ typ: "tx", state, nonce, verifier, returnTo }, cfg.cookieSecret, "tx", TX_MAX_AGE);
|
|
57
62
|
// One cookie per sign-in: two tabs signing in at once do not overwrite each other.
|
|
58
|
-
const
|
|
63
|
+
const secure = isSecure(origin);
|
|
64
|
+
const cookie = serialize(txCookie(state, secure), tx, { secure, maxAge: TX_MAX_AGE, path: txPath(cfg, secure) });
|
|
59
65
|
const location = authorizationUrl({ issuer: cfg.issuer, clientId: cfg.clientId, redirectUri: `${origin}${cfg.basePath}/callback`, state, nonce, codeChallenge: challenge, resource: cfg.audience, prompt });
|
|
60
66
|
return redirect(location, [cookie], 302);
|
|
61
67
|
}
|
|
@@ -65,10 +71,10 @@ async function callback(req, cfg) {
|
|
|
65
71
|
const q = new URL(req.url).searchParams;
|
|
66
72
|
const state = q.get("state") ?? "";
|
|
67
73
|
const cookies = parseCookies(req.headers.get("cookie"));
|
|
68
|
-
const txName =
|
|
74
|
+
const txName = txCookie(state, secure);
|
|
69
75
|
const tx = state ? await unseal(cookies.get(txName), cfg.cookieSecret, "tx") : null;
|
|
70
76
|
const retry = `${cfg.basePath}/sign-in`;
|
|
71
|
-
const dropTx = [serialize(txName, "", { secure, maxAge: 0, path: cfg
|
|
77
|
+
const dropTx = [serialize(txName, "", { secure, maxAge: 0, path: txPath(cfg, secure) })];
|
|
72
78
|
if (!tx || tx.typ !== "tx" || tx.state !== state)
|
|
73
79
|
return errorPage("invalid_state", "This sign-in expired or was started in another browser. Start again from the app.", retry, dropTx);
|
|
74
80
|
const back = `${retry}?redirect_url=${encodeURIComponent(tx.returnTo)}`;
|
|
@@ -90,8 +96,8 @@ async function callback(req, cfg) {
|
|
|
90
96
|
const t = await exchangeCode({ issuer: cfg.issuer, clientId: cfg.clientId, clientSecret: cfg.clientSecret, fetch: cfg.fetch }, { code, redirectUri: `${origin}${cfg.basePath}/callback`, codeVerifier: tx.verifier, resource: cfg.audience });
|
|
91
97
|
if (!t.idToken)
|
|
92
98
|
throw new OAuthError("invalid_response", "No ID token: the app needs the openid scope.");
|
|
93
|
-
await verifyIdToken(t.idToken, { issuer: cfg.issuer, clientId: cfg.clientId, nonce: tx.nonce, fetch: cfg.fetch });
|
|
94
|
-
session = { at: t.accessToken, rt: t.refreshToken, it: t.idToken, exp: t.expiresAt, u: await profileOf(cfg, t.accessToken) };
|
|
99
|
+
const claims = await verifyIdToken(t.idToken, { issuer: cfg.issuer, clientId: cfg.clientId, nonce: tx.nonce, fetch: cfg.fetch });
|
|
100
|
+
session = { at: t.accessToken, rt: t.refreshToken, it: t.idToken, exp: t.expiresAt, u: await profileOf(cfg, t.accessToken, claims.sub) };
|
|
95
101
|
}
|
|
96
102
|
catch (e) {
|
|
97
103
|
const oe = e instanceof OAuthError ? e : new OAuthError("server_error", "Could not complete the sign-in.");
|
|
@@ -106,7 +112,7 @@ async function signOut(req, cfg) {
|
|
|
106
112
|
if (req.headers.get("origin") !== origin)
|
|
107
113
|
return json({ error: "forbidden", error_description: "Sign out from the app's own pages." }, 403);
|
|
108
114
|
const cookies = parseCookies(req.headers.get("cookie"));
|
|
109
|
-
const s = await readSession(cookies, cfg);
|
|
115
|
+
const s = await readSession(cookies, cfg, isSecure(origin));
|
|
110
116
|
const cleared = clearSession(cookies, cfg, isSecure(origin));
|
|
111
117
|
const after = `${origin}${cfg.afterSignOutPath}`;
|
|
112
118
|
if (!s)
|
package/dist/handlers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"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"}
|
package/dist/proxy.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { type NextRequest } from "next/server.js";
|
|
|
2
2
|
import { type AccountsOptions } from "./config.js";
|
|
3
3
|
/** Headers the proxy sets for the rest of the request; one sent by the browser is dropped. */
|
|
4
4
|
export declare const PATH_HEADER = "x-accounts-path";
|
|
5
|
+
/** "1" when the app is on https: auth() then reads the __Host- session cookie, as the proxy does. */
|
|
6
|
+
export declare const SECURE_HEADER = "x-accounts-secure";
|
|
5
7
|
export type RouteMatcher = (req: {
|
|
6
8
|
nextUrl: {
|
|
7
9
|
pathname: string;
|
package/dist/proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAK7D,8FAA8F;AAC9F,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAC7C,qGAAqG;AACrG,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAKjD,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,OAAO,KAAK,OAAO,CAAC;AAEzF,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,YAAY,CAMhG;AAED,MAAM,MAAM,yBAAyB,GAAG,eAAe,GAAG;IACxD,iGAAiG;IACjG,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,YAAY,CAAC;CAC9C,CAAC;AAIF,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,SAMvC,WAAW,KAAG,OAAO,CAAC,QAAQ,CAAC,CAkCjE"}
|
package/dist/proxy.js
CHANGED
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
// routes, keeps the session fresh (refresh before the access token expires), protects the routes it is
|
|
3
3
|
// told to, and hands the fresh session to the rest of the request (auth(), server components).
|
|
4
4
|
import { NextResponse } from "next/server.js";
|
|
5
|
+
import { refreshBackoff } from "@iaurelius/accounts/oidc";
|
|
5
6
|
import { configOf } from "./config.js";
|
|
6
7
|
import { parseCookies } from "./cookies.js";
|
|
7
8
|
import { handleAccountsRoute, isSecure, originOf } from "./handlers.js";
|
|
8
|
-
import { applySetCookies, cookieHeader, resolveSession } from "./session.js";
|
|
9
|
+
import { applySetCookies, cookieHeader, resolveSession, sessionPauses } from "./session.js";
|
|
9
10
|
/** Headers the proxy sets for the rest of the request; one sent by the browser is dropped. */
|
|
10
11
|
export const PATH_HEADER = "x-accounts-path";
|
|
12
|
+
/** "1" when the app is on https: auth() then reads the __Host- session cookie, as the proxy does. */
|
|
13
|
+
export const SECURE_HEADER = "x-accounts-secure";
|
|
14
|
+
/** A response that carries the session's cookie (encrypted tokens) is for this browser only, never for a cache. */
|
|
15
|
+
const PRIVATE = "private, no-store";
|
|
11
16
|
/** A matcher from paths or patterns: "/dashboard(.*)" matches /dashboard and everything under it. */
|
|
12
17
|
export function createRouteMatcher(patterns) {
|
|
13
18
|
const list = (Array.isArray(patterns) ? patterns : [patterns]).map((p) => (p instanceof RegExp ? p : new RegExp(`^${p}$`)));
|
|
@@ -19,32 +24,38 @@ export function createRouteMatcher(patterns) {
|
|
|
19
24
|
const isApi = (req) => req.nextUrl.pathname.startsWith("/api/") || (req.headers.get("accept") ?? "").includes("application/json");
|
|
20
25
|
export function accountsMiddleware(options = {}) {
|
|
21
26
|
const isProtected = !options.protect ? null : typeof options.protect === "function" ? options.protect : createRouteMatcher(options.protect);
|
|
27
|
+
// After a 429 (or a 503 with Retry-After) of the token endpoint, no request refreshes again before its
|
|
28
|
+
// Retry-After. Any other failure pauses only the refresh of the session that met it.
|
|
29
|
+
const backoff = refreshBackoff();
|
|
30
|
+
const pauses = sessionPauses();
|
|
22
31
|
return async function proxy(req) {
|
|
23
|
-
const cfg = configOf(options);
|
|
32
|
+
const cfg = { ...configOf(options), backoff, pauses };
|
|
24
33
|
const own = await handleAccountsRoute(req, cfg);
|
|
25
34
|
if (own)
|
|
26
35
|
return own;
|
|
27
36
|
const origin = originOf(req, cfg);
|
|
37
|
+
const secure = isSecure(origin);
|
|
28
38
|
const cookies = parseCookies(req.headers.get("cookie"));
|
|
29
|
-
const { session, setCookies } = await resolveSession(cookies, cfg,
|
|
30
|
-
|
|
31
|
-
if (isApi(req)) {
|
|
32
|
-
const res = NextResponse.json({ error: "unauthorized", error_description: "Sign in first." }, { status: 401, headers: { "cache-control": "no-store" } });
|
|
33
|
-
for (const c of setCookies)
|
|
34
|
-
res.headers.append("set-cookie", c);
|
|
35
|
-
return res;
|
|
36
|
-
}
|
|
37
|
-
const to = new URL(`${cfg.basePath}/sign-in`, origin);
|
|
38
|
-
to.searchParams.set("redirect_url", req.nextUrl.pathname + req.nextUrl.search);
|
|
39
|
-
const res = NextResponse.redirect(to, 307);
|
|
39
|
+
const { session, setCookies } = await resolveSession(cookies, cfg, secure);
|
|
40
|
+
const withCookies = (res) => {
|
|
40
41
|
for (const c of setCookies)
|
|
41
42
|
res.headers.append("set-cookie", c);
|
|
43
|
+
if (setCookies.length)
|
|
44
|
+
res.headers.set("cache-control", PRIVATE);
|
|
42
45
|
return res;
|
|
46
|
+
};
|
|
47
|
+
if (!session && isProtected?.(req)) {
|
|
48
|
+
if (isApi(req))
|
|
49
|
+
return withCookies(NextResponse.json({ error: "unauthorized", error_description: "Sign in first." }, { status: 401, headers: { "cache-control": PRIVATE } }));
|
|
50
|
+
const to = new URL(`${cfg.basePath}/sign-in`, origin);
|
|
51
|
+
to.searchParams.set("redirect_url", req.nextUrl.pathname + req.nextUrl.search);
|
|
52
|
+
return withCookies(NextResponse.redirect(to, 307));
|
|
43
53
|
}
|
|
44
54
|
// The rest of this request (auth(), server components) sees the session as it is now.
|
|
45
55
|
const headers = new Headers(req.headers);
|
|
46
56
|
headers.delete(PATH_HEADER);
|
|
47
57
|
headers.set(PATH_HEADER, req.nextUrl.pathname + req.nextUrl.search);
|
|
58
|
+
headers.set(SECURE_HEADER, secure ? "1" : "0");
|
|
48
59
|
if (setCookies.length) {
|
|
49
60
|
const now = cookieHeader(applySetCookies(cookies, setCookies));
|
|
50
61
|
if (now)
|
|
@@ -52,10 +63,7 @@ export function accountsMiddleware(options = {}) {
|
|
|
52
63
|
else
|
|
53
64
|
headers.delete("cookie");
|
|
54
65
|
}
|
|
55
|
-
|
|
56
|
-
for (const c of setCookies)
|
|
57
|
-
res.headers.append("set-cookie", c);
|
|
58
|
-
return res;
|
|
66
|
+
return withCookies(NextResponse.next({ request: { headers } }));
|
|
59
67
|
};
|
|
60
68
|
}
|
|
61
69
|
//# sourceMappingURL=proxy.js.map
|
package/dist/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,uGAAuG;AACvG,+FAA+F;AAC/F,OAAO,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAI7D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACvH,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,KAAK,IAAI,GAAG;IACV,wEAAwE;IACxE,gBAAgB,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,KAAK,CAAC;CAC3D,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG;IACtC,eAAe,EAAE,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kGAAkG;IAClG,IAAI,EAAE,WAAW,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,6CAA6C;IAC7C,OAAO,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC5C,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG;IACvC,eAAe,EAAE,KAAK,CAAC;IACvB,MAAM,EAAE,IAAI,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,IAAI,CAAC;IACZ,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,gDAAgD;IAChD,OAAO,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;CAC/B,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAI7D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACvH,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,KAAK,IAAI,GAAG;IACV,wEAAwE;IACxE,gBAAgB,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,KAAK,CAAC;CAC3D,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG;IACtC,eAAe,EAAE,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kGAAkG;IAClG,IAAI,EAAE,WAAW,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,6CAA6C;IAC7C,OAAO,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC5C,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG;IACvC,eAAe,EAAE,KAAK,CAAC;IACvB,MAAM,EAAE,IAAI,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,IAAI,CAAC;IACZ,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,gDAAgD;IAChD,OAAO,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;CAC/B,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;AAqDlE;;;GAGG;AACH,eAAO,MAAM,IAAI,SAA2B,OAAO,CAAC,UAAU,CAAC;mBAC1C,OAAO,CAAC,kBAAkB,CAAC;CAC9C,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAE5E,4GAA4G;AAC5G,eAAO,MAAM,WAAW,aAAyB,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,KAAQ,OAAO,CAAC,WAAW,GAAG,IAAI,CAkB/G,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -5,16 +5,33 @@ import { redirect } from "next/navigation.js";
|
|
|
5
5
|
import { cache } from "react";
|
|
6
6
|
import { endpoints } from "@iaurelius/accounts/oidc";
|
|
7
7
|
import { configOf } from "./config.js";
|
|
8
|
-
import { PATH_HEADER } from "./proxy.js";
|
|
9
|
-
import { infoOf, readSession } from "./session.js";
|
|
8
|
+
import { PATH_HEADER, SECURE_HEADER } from "./proxy.js";
|
|
9
|
+
import { SECURE_SESSION_COOKIE, infoOf, readSession } from "./session.js";
|
|
10
10
|
export { accountsMiddleware, createRouteMatcher } from "./proxy.js";
|
|
11
|
+
/**
|
|
12
|
+
* Whether the app is on https, for a request the proxy did not see (it says so itself: x-accounts-secure). That
|
|
13
|
+
* decides which session cookie is ours: on https only the __Host- one, never the plain name a sibling subdomain can
|
|
14
|
+
* plant. So the plain one is read only when the app is on http for sure: its URL (ACCOUNTS_APP_URL) says http, or,
|
|
15
|
+
* without one, the request came over http (x-forwarded-proto, which Next and the hosting platforms set). When
|
|
16
|
+
* nothing says, https.
|
|
17
|
+
*/
|
|
18
|
+
function secureWithoutProxy(cookies, appUrl, forwardedProto) {
|
|
19
|
+
if ([...cookies.keys()].some((k) => k.startsWith(SECURE_SESSION_COOKIE)))
|
|
20
|
+
return true;
|
|
21
|
+
if (appUrl)
|
|
22
|
+
return !appUrl.startsWith("http://");
|
|
23
|
+
return forwardedProto?.split(",")[0]?.trim().toLowerCase() !== "http";
|
|
24
|
+
}
|
|
11
25
|
const readAuth = cache(async () => {
|
|
12
26
|
// Cookies first: that makes the route dynamic, so a build without settings does not try to prerender it.
|
|
13
27
|
const jar = await cookies();
|
|
14
28
|
const cfg = configOf();
|
|
15
29
|
const map = new Map(jar.getAll().map((c) => [c.name, c.value]));
|
|
16
|
-
const
|
|
17
|
-
const
|
|
30
|
+
const h = await headers();
|
|
31
|
+
const said = h.get(SECURE_HEADER);
|
|
32
|
+
const secure = said !== null ? said === "1" : secureWithoutProxy(map, cfg.appUrl, h.get("x-forwarded-proto"));
|
|
33
|
+
const s = await readSession(map, cfg, secure);
|
|
34
|
+
const current = h.get(PATH_HEADER) ?? "/";
|
|
18
35
|
const redirectToSignIn = (opts) => redirect(`${cfg.basePath}/sign-in?redirect_url=${encodeURIComponent(opts?.returnTo ?? current)}`);
|
|
19
36
|
const info = s && s.exp > Math.floor(Date.now() / 1000) ? infoOf(s) : null;
|
|
20
37
|
if (!s || !info) {
|
|
@@ -60,8 +77,11 @@ export const currentUser = cache(async (options = {}) => {
|
|
|
60
77
|
if (!res.ok)
|
|
61
78
|
return null;
|
|
62
79
|
const c = (await res.json());
|
|
80
|
+
// OIDC Core 5.3.2: an answer about someone else is not this person.
|
|
81
|
+
if (c.sub !== a.userId)
|
|
82
|
+
return null;
|
|
63
83
|
return {
|
|
64
|
-
id:
|
|
84
|
+
id: a.userId,
|
|
65
85
|
email: typeof c.email === "string" ? c.email : a.user.email,
|
|
66
86
|
emailVerified: c.email_verified === true,
|
|
67
87
|
name: typeof c.name === "string" && c.name ? c.name : null,
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,yCAAyC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAoB,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/session.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { type SessionUser } from "@iaurelius/accounts/oidc";
|
|
2
2
|
import type { AccountsConfig } from "./config.js";
|
|
3
3
|
import { type CookieOptions } from "./cookies.js";
|
|
4
|
+
/** The session cookie on http (localhost). */
|
|
4
5
|
export declare const SESSION_COOKIE = "__accounts_session";
|
|
6
|
+
/**
|
|
7
|
+
* On https it is a __Host- cookie: the browser only takes it from this very host, Secure, on Path=/ and without
|
|
8
|
+
* Domain, so a sibling subdomain (blog., staging.) cannot plant its own session here nor shadow this one.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SECURE_SESSION_COOKIE = "__Host-accounts_session";
|
|
11
|
+
export declare const sessionCookie: (secure: boolean) => "__Host-accounts_session" | "__accounts_session";
|
|
5
12
|
/** The person's profile as userinfo gave it: Accounts keeps it out of the ID token. */
|
|
6
13
|
export type Profile = {
|
|
7
14
|
email?: string;
|
|
@@ -25,21 +32,39 @@ export type SessionInfo = {
|
|
|
25
32
|
expiresAt: number;
|
|
26
33
|
};
|
|
27
34
|
export declare const cookieOptions: (cfg: AccountsConfig, secure: boolean, maxAge?: number) => CookieOptions;
|
|
28
|
-
export declare function readSession(cookies: Map<string, string>, cfg: AccountsConfig): Promise<Session | null>;
|
|
35
|
+
export declare function readSession(cookies: Map<string, string>, cfg: AccountsConfig, secure: boolean): Promise<Session | null>;
|
|
29
36
|
export declare function writeSession(s: Session, cookies: Map<string, string>, cfg: AccountsConfig, secure: boolean): Promise<string[]>;
|
|
30
37
|
export declare const clearSession: (cookies: Map<string, string>, cfg: AccountsConfig, secure: boolean) => string[];
|
|
38
|
+
/**
|
|
39
|
+
* Pauses of one session's refresh (by its refresh token) after a failure that is about that request only: no
|
|
40
|
+
* answer, a 5xx without Retry-After. Its next requests do not try again for a moment (a page load is many
|
|
41
|
+
* requests), and nobody else waits. At most `max` sessions are kept (the oldest pause goes first).
|
|
42
|
+
*/
|
|
43
|
+
export declare function sessionPauses(max?: number): {
|
|
44
|
+
/** Milliseconds left before this refresh token is tried again; 0: go ahead. */
|
|
45
|
+
waiting(rt: string): number;
|
|
46
|
+
failed(rt: string, e: unknown): void;
|
|
47
|
+
succeeded(rt: string): void;
|
|
48
|
+
readonly size: number;
|
|
49
|
+
};
|
|
50
|
+
export type SessionPauses = ReturnType<typeof sessionPauses>;
|
|
31
51
|
/** Who is signed in, from the session's ID token (verified when it was received, kept encrypted). */
|
|
32
52
|
export declare function infoOf(s: Session): SessionInfo | null;
|
|
33
53
|
export type Resolved = {
|
|
34
54
|
session: Session | null;
|
|
35
55
|
setCookies: string[];
|
|
36
56
|
};
|
|
37
|
-
/** The profile claims worth keeping, from userinfo. */
|
|
38
|
-
export declare function profileOf(cfg: AccountsConfig, accessToken: string): Promise<Profile | undefined>;
|
|
57
|
+
/** The profile claims worth keeping, from userinfo: only if it answers about `sub`, the person of the ID token. */
|
|
58
|
+
export declare function profileOf(cfg: AccountsConfig, accessToken: string, sub: string | undefined): Promise<Profile | undefined>;
|
|
39
59
|
/**
|
|
40
|
-
* The request's session, refreshed if its access token is about to expire.
|
|
41
|
-
*
|
|
42
|
-
*
|
|
60
|
+
* The request's session, refreshed if its access token is about to expire.
|
|
61
|
+
* - A refresh the application refuses for good (a 4xx with an OAuth error: `invalid_grant` when revoked, banned or
|
|
62
|
+
* over, `invalid_client`, `invalid_scope`, `invalid_target`…) signs the person out here.
|
|
63
|
+
* - One that only says "not now" (429, 5xx, no answer) keeps the cookie and its refresh token: this request has
|
|
64
|
+
* the session while its access token lasts. After a 429 (or a 503 with Retry-After) no refresh of the app is
|
|
65
|
+
* tried before the server's Retry-After; after anything else, only this session's waits a moment.
|
|
66
|
+
* - A refreshed ID token for someone else (another sub, issuer or audience) ends the session and revokes the
|
|
67
|
+
* refresh token that came with it.
|
|
43
68
|
*/
|
|
44
69
|
export declare function resolveSession(cookies: Map<string, string>, cfg: AccountsConfig, secure: boolean): Promise<Resolved>;
|
|
45
70
|
/** The request's cookies with the ones just set applied: what the rest of this request must see. */
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/dist/session.js
CHANGED
|
@@ -1,18 +1,65 @@
|
|
|
1
|
-
import { OAuthError, fetchUserInfo, readIdToken, refreshTokens, userFromClaims } from "@iaurelius/accounts/oidc";
|
|
1
|
+
import { OAuthError, appMustWait, fetchUserInfo, readIdToken, refreshTokens, revokeToken, sameIdentity, sessionEnded, userFromClaims } from "@iaurelius/accounts/oidc";
|
|
2
2
|
import { clearChunked, readChunked, seal, unseal, writeChunked } from "./cookies.js";
|
|
3
|
+
/** The session cookie on http (localhost). */
|
|
3
4
|
export const SESSION_COOKIE = "__accounts_session";
|
|
5
|
+
/**
|
|
6
|
+
* On https it is a __Host- cookie: the browser only takes it from this very host, Secure, on Path=/ and without
|
|
7
|
+
* Domain, so a sibling subdomain (blog., staging.) cannot plant its own session here nor shadow this one.
|
|
8
|
+
*/
|
|
9
|
+
export const SECURE_SESSION_COOKIE = "__Host-accounts_session";
|
|
10
|
+
export const sessionCookie = (secure) => (secure ? SECURE_SESSION_COOKIE : SESSION_COOKIE);
|
|
4
11
|
export const cookieOptions = (cfg, secure, maxAge) => ({ secure, maxAge, path: "/" });
|
|
5
|
-
export async function readSession(cookies, cfg) {
|
|
12
|
+
export async function readSession(cookies, cfg, secure) {
|
|
6
13
|
// The access token's expiry travels as `ax`: `exp` is the cookie's own (the JWE's expiration).
|
|
7
|
-
const s = await unseal(readChunked(
|
|
14
|
+
const s = await unseal(readChunked(sessionCookie(secure), cookies), cfg.cookieSecret, "session");
|
|
8
15
|
return s && s.typ === "session" && typeof s.at === "string" && typeof s.ax === "number" ? { at: s.at, rt: s.rt, it: s.it, exp: s.ax, u: s.u } : null;
|
|
9
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* On https, the session cookie of 0.2.0 and before (`__accounts_session`, whole or in chunks): it is no longer read
|
|
19
|
+
* there, and the browser would send it along with the new one for up to 30 days (a Cookie header twice as big).
|
|
20
|
+
* Dropped wherever it is seen. Only the app's own one can be dropped: one a sibling subdomain set with Domain stays.
|
|
21
|
+
*/
|
|
22
|
+
const legacyDrops = (cookies, cfg, secure) => (secure ? clearChunked(SESSION_COOKIE, cookies, cookieOptions(cfg, true)) : []);
|
|
10
23
|
export async function writeSession(s, cookies, cfg, secure) {
|
|
11
24
|
const maxAge = cfg.sessionMaxAgeDays * 86_400;
|
|
12
25
|
const value = await seal({ typ: "session", at: s.at, ...(s.rt && { rt: s.rt }), ...(s.it && { it: s.it }), ax: s.exp, ...(s.u && { u: s.u }) }, cfg.cookieSecret, "session", maxAge);
|
|
13
|
-
return writeChunked(
|
|
26
|
+
return [...writeChunked(sessionCookie(secure), value, cookies, cookieOptions(cfg, secure, maxAge)), ...legacyDrops(cookies, cfg, secure)];
|
|
27
|
+
}
|
|
28
|
+
export const clearSession = (cookies, cfg, secure) => [
|
|
29
|
+
...clearChunked(sessionCookie(secure), cookies, cookieOptions(cfg, secure)),
|
|
30
|
+
...legacyDrops(cookies, cfg, secure),
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Pauses of one session's refresh (by its refresh token) after a failure that is about that request only: no
|
|
34
|
+
* answer, a 5xx without Retry-After. Its next requests do not try again for a moment (a page load is many
|
|
35
|
+
* requests), and nobody else waits. At most `max` sessions are kept (the oldest pause goes first).
|
|
36
|
+
*/
|
|
37
|
+
export function sessionPauses(max = 1000) {
|
|
38
|
+
const until = new Map();
|
|
39
|
+
return {
|
|
40
|
+
/** Milliseconds left before this refresh token is tried again; 0: go ahead. */
|
|
41
|
+
waiting(rt) {
|
|
42
|
+
const left = (until.get(rt) ?? 0) - Date.now();
|
|
43
|
+
if (left > 0)
|
|
44
|
+
return left;
|
|
45
|
+
until.delete(rt);
|
|
46
|
+
return 0;
|
|
47
|
+
},
|
|
48
|
+
failed(rt, e) {
|
|
49
|
+
const asked = e instanceof OAuthError ? e.retryAfter : undefined;
|
|
50
|
+
until.delete(rt);
|
|
51
|
+
if (until.size >= max)
|
|
52
|
+
until.delete(until.keys().next().value);
|
|
53
|
+
until.set(rt, Date.now() + Math.min(300, Math.max(1, asked ?? 5)) * 1000);
|
|
54
|
+
},
|
|
55
|
+
succeeded(rt) {
|
|
56
|
+
until.delete(rt);
|
|
57
|
+
},
|
|
58
|
+
get size() {
|
|
59
|
+
return until.size;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
14
62
|
}
|
|
15
|
-
export const clearSession = (cookies, cfg, secure) => clearChunked(SESSION_COOKIE, cookies, cookieOptions(cfg, secure));
|
|
16
63
|
/** Who is signed in, from the session's ID token (verified when it was received, kept encrypted). */
|
|
17
64
|
export function infoOf(s) {
|
|
18
65
|
if (!s.it)
|
|
@@ -25,9 +72,9 @@ export function infoOf(s) {
|
|
|
25
72
|
return null;
|
|
26
73
|
}
|
|
27
74
|
}
|
|
28
|
-
/** The profile claims worth keeping, from userinfo. */
|
|
29
|
-
export async function profileOf(cfg, accessToken) {
|
|
30
|
-
const c = await fetchUserInfo({ issuer: cfg.issuer, accessToken, fetch: cfg.fetch });
|
|
75
|
+
/** The profile claims worth keeping, from userinfo: only if it answers about `sub`, the person of the ID token. */
|
|
76
|
+
export async function profileOf(cfg, accessToken, sub) {
|
|
77
|
+
const c = await fetchUserInfo({ issuer: cfg.issuer, accessToken, fetch: cfg.fetch, sub });
|
|
31
78
|
if (!c)
|
|
32
79
|
return undefined;
|
|
33
80
|
const p = {};
|
|
@@ -41,34 +88,68 @@ export async function profileOf(cfg, accessToken) {
|
|
|
41
88
|
p.picture = c.picture;
|
|
42
89
|
return p;
|
|
43
90
|
}
|
|
91
|
+
const subOf = (idToken) => {
|
|
92
|
+
try {
|
|
93
|
+
return idToken ? readIdToken(idToken).sub : undefined;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
44
99
|
/**
|
|
45
|
-
* The request's session, refreshed if its access token is about to expire.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
100
|
+
* The request's session, refreshed if its access token is about to expire.
|
|
101
|
+
* - A refresh the application refuses for good (a 4xx with an OAuth error: `invalid_grant` when revoked, banned or
|
|
102
|
+
* over, `invalid_client`, `invalid_scope`, `invalid_target`…) signs the person out here.
|
|
103
|
+
* - One that only says "not now" (429, 5xx, no answer) keeps the cookie and its refresh token: this request has
|
|
104
|
+
* the session while its access token lasts. After a 429 (or a 503 with Retry-After) no refresh of the app is
|
|
105
|
+
* tried before the server's Retry-After; after anything else, only this session's waits a moment.
|
|
106
|
+
* - A refreshed ID token for someone else (another sub, issuer or audience) ends the session and revokes the
|
|
107
|
+
* refresh token that came with it.
|
|
48
108
|
*/
|
|
49
109
|
export async function resolveSession(cookies, cfg, secure) {
|
|
50
|
-
const s = await readSession(cookies, cfg);
|
|
110
|
+
const s = await readSession(cookies, cfg, secure);
|
|
51
111
|
const now = Math.floor(Date.now() / 1000);
|
|
112
|
+
const legacy = legacyDrops(cookies, cfg, secure);
|
|
52
113
|
if (!s) {
|
|
53
114
|
// A cookie we cannot read (another secret, tampered, expired) is dropped.
|
|
54
|
-
const stale = readChunked(
|
|
55
|
-
return { session: null, setCookies: stale ? clearSession(cookies, cfg, secure) :
|
|
115
|
+
const stale = readChunked(sessionCookie(secure), cookies) !== undefined;
|
|
116
|
+
return { session: null, setCookies: stale ? clearSession(cookies, cfg, secure) : legacy };
|
|
56
117
|
}
|
|
57
118
|
if (s.exp - now > cfg.refreshBeforeSeconds)
|
|
58
|
-
return { session: s, setCookies:
|
|
119
|
+
return { session: s, setCookies: legacy };
|
|
120
|
+
const stillValid = s.exp > now ? s : null;
|
|
59
121
|
if (!s.rt)
|
|
60
|
-
return
|
|
122
|
+
return stillValid ? { session: s, setCookies: legacy } : { session: null, setCookies: clearSession(cookies, cfg, secure) };
|
|
123
|
+
// The application asked us to wait (or this session's refresh failed a moment ago): the token while it lasts,
|
|
124
|
+
// the cookie kept.
|
|
125
|
+
if (cfg.backoff?.waiting || cfg.pauses?.waiting(s.rt))
|
|
126
|
+
return { session: stillValid, setCookies: legacy };
|
|
127
|
+
const creds = { issuer: cfg.issuer, clientId: cfg.clientId, clientSecret: cfg.clientSecret, fetch: cfg.fetch };
|
|
128
|
+
let t;
|
|
61
129
|
try {
|
|
62
|
-
|
|
63
|
-
// The profile may have changed (a new name): read again, keeping the old one if userinfo does not answer.
|
|
64
|
-
const next = { at: t.accessToken, rt: t.refreshToken ?? s.rt, it: t.idToken ?? s.it, exp: t.expiresAt, u: (await profileOf(cfg, t.accessToken)) ?? s.u };
|
|
65
|
-
return { session: next, setCookies: await writeSession(next, cookies, cfg, secure) };
|
|
130
|
+
t = await refreshTokens(creds, { refreshToken: s.rt, resource: cfg.audience });
|
|
66
131
|
}
|
|
67
132
|
catch (e) {
|
|
68
|
-
if (e
|
|
133
|
+
if (sessionEnded(e))
|
|
69
134
|
return { session: null, setCookies: clearSession(cookies, cfg, secure) };
|
|
70
|
-
|
|
135
|
+
if (appMustWait(e))
|
|
136
|
+
cfg.backoff?.failed(e);
|
|
137
|
+
else
|
|
138
|
+
cfg.pauses?.failed(s.rt, e);
|
|
139
|
+
return { session: stillValid, setCookies: legacy };
|
|
140
|
+
}
|
|
141
|
+
cfg.backoff?.succeeded();
|
|
142
|
+
cfg.pauses?.succeeded(s.rt);
|
|
143
|
+
// OIDC Core 12.2: the refreshed ID token is the same person, for this app, from this application.
|
|
144
|
+
if (t.idToken && !sameIdentity(s.it, t.idToken, cfg)) {
|
|
145
|
+
if (t.refreshToken)
|
|
146
|
+
await revokeToken(creds, { token: t.refreshToken, hint: "refresh_token" });
|
|
147
|
+
return { session: null, setCookies: clearSession(cookies, cfg, secure) };
|
|
71
148
|
}
|
|
149
|
+
const it = t.idToken ?? s.it;
|
|
150
|
+
// The profile may have changed (a new name): read again, keeping the old one if userinfo does not answer.
|
|
151
|
+
const next = { at: t.accessToken, rt: t.refreshToken ?? s.rt, it, exp: t.expiresAt, u: (await profileOf(cfg, t.accessToken, subOf(it))) ?? s.u };
|
|
152
|
+
return { session: next, setCookies: await writeSession(next, cookies, cfg, secure) };
|
|
72
153
|
}
|
|
73
154
|
/** The request's cookies with the ones just set applied: what the rest of this request must see. */
|
|
74
155
|
export function applySetCookies(cookies, setCookies) {
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAoB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iaurelius/accounts-nextjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Accounts by iAurelius for Next.js (App Router): sign-in on the hosted page, sessions in an encrypted cookie, auth() on the server and <UserButton /> in your UI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"auth",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@iaurelius/accounts": "^0.
|
|
41
|
+
"@iaurelius/accounts": "^0.4.0",
|
|
42
42
|
"jose": "^6.2.12"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"next": "
|
|
46
|
-
"react": "
|
|
45
|
+
"next": "^15.5.24 || >=16.3.3",
|
|
46
|
+
"react": "~19.0.1 || ~19.1.2 || >=19.2.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/react": "19.3.0",
|