@idp.global/sdk 19.2.1 → 19.3.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/changelog.md +18 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_relyingparty/classes.errors.d.ts +9 -1
- package/dist_ts_relyingparty/classes.errors.js +5 -1
- package/dist_ts_relyingparty/classes.relyingpartyroutes.d.ts +62 -2
- package/dist_ts_relyingparty/classes.relyingpartyroutes.js +260 -12
- package/dist_ts_relyingparty/classes.relyingpartysessions.d.ts +108 -1
- package/dist_ts_relyingparty/classes.relyingpartysessions.js +508 -60
- package/dist_ts_relyingparty/classes.rpmodels.d.ts +65 -4
- package/dist_ts_relyingparty/classes.rpmodels.js +217 -5
- package/dist_ts_relyingparty/helpers.bearer.d.ts +48 -0
- package/dist_ts_relyingparty/helpers.bearer.js +199 -0
- package/dist_ts_relyingparty/index.d.ts +1 -0
- package/dist_ts_relyingparty/index.js +2 -1
- package/dist_ts_relyingparty/interfaces.d.ts +111 -1
- package/dist_ts_relyingparty/testing.d.ts +22 -0
- package/dist_ts_relyingparty/testing.js +42 -1
- package/package.json +8 -11
- package/readme.md +153 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_relyingparty/classes.errors.ts +13 -1
- package/ts_relyingparty/classes.relyingpartyroutes.ts +307 -14
- package/ts_relyingparty/classes.relyingpartysessions.ts +610 -61
- package/ts_relyingparty/classes.rpmodels.ts +124 -5
- package/ts_relyingparty/helpers.bearer.ts +260 -0
- package/ts_relyingparty/index.ts +1 -0
- package/ts_relyingparty/interfaces.ts +120 -1
- package/ts_relyingparty/testing.ts +60 -0
package/changelog.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-10-21 - 19.3.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- bearer hand-off mode for an application's own clients (relyingparty)
|
|
8
|
+
- `RelyingPartySessions` takes `bearer: { returnTargets, accessTokenMaxAgeSeconds? }`. Web, loopback (RFC 8252, any port), private-use scheme and popup clients start a PKCE S256 login at `bearer/login` and receive a single-use hand-off code. The code lives at most 60 seconds, is bound to the challenge, is stored only as a hash and is never a token. Redirect clients get it in the query; a popup page posts it to its opener at the exact registered origin, never `*`. Return targets are an exact allow-list: no prefix, no wildcard.
|
|
9
|
+
- `bearer/claim` trades the code and its verifier for the relying party's own short-lived access token and a rotating refresh token. `bearer/refresh`, `bearer/session` and `bearer/logout` use them; no bearer route reads or sets a cookie, and CORS is answered for popup origins only, without credentials.
|
|
10
|
+
- Each of these ends the session: a wrong verifier, a claimed code or a spent refresh token coming back, a code that expires unclaimed, or the end of the idp.global login. Sessions keep the cookie mode's hooks and `AuthorityObserver`.
|
|
11
|
+
- New `BearerHandoff` and `BearerToken` models, with their own collections, through `@lossless.org/client/nosqldb`. The testing entry adds `createBearerPkcePair()` and `readBearerDelivery()`.
|
|
12
|
+
|
|
13
|
+
### Fixes
|
|
14
|
+
|
|
15
|
+
- depend on `@push.rocks/smartjwt` 3, which no longer pulls `node-forge` (browser)
|
|
16
|
+
- smartjwt 2.7.0 depended on `@push.rocks/smartcrypto` 2, whose `node-forge` has the high advisory GHSA-86w9-cpqp-85rv with no patched release. smartjwt 3 uses smartcrypto 3, which has no runtime dependencies. The SDK uses only `decodeJwtPayloadWithoutVerification()` from `@push.rocks/smartjwt/web`, which 3.0.0 leaves unchanged.
|
|
17
|
+
- The lockfile resolves `brace-expansion` 2.1.7 and 5.0.12, clearing the high advisories on 2.1.2.
|
|
18
|
+
- require `@api.global/typedsocket` 8.10.1 or later on the 8 line, which no longer ships `node-forge` (deps)
|
|
19
|
+
- typedsocket 8.8–8.10.0 depended on `@push.rocks/smartcrypto` 2 and its `node-forge`; 8.10.1 (dist-tag `v8-lts`) uses smartcrypto 3. The wire major stays 8, so the deployed `@idp.global/app` still talks to it.
|
|
20
|
+
|
|
3
21
|
## 2026-10-13 - 19.2.1
|
|
4
22
|
|
|
5
23
|
### Fixes
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@idp.global/sdk',
|
|
6
|
-
version: '19.
|
|
6
|
+
version: '19.3.0',
|
|
7
7
|
description: 'Reusable browser and server SDK for idp.global authentication.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxpQkFBaUI7SUFDdkIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLGdFQUFnRTtDQUM5RSxDQUFBIn0=
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { TLoginCallbackStage } from './interfaces.js';
|
|
2
|
-
export type TRelyingPartyErrorCode = 'login_method_unavailable' | 'invalid_login_callback' | 'missing_login_intent' | 'invalid_or_replayed_login' | 'invalid_login_finalize'
|
|
2
|
+
export type TRelyingPartyErrorCode = 'login_method_unavailable' | 'invalid_login_callback' | 'missing_login_intent' | 'invalid_or_replayed_login' | 'invalid_login_finalize'
|
|
3
|
+
/** a bearer login start the relying party cannot accept: a missing or malformed parameter */
|
|
4
|
+
| 'invalid_bearer_request'
|
|
5
|
+
/** a bearer client named a return target that is not configured for its kind, exactly */
|
|
6
|
+
| 'return_target_not_allowed'
|
|
7
|
+
/** a hand-off code that is unknown, expired, already claimed, or claimed with the wrong verifier */
|
|
8
|
+
| 'invalid_bearer_handoff'
|
|
9
|
+
/** a refresh token that is unknown, rotated, expired, or of a session that is over */
|
|
10
|
+
| 'invalid_bearer_grant';
|
|
3
11
|
/** A request the login flow refuses; the code is safe to answer, the browser learns nothing more. */
|
|
4
12
|
export declare class RelyingPartyError extends Error {
|
|
5
13
|
readonly code: TRelyingPartyErrorCode;
|
|
@@ -4,6 +4,10 @@ const RELYING_PARTY_ERROR_STATUS = {
|
|
|
4
4
|
missing_login_intent: 400,
|
|
5
5
|
invalid_or_replayed_login: 400,
|
|
6
6
|
invalid_login_finalize: 400,
|
|
7
|
+
invalid_bearer_request: 400,
|
|
8
|
+
return_target_not_allowed: 400,
|
|
9
|
+
invalid_bearer_handoff: 400,
|
|
10
|
+
invalid_bearer_grant: 400,
|
|
7
11
|
};
|
|
8
12
|
/** A request the login flow refuses; the code is safe to answer, the browser learns nothing more. */
|
|
9
13
|
export class RelyingPartyError extends Error {
|
|
@@ -66,4 +70,4 @@ export class RelyingPartyDatabaseUnavailableError extends Error {
|
|
|
66
70
|
this.name = 'RelyingPartyDatabaseUnavailableError';
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5lcnJvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvY2xhc3Nlcy5lcnJvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBaUJBLE1BQU0sMEJBQTBCLEdBQXFEO0lBQ25GLHdCQUF3QixFQUFFLEdBQUc7SUFDN0Isc0JBQXNCLEVBQUUsR0FBRztJQUMzQixvQkFBb0IsRUFBRSxHQUFHO0lBQ3pCLHlCQUF5QixFQUFFLEdBQUc7SUFDOUIsc0JBQXNCLEVBQUUsR0FBRztJQUMzQixzQkFBc0IsRUFBRSxHQUFHO0lBQzNCLHlCQUF5QixFQUFFLEdBQUc7SUFDOUIsc0JBQXNCLEVBQUUsR0FBRztJQUMzQixvQkFBb0IsRUFBRSxHQUFHO0NBQzFCLENBQUM7QUFFRixxR0FBcUc7QUFDckcsTUFBTSxPQUFPLGlCQUFrQixTQUFRLEtBQUs7SUFHZCxJQUFJO0lBRmhCLE1BQU0sQ0FBUztJQUUvQixZQUE0QixJQUE0QjtRQUN0RCxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBRGMsSUFBSTtRQUU5QixJQUFJLENBQUMsSUFBSSxHQUFHLG1CQUFtQixDQUFDO1FBQ2hDLElBQUksQ0FBQyxNQUFNLEdBQUcsMEJBQTBCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakQsQ0FBQztDQUNGO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxPQUFPLG1CQUFvQixTQUFRLEtBQUs7SUFJMUIsSUFBSTtJQUNKLE1BQU07SUFKUixRQUFRLENBQVU7SUFFbEMsWUFDa0IsSUFBWSxFQUNaLE1BQWMsRUFDOUIsVUFBVSxHQUEwQixFQUFFO1FBRXRDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFKSSxJQUFJO3NCQUNKLE1BQU07UUFJdEIsSUFBSSxDQUFDLElBQUksR0FBRyxxQkFBcUIsQ0FBQztRQUNsQyxJQUFJLFVBQVUsQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFFRCxxR0FBcUc7QUFDckcsTUFBTSxPQUFPLGtCQUFtQixTQUFRLEtBQUs7SUFFekIsS0FBSztJQUR2QixZQUNrQixLQUEwQixFQUMxQyxRQUFpQjtRQUVqQixLQUFLLENBQUMsMkNBQTJDLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztxQkFIeEQsS0FBSztRQUlyQixJQUFJLENBQUMsSUFBSSxHQUFHLG9CQUFvQixDQUFDO0lBQ25DLENBQUM7Q0FDRjtBQVFELE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxLQUFLO0lBR2hCLElBQUk7SUFGaEIsTUFBTSxDQUFTO0lBRS9CLFlBQTRCLElBQThCLEVBQUUsUUFBa0I7UUFDNUUsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO29CQURQLElBQUk7UUFFOUIsSUFBSSxDQUFDLElBQUksR0FBRyxxQkFBcUIsQ0FBQztRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksS0FBSywwQkFBMEIsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDaEUsQ0FBQztDQUNGO0FBRUQsZ0ZBQWdGO0FBQ2hGLE1BQU0sT0FBTyxvQ0FBcUMsU0FBUSxLQUFLO0lBQzdELFlBQVksUUFBa0I7UUFDNUIsS0FBSyxDQUFDLGlFQUFpRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDOUYsSUFBSSxDQUFDLElBQUksR0FBRyxzQ0FBc0MsQ0FBQztJQUNyRCxDQUFDO0NBQ0YifQ==
|
|
@@ -40,7 +40,7 @@ export interface IRelyingPartyRoutesOptions<TPrincipal extends object | undefine
|
|
|
40
40
|
session: IRelyingPartySession;
|
|
41
41
|
endedLiveSession: boolean;
|
|
42
42
|
}): Promise<void>;
|
|
43
|
-
/** the largest logout body read, in bytes; a longer one is cancelled as soon as it passes the limit */
|
|
43
|
+
/** the largest logout, claim or refresh body read, in bytes; a longer one is cancelled as soon as it passes the limit */
|
|
44
44
|
maxBodyBytes?: number;
|
|
45
45
|
/**
|
|
46
46
|
* diagnostics of a failed start or callback; the default writes one JSON
|
|
@@ -49,6 +49,10 @@ export interface IRelyingPartyRoutesOptions<TPrincipal extends object | undefine
|
|
|
49
49
|
*/
|
|
50
50
|
onRouteEvent?(eventArg: {
|
|
51
51
|
event: 'auth_login_start_failed' | 'auth_callback_failed' | 'auth_callback_declined' | 'auth_callback_refused'
|
|
52
|
+
/** a bearer login start named something the relying party does not accept; `code` says what */
|
|
53
|
+
| 'auth_bearer_start_refused'
|
|
54
|
+
/** a bearer claim, refresh, session or logout failed for a reason other than its credential */
|
|
55
|
+
| 'auth_bearer_failed'
|
|
52
56
|
/** an application hook of the routes threw; the step it belonged to is complete */
|
|
53
57
|
| 'hook_failed';
|
|
54
58
|
hook?: 'onLogout';
|
|
@@ -72,6 +76,24 @@ export interface IRelyingPartyRoutesOptions<TPrincipal extends object | undefine
|
|
|
72
76
|
* - `POST logout` ends the session; it needs this origin and the CSRF token,
|
|
73
77
|
* and `onLogout` runs before it answers
|
|
74
78
|
*
|
|
79
|
+
* With bearer mode on (`RelyingPartySessions` `bearer`), the routes of the
|
|
80
|
+
* application's own clients join them; none of them reads or sets a cookie:
|
|
81
|
+
*
|
|
82
|
+
* - `GET bearer/login?client_kind=…&return_target=…&code_challenge=…&code_challenge_method=S256[&state=…]`
|
|
83
|
+
* redirects to the provider
|
|
84
|
+
* - `GET callback` answers a bearer login's callback by delivering the
|
|
85
|
+
* hand-off code — or the `error` — to the return target: a redirect with
|
|
86
|
+
* `code` (or `error`) and `state` in the query, or for a popup a page that
|
|
87
|
+
* posts them to its opener at the registered origin
|
|
88
|
+
* - `POST bearer/claim` `{ code, codeVerifier }` and `POST bearer/refresh`
|
|
89
|
+
* `{ refreshToken }` answer the tokens
|
|
90
|
+
* - `GET bearer/session` answers the session of `Authorization: Bearer <access token>`
|
|
91
|
+
* - `POST bearer/logout` ends the session of the `Authorization` access token
|
|
92
|
+
* or of the body's `{ refreshToken }`
|
|
93
|
+
*
|
|
94
|
+
* The four API routes answer CORS requests from the popup return targets'
|
|
95
|
+
* origins, exactly, and no others; they never allow credentials.
|
|
96
|
+
*
|
|
75
97
|
* `handle()` answers `null` for every other request, so the application
|
|
76
98
|
* chains its own routes (a local password login) around it. Cookies are only
|
|
77
99
|
* ever set here: a `/typedrequest` answer cannot carry `Set-Cookie`.
|
|
@@ -79,13 +101,18 @@ export interface IRelyingPartyRoutesOptions<TPrincipal extends object | undefine
|
|
|
79
101
|
export declare class RelyingPartyRoutes<TPrincipal extends object | undefined = undefined> {
|
|
80
102
|
#private;
|
|
81
103
|
constructor(optionsArg: IRelyingPartyRoutesOptions<TPrincipal>);
|
|
82
|
-
/** The paths the routes answer, for registering them one by one. */
|
|
104
|
+
/** The paths the routes answer, for registering them one by one; the `bearer…` paths answer only in bearer mode. */
|
|
83
105
|
get paths(): {
|
|
84
106
|
login: string;
|
|
85
107
|
callback: string;
|
|
86
108
|
finalize: string;
|
|
87
109
|
session: string;
|
|
88
110
|
logout: string;
|
|
111
|
+
bearerLogin: string;
|
|
112
|
+
bearerClaim: string;
|
|
113
|
+
bearerRefresh: string;
|
|
114
|
+
bearerSession: string;
|
|
115
|
+
bearerLogout: string;
|
|
89
116
|
};
|
|
90
117
|
readonly handle: (contextArg: IRelyingPartyHttpContext) => Promise<Response | null>;
|
|
91
118
|
private login;
|
|
@@ -96,6 +123,39 @@ export declare class RelyingPartyRoutes<TPrincipal extends object | undefined =
|
|
|
96
123
|
*/
|
|
97
124
|
private refusalLocationOf;
|
|
98
125
|
private callback;
|
|
126
|
+
/** A callback that failed for a reason other than a refusal: reported when it is the relying party's fault. */
|
|
127
|
+
private callbackFailure;
|
|
128
|
+
private callbackFailureStatus;
|
|
129
|
+
private handleBearer;
|
|
130
|
+
/**
|
|
131
|
+
* The CORS answer for a request from a popup return target's origin, which
|
|
132
|
+
* is matched exactly; `null` for every other origin, which gets none.
|
|
133
|
+
* Credentials are never allowed: bearer mode carries no cookie.
|
|
134
|
+
*/
|
|
135
|
+
private bearerCorsHeaders;
|
|
136
|
+
private bearerLogin;
|
|
137
|
+
/**
|
|
138
|
+
* The callback of a bearer login, delivered to its return target whatever
|
|
139
|
+
* the outcome: the hand-off code, `access_denied` when the provider came
|
|
140
|
+
* back without one, the code of an application refusal (its `location` is
|
|
141
|
+
* a page of the cookie flow and not followed), or `authentication_failed`.
|
|
142
|
+
*/
|
|
143
|
+
private bearerCallback;
|
|
144
|
+
/**
|
|
145
|
+
* A redirect to the return target with the outcome in its query, or for a
|
|
146
|
+
* popup the page that posts it to the opener. Neither sends a referrer, and
|
|
147
|
+
* the popup page runs its one nonce script and nothing else.
|
|
148
|
+
*/
|
|
149
|
+
private deliverBearerOutcome;
|
|
150
|
+
/**
|
|
151
|
+
* Runs one bearer API step and answers its JSON. A refused credential
|
|
152
|
+
* answers its code with 400; an unreachable provider answers
|
|
153
|
+
* `authority_unavailable` with 503 and spends nothing; any other failure is
|
|
154
|
+
* reported and answers `authentication_unavailable`.
|
|
155
|
+
*/
|
|
156
|
+
private bearerApi;
|
|
157
|
+
private bearerTokenAnswer;
|
|
158
|
+
private bearerSessionAnswer;
|
|
99
159
|
private logout;
|
|
100
160
|
private sessionAnswer;
|
|
101
161
|
/**
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
|
-
import { LoginCallbackError, RelyingPartyError, RelyingPartyRefusal } from './classes.errors.js';
|
|
2
|
+
import { AuthorityTokenError, LoginCallbackError, RelyingPartyError, RelyingPartyRefusal } from './classes.errors.js';
|
|
3
|
+
import { bearerDeliveryLocation, bearerPopupContentSecurityPolicy, bearerPopupPage, parseBearerAuthorization, } from './helpers.bearer.js';
|
|
4
|
+
import { randomToken } from './helpers.crypto.js';
|
|
3
5
|
import { sanitizeReturnPath } from './helpers.returnpath.js';
|
|
4
6
|
const DEFAULT_MAX_BODY_BYTES = 16 * 1024;
|
|
5
7
|
/** What the provider names in a callback it did not issue a code for. */
|
|
@@ -17,6 +19,13 @@ const jsonResponse = (bodyArg, statusArg, headersArg) => {
|
|
|
17
19
|
return new Response(JSON.stringify(bodyArg), { status: statusArg, headers });
|
|
18
20
|
};
|
|
19
21
|
const redirect = (locationArg, headersArg) => new Response(null, { status: 302, headers: noStoreHeaders({ Location: locationArg, ...headersArg }) });
|
|
22
|
+
/** A JSON body's field, or `undefined` for anything that is not an object holding it. */
|
|
23
|
+
const bodyField = (bodyArg, nameArg) => bodyArg && typeof bodyArg === 'object' && Object.hasOwn(bodyArg, nameArg) ? Reflect.get(bodyArg, nameArg) : undefined;
|
|
24
|
+
/** A query parameter given once; `null` when it is repeated, so it never passes as given. */
|
|
25
|
+
const singleParam = (paramsArg, nameArg) => {
|
|
26
|
+
const all = paramsArg.getAll(nameArg);
|
|
27
|
+
return all.length === 0 ? undefined : all.length === 1 ? all[0] : null;
|
|
28
|
+
};
|
|
20
29
|
/**
|
|
21
30
|
* The HTTP steps of a relying-party login, all under the sessions' login path
|
|
22
31
|
* prefix (default `/auth/`):
|
|
@@ -30,6 +39,24 @@ const redirect = (locationArg, headersArg) => new Response(null, { status: 302,
|
|
|
30
39
|
* - `POST logout` ends the session; it needs this origin and the CSRF token,
|
|
31
40
|
* and `onLogout` runs before it answers
|
|
32
41
|
*
|
|
42
|
+
* With bearer mode on (`RelyingPartySessions` `bearer`), the routes of the
|
|
43
|
+
* application's own clients join them; none of them reads or sets a cookie:
|
|
44
|
+
*
|
|
45
|
+
* - `GET bearer/login?client_kind=…&return_target=…&code_challenge=…&code_challenge_method=S256[&state=…]`
|
|
46
|
+
* redirects to the provider
|
|
47
|
+
* - `GET callback` answers a bearer login's callback by delivering the
|
|
48
|
+
* hand-off code — or the `error` — to the return target: a redirect with
|
|
49
|
+
* `code` (or `error`) and `state` in the query, or for a popup a page that
|
|
50
|
+
* posts them to its opener at the registered origin
|
|
51
|
+
* - `POST bearer/claim` `{ code, codeVerifier }` and `POST bearer/refresh`
|
|
52
|
+
* `{ refreshToken }` answer the tokens
|
|
53
|
+
* - `GET bearer/session` answers the session of `Authorization: Bearer <access token>`
|
|
54
|
+
* - `POST bearer/logout` ends the session of the `Authorization` access token
|
|
55
|
+
* or of the body's `{ refreshToken }`
|
|
56
|
+
*
|
|
57
|
+
* The four API routes answer CORS requests from the popup return targets'
|
|
58
|
+
* origins, exactly, and no others; they never allow credentials.
|
|
59
|
+
*
|
|
33
60
|
* `handle()` answers `null` for every other request, so the application
|
|
34
61
|
* chains its own routes (a local password login) around it. Cookies are only
|
|
35
62
|
* ever set here: a `/typedrequest` answer cannot carry `Set-Cookie`.
|
|
@@ -43,7 +70,7 @@ export class RelyingPartyRoutes {
|
|
|
43
70
|
this.#options = optionsArg;
|
|
44
71
|
this.#maxBodyBytes = optionsArg.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
|
|
45
72
|
}
|
|
46
|
-
/** The paths the routes answer, for registering them one by one. */
|
|
73
|
+
/** The paths the routes answer, for registering them one by one; the `bearer…` paths answer only in bearer mode. */
|
|
47
74
|
get paths() {
|
|
48
75
|
const prefix = this.#sessions.loginPathPrefix;
|
|
49
76
|
return {
|
|
@@ -52,6 +79,11 @@ export class RelyingPartyRoutes {
|
|
|
52
79
|
finalize: prefix + 'finalize',
|
|
53
80
|
session: prefix + 'session',
|
|
54
81
|
logout: prefix + 'logout',
|
|
82
|
+
bearerLogin: prefix + 'bearer/login',
|
|
83
|
+
bearerClaim: prefix + 'bearer/claim',
|
|
84
|
+
bearerRefresh: prefix + 'bearer/refresh',
|
|
85
|
+
bearerSession: prefix + 'bearer/session',
|
|
86
|
+
bearerLogout: prefix + 'bearer/logout',
|
|
55
87
|
};
|
|
56
88
|
}
|
|
57
89
|
handle = async (contextArg) => {
|
|
@@ -59,6 +91,12 @@ export class RelyingPartyRoutes {
|
|
|
59
91
|
const path = contextArg.url.pathname;
|
|
60
92
|
const method = contextArg.method.toUpperCase();
|
|
61
93
|
const providerLogin = this.#sessions.providerLoginEnabled;
|
|
94
|
+
if (this.#sessions.bearerLoginEnabled) {
|
|
95
|
+
const bearerResponse = await this.handleBearer(contextArg, path, method);
|
|
96
|
+
if (bearerResponse) {
|
|
97
|
+
return bearerResponse;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
62
100
|
if (path === paths.login && method === 'GET' && providerLogin) {
|
|
63
101
|
return this.login(contextArg);
|
|
64
102
|
}
|
|
@@ -110,6 +148,19 @@ export class RelyingPartyRoutes {
|
|
|
110
148
|
async callback(contextArg) {
|
|
111
149
|
// the callback is read from the public origin, never from a forwarded host
|
|
112
150
|
const callbackUrl = new URL(contextArg.url.pathname + contextArg.url.search, this.#sessions.publicOrigin);
|
|
151
|
+
if (this.#sessions.bearerLoginEnabled) {
|
|
152
|
+
let delivery;
|
|
153
|
+
try {
|
|
154
|
+
delivery = await this.#sessions.bearerDeliveryOf(callbackUrl);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
// unknown whose callback this is: answered as the cookie path answers a failure
|
|
158
|
+
return this.callbackFailure(error, { 'Set-Cookie': this.#sessions.clearIntentCookie() });
|
|
159
|
+
}
|
|
160
|
+
if (delivery) {
|
|
161
|
+
return this.bearerCallback(callbackUrl, delivery);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
113
164
|
const cookieHeader = contextArg.headers.get('cookie');
|
|
114
165
|
const providerError = callbackUrl.searchParams.get('error');
|
|
115
166
|
if (providerError) {
|
|
@@ -137,18 +188,215 @@ export class RelyingPartyRoutes {
|
|
|
137
188
|
}
|
|
138
189
|
return jsonResponse({ error: 'authentication_failed' }, error.status, clearIntent);
|
|
139
190
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
191
|
+
return this.callbackFailure(error, clearIntent);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/** A callback that failed for a reason other than a refusal: reported when it is the relying party's fault. */
|
|
195
|
+
callbackFailure(errorArg, headersArg) {
|
|
196
|
+
const status = this.callbackFailureStatus(errorArg);
|
|
197
|
+
return jsonResponse({ error: 'authentication_failed' }, status, headersArg);
|
|
198
|
+
}
|
|
199
|
+
callbackFailureStatus(errorArg) {
|
|
200
|
+
const status = errorArg instanceof RelyingPartyError ? errorArg.status : 502;
|
|
201
|
+
if (status >= 500) {
|
|
202
|
+
this.emit({
|
|
203
|
+
event: 'auth_callback_failed',
|
|
204
|
+
correlationId: plugins.crypto.randomUUID(),
|
|
205
|
+
stage: errorArg instanceof LoginCallbackError ? errorArg.stage : 'unclassified',
|
|
206
|
+
message: errorArg instanceof Error ? errorArg.message : String(errorArg),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return status;
|
|
210
|
+
}
|
|
211
|
+
// ==========================================================================
|
|
212
|
+
// bearer hand-off
|
|
213
|
+
// ==========================================================================
|
|
214
|
+
async handleBearer(contextArg, pathArg, methodArg) {
|
|
215
|
+
const paths = this.paths;
|
|
216
|
+
if (pathArg === paths.bearerLogin) {
|
|
217
|
+
return methodArg === 'GET' ? this.bearerLogin(contextArg) : null;
|
|
218
|
+
}
|
|
219
|
+
const route = ['bearerClaim', 'bearerRefresh', 'bearerSession', 'bearerLogout']
|
|
220
|
+
.find((routeArg) => paths[routeArg] === pathArg);
|
|
221
|
+
if (!route) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
const corsHeaders = this.bearerCorsHeaders(contextArg);
|
|
225
|
+
if (methodArg === 'OPTIONS') {
|
|
226
|
+
if (!corsHeaders) {
|
|
227
|
+
return jsonResponse({ error: 'forbidden' }, 403, { Vary: 'Origin' });
|
|
228
|
+
}
|
|
229
|
+
return new Response(null, {
|
|
230
|
+
status: 204,
|
|
231
|
+
headers: noStoreHeaders({
|
|
232
|
+
...corsHeaders,
|
|
233
|
+
'Access-Control-Allow-Methods': 'GET, POST',
|
|
234
|
+
'Access-Control-Allow-Headers': 'authorization, content-type',
|
|
235
|
+
'Access-Control-Max-Age': '600',
|
|
236
|
+
}),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
const headers = corsHeaders ?? { Vary: 'Origin' };
|
|
240
|
+
if (route === 'bearerSession') {
|
|
241
|
+
return methodArg === 'GET' ? this.bearerApi(headers, () => this.bearerSessionAnswer(contextArg)) : null;
|
|
242
|
+
}
|
|
243
|
+
if (methodArg !== 'POST') {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
if (route === 'bearerClaim') {
|
|
247
|
+
return this.bearerApi(headers, async () => {
|
|
248
|
+
const body = await this.readJsonBody(contextArg);
|
|
249
|
+
return this.bearerTokenAnswer(await this.#sessions.claimBearerHandoff(bodyField(body, 'code'), bodyField(body, 'codeVerifier')));
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (route === 'bearerRefresh') {
|
|
253
|
+
return this.bearerApi(headers, async () => {
|
|
254
|
+
const body = await this.readJsonBody(contextArg);
|
|
255
|
+
return this.bearerTokenAnswer(await this.#sessions.refreshBearerTokens(bodyField(body, 'refreshToken')));
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return this.bearerApi(headers, async () => {
|
|
259
|
+
const accessToken = parseBearerAuthorization(contextArg.headers.get('authorization'));
|
|
260
|
+
let endedLiveSession = accessToken ? await this.#sessions.endBearerSession(accessToken) : false;
|
|
261
|
+
if (!endedLiveSession) {
|
|
262
|
+
const refreshToken = bodyField(await this.readJsonBody(contextArg), 'refreshToken');
|
|
263
|
+
endedLiveSession = refreshToken !== undefined ? await this.#sessions.endBearerSession(refreshToken) : false;
|
|
264
|
+
}
|
|
265
|
+
return { endedLiveSession };
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* The CORS answer for a request from a popup return target's origin, which
|
|
270
|
+
* is matched exactly; `null` for every other origin, which gets none.
|
|
271
|
+
* Credentials are never allowed: bearer mode carries no cookie.
|
|
272
|
+
*/
|
|
273
|
+
bearerCorsHeaders(contextArg) {
|
|
274
|
+
const origin = contextArg.headers.get('origin');
|
|
275
|
+
const popupOrigins = this.#sessions.bearerReturnTargets?.popup ?? [];
|
|
276
|
+
if (origin === null || !popupOrigins.includes(origin)) {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
return { 'Access-Control-Allow-Origin': origin, Vary: 'Origin' };
|
|
280
|
+
}
|
|
281
|
+
async bearerLogin(contextArg) {
|
|
282
|
+
const query = contextArg.url.searchParams;
|
|
283
|
+
const state = singleParam(query, 'state');
|
|
284
|
+
// every field is checked by startBearerLogin, which takes them as untrusted input
|
|
285
|
+
const request = {
|
|
286
|
+
clientKind: singleParam(query, 'client_kind'),
|
|
287
|
+
returnTarget: singleParam(query, 'return_target'),
|
|
288
|
+
codeChallenge: singleParam(query, 'code_challenge'),
|
|
289
|
+
codeChallengeMethod: singleParam(query, 'code_challenge_method'),
|
|
290
|
+
...(state !== undefined ? { state } : {}),
|
|
291
|
+
};
|
|
292
|
+
try {
|
|
293
|
+
const start = await this.#sessions.startBearerLogin(request);
|
|
294
|
+
return redirect(start.authorizationUrl.href, { 'Referrer-Policy': 'no-referrer' });
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
if (error instanceof RelyingPartyError && error.status < 500) {
|
|
298
|
+
this.emit({ event: 'auth_bearer_start_refused', code: error.code });
|
|
299
|
+
return jsonResponse({ error: error.code }, error.status);
|
|
300
|
+
}
|
|
301
|
+
this.emit({ event: 'auth_login_start_failed', message: error instanceof Error ? error.message : String(error) });
|
|
302
|
+
return jsonResponse({ error: 'authentication_unavailable' }, 503);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* The callback of a bearer login, delivered to its return target whatever
|
|
307
|
+
* the outcome: the hand-off code, `access_denied` when the provider came
|
|
308
|
+
* back without one, the code of an application refusal (its `location` is
|
|
309
|
+
* a page of the cookie flow and not followed), or `authentication_failed`.
|
|
310
|
+
*/
|
|
311
|
+
async bearerCallback(callbackUrlArg, deliveryArg) {
|
|
312
|
+
const providerError = callbackUrlArg.searchParams.get('error');
|
|
313
|
+
if (providerError) {
|
|
314
|
+
await this.#sessions.abandonBearerLogin(callbackUrlArg);
|
|
315
|
+
this.emit({ event: 'auth_callback_declined', code: providerError.slice(0, MAX_PROVIDER_ERROR_CODE_LENGTH) });
|
|
316
|
+
return this.deliverBearerOutcome(deliveryArg, { error: 'access_denied' });
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
const handoff = await this.#sessions.completeBearerLogin(callbackUrlArg);
|
|
320
|
+
return this.deliverBearerOutcome(handoff.delivery, { code: handoff.code });
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
if (error instanceof RelyingPartyRefusal) {
|
|
324
|
+
this.emit({ event: 'auth_callback_refused', code: error.code });
|
|
325
|
+
return this.deliverBearerOutcome(deliveryArg, { error: error.code });
|
|
148
326
|
}
|
|
149
|
-
|
|
327
|
+
this.callbackFailureStatus(error);
|
|
328
|
+
return this.deliverBearerOutcome(deliveryArg, { error: 'authentication_failed' });
|
|
150
329
|
}
|
|
151
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* A redirect to the return target with the outcome in its query, or for a
|
|
333
|
+
* popup the page that posts it to the opener. Neither sends a referrer, and
|
|
334
|
+
* the popup page runs its one nonce script and nothing else.
|
|
335
|
+
*/
|
|
336
|
+
deliverBearerOutcome(deliveryArg, outcomeArg) {
|
|
337
|
+
if (deliveryArg.clientKind !== 'popup') {
|
|
338
|
+
return redirect(bearerDeliveryLocation(deliveryArg, outcomeArg, this.#sessions.publicOrigin), { 'Referrer-Policy': 'no-referrer' });
|
|
339
|
+
}
|
|
340
|
+
const nonce = randomToken(16);
|
|
341
|
+
return new Response(bearerPopupPage(deliveryArg, outcomeArg, nonce), {
|
|
342
|
+
status: 200,
|
|
343
|
+
headers: noStoreHeaders({
|
|
344
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
345
|
+
'Content-Security-Policy': bearerPopupContentSecurityPolicy(nonce),
|
|
346
|
+
'X-Content-Type-Options': 'nosniff',
|
|
347
|
+
'Referrer-Policy': 'no-referrer',
|
|
348
|
+
}),
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Runs one bearer API step and answers its JSON. A refused credential
|
|
353
|
+
* answers its code with 400; an unreachable provider answers
|
|
354
|
+
* `authority_unavailable` with 503 and spends nothing; any other failure is
|
|
355
|
+
* reported and answers `authentication_unavailable`.
|
|
356
|
+
*/
|
|
357
|
+
async bearerApi(headersArg, stepArg) {
|
|
358
|
+
try {
|
|
359
|
+
return jsonResponse(await stepArg(), 200, headersArg);
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
if (error instanceof RelyingPartyError && error.status < 500) {
|
|
363
|
+
return jsonResponse({ error: error.code }, error.status, headersArg);
|
|
364
|
+
}
|
|
365
|
+
if (error instanceof AuthorityTokenError && error.code === 'authority_unavailable') {
|
|
366
|
+
return jsonResponse({ error: error.code }, error.status, headersArg);
|
|
367
|
+
}
|
|
368
|
+
this.emit({
|
|
369
|
+
event: 'auth_bearer_failed',
|
|
370
|
+
correlationId: plugins.crypto.randomUUID(),
|
|
371
|
+
message: error instanceof Error ? error.message : String(error),
|
|
372
|
+
});
|
|
373
|
+
return jsonResponse({ error: 'authentication_unavailable' }, 503, headersArg);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
bearerTokenAnswer(tokensArg) {
|
|
377
|
+
return {
|
|
378
|
+
tokenType: 'Bearer',
|
|
379
|
+
accessToken: tokensArg.accessToken,
|
|
380
|
+
accessTokenExpiresAt: tokensArg.accessTokenExpiresAt,
|
|
381
|
+
// counted on the relying party's clock, so a client with another clock can use it
|
|
382
|
+
expiresIn: Math.max(0, Math.floor((tokensArg.accessTokenExpiresAt - tokensArg.issuedAt) / 1_000)),
|
|
383
|
+
refreshToken: tokensArg.refreshToken,
|
|
384
|
+
refreshTokenExpiresAt: tokensArg.refreshTokenExpiresAt,
|
|
385
|
+
session: {
|
|
386
|
+
sessionId: tokensArg.session.id,
|
|
387
|
+
principalId: tokensArg.session.principalId,
|
|
388
|
+
expiresAt: tokensArg.session.expiresAt,
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
async bearerSessionAnswer(contextArg) {
|
|
393
|
+
const live = await this.#sessions.resolveBearerSession(contextArg.headers.get('authorization'));
|
|
394
|
+
return {
|
|
395
|
+
session: live
|
|
396
|
+
? { sessionId: live.session.id, principalId: live.session.principalId, expiresAt: live.session.expiresAt }
|
|
397
|
+
: null,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
152
400
|
async logout(contextArg) {
|
|
153
401
|
if (contextArg.headers.get('origin') !== this.#sessions.publicOrigin) {
|
|
154
402
|
return jsonResponse({ error: 'forbidden' }, 403);
|
|
@@ -263,4 +511,4 @@ export class RelyingPartyRoutes {
|
|
|
263
511
|
}
|
|
264
512
|
}
|
|
265
513
|
}
|
|
266
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5yZWx5aW5ncGFydHlyb3V0ZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvY2xhc3Nlcy5yZWx5aW5ncGFydHlyb3V0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFakcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFpRTdELE1BQU0sc0JBQXNCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUN6Qyx5RUFBeUU7QUFDekUsTUFBTSw4QkFBOEIsR0FBRyxFQUFFLENBQUM7QUFFMUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxVQUFtQyxFQUFXLEVBQUU7SUFDdEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDeEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDekMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDbEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUMzRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDLENBQUM7QUFFRixNQUFNLFlBQVksR0FBRyxDQUFDLE9BQWUsRUFBRSxTQUFpQixFQUFFLFVBQW1DLEVBQVksRUFBRTtJQUN6RyxNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDM0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztJQUMvRCxPQUFPLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVB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
|
|
514
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5yZWx5aW5ncGFydHlyb3V0ZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvY2xhc3Nlcy5yZWx5aW5ncGFydHlyb3V0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFdEgsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixnQ0FBZ0MsRUFDaEMsZUFBZSxFQUNmLHdCQUF3QixHQUV6QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQTJFN0QsTUFBTSxzQkFBc0IsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ3pDLHlFQUF5RTtBQUN6RSxNQUFNLDhCQUE4QixHQUFHLEVBQUUsQ0FBQztBQUUxQyxNQUFNLGNBQWMsR0FBRyxDQUFDLFVBQW1DLEVBQVcsRUFBRTtJQUN0RSxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN4QyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN6QyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQzNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMsQ0FBQztBQUVGLE1BQU0sWUFBWSxHQUFHLENBQUMsT0FBZSxFQUFFLFNBQWlCLEVBQUUsVUFBbUMsRUFBWSxFQUFFO0lBQ3pHLE1BQU0sT0FBTyxHQUFH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
|