@atlasauth/backend 0.7.3 → 0.9.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 +29 -0
- package/README.md +175 -1
- package/dist/client/activity.d.ts +5 -0
- package/dist/client/activity.js.map +1 -1
- package/dist/client/branding.d.ts +58 -0
- package/dist/client/branding.js.map +1 -1
- package/dist/client/domains.d.ts +13 -0
- package/dist/client/domains.js.map +1 -1
- package/dist/client/email-templates.d.ts +1 -1
- package/dist/client/email-templates.js.map +1 -1
- package/dist/client/index.d.ts +55 -2
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/instance.d.ts +201 -0
- package/dist/client/instance.js +38 -0
- package/dist/client/instance.js.map +1 -1
- package/dist/client/logout-notify-endpoints.d.ts +71 -0
- package/dist/client/logout-notify-endpoints.js +34 -0
- package/dist/client/logout-notify-endpoints.js.map +1 -0
- package/dist/client/messaging.d.ts +168 -0
- package/dist/client/messaging.js +45 -0
- package/dist/client/messaging.js.map +1 -1
- package/dist/client/oauth-clients.d.ts +86 -1
- package/dist/client/oauth-clients.js +23 -2
- package/dist/client/oauth-clients.js.map +1 -1
- package/dist/client/platform.d.ts +129 -0
- package/dist/client/platform.js +80 -0
- package/dist/client/platform.js.map +1 -1
- package/dist/client/users.d.ts +29 -1
- package/dist/client/users.js +10 -2
- package/dist/client/users.js.map +1 -1
- package/dist/client/webhooks.d.ts +21 -0
- package/dist/client/webhooks.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/logout-token.d.ts +8 -0
- package/dist/logout-token.js +20 -15
- package/dist/logout-token.js.map +1 -1
- package/dist/oidc.d.ts +225 -0
- package/dist/oidc.js +631 -0
- package/dist/oidc.js.map +1 -0
- package/dist/testing.d.ts +90 -1
- package/dist/testing.js +202 -3
- package/dist/testing.js.map +1 -1
- package/dist/verify.d.ts +21 -0
- package/dist/verify.js +20 -0
- package/dist/verify.js.map +1 -1
- package/dist/webhooks.d.ts +16 -5
- package/dist/webhooks.js +11 -7
- package/dist/webhooks.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4,12 +4,14 @@ export * from './verify';
|
|
|
4
4
|
export * from './handshake';
|
|
5
5
|
export { BACKCHANNEL_LOGOUT_EVENT, LOGOUT_TOKEN_CLOCK_SKEW_SECONDS, LOGOUT_TOKEN_MAX_AGE_SECONDS, LogoutTokenVerifier, memoryLogoutReplayStore, verifyLogoutToken, } from './logout-token';
|
|
6
6
|
export type { LogoutReplayStore, LogoutTokenCheckOptions, LogoutTokenClaims, LogoutTokenResult, LogoutTokenVerifierOptions, } from './logout-token';
|
|
7
|
+
export { AtlasOidcError, OIDC_FLOW_COOKIE, OIDC_FLOW_MAX_AGE_SECONDS, oidc, oidcCallback, oidcClearCookie, oidcLogoutUrl, oidcStart, oidcVerifyIdToken, resetOidcCaches, } from './oidc';
|
|
8
|
+
export type { AtlasOidc, AtlasOidcErrorCode, OidcCallbackOptions, OidcClientAuth, OidcIdentity, OidcLogoutUrlOptions, OidcStartOptions, OidcStartResult, VerifyIdTokenOptions, } from './oidc';
|
|
7
9
|
export * from './webhooks';
|
|
8
10
|
export { createAtlasClient } from './client';
|
|
9
11
|
export type { AtlasClient } from './client';
|
|
10
12
|
export * from './client';
|
|
11
|
-
export { createTestIssuer } from './testing';
|
|
12
|
-
export type { TestIssuer, CreateTestIssuerOptions } from './testing';
|
|
13
|
+
export { createTestIssuer, TEST_TOKEN_TAMPERS } from './testing';
|
|
14
|
+
export type { TestIssuer, CreateTestIssuerOptions, MintIdTokenOptions, TestAuthorizeOptions, TestAuthorizeResult, TestTokenTamper, } from './testing';
|
|
13
15
|
export { verifyPCActn } from './pca/verify';
|
|
14
16
|
export type { PcaVerdict, PcaContext, VerifyPCActnOptions } from './pca/verify';
|
|
15
17
|
export { requirePCA, defaultExtract, memoryPcaStore } from './pca/require-pca';
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.memoryPcaStore = exports.defaultExtract = exports.requirePCA = exports.verifyPCActn = exports.createTestIssuer = exports.createAtlasClient = exports.verifyLogoutToken = exports.memoryLogoutReplayStore = exports.LogoutTokenVerifier = exports.LOGOUT_TOKEN_MAX_AGE_SECONDS = exports.LOGOUT_TOKEN_CLOCK_SKEW_SECONDS = exports.BACKCHANNEL_LOGOUT_EVENT = exports.instanceIdFromPublishableKey = exports.discoveryUrlFor = exports.JwksDiscovery = exports.DiscoveryError = void 0;
|
|
17
|
+
exports.memoryPcaStore = exports.defaultExtract = exports.requirePCA = exports.verifyPCActn = exports.TEST_TOKEN_TAMPERS = exports.createTestIssuer = exports.createAtlasClient = exports.resetOidcCaches = exports.oidcVerifyIdToken = exports.oidcStart = exports.oidcLogoutUrl = exports.oidcClearCookie = exports.oidcCallback = exports.oidc = exports.OIDC_FLOW_MAX_AGE_SECONDS = exports.OIDC_FLOW_COOKIE = exports.AtlasOidcError = exports.verifyLogoutToken = exports.memoryLogoutReplayStore = exports.LogoutTokenVerifier = exports.LOGOUT_TOKEN_MAX_AGE_SECONDS = exports.LOGOUT_TOKEN_CLOCK_SKEW_SECONDS = exports.BACKCHANNEL_LOGOUT_EVENT = exports.instanceIdFromPublishableKey = exports.discoveryUrlFor = exports.JwksDiscovery = exports.DiscoveryError = void 0;
|
|
18
18
|
// §7.3 token verification — the original surface, unchanged.
|
|
19
19
|
__exportStar(require("./jwks-cache"), exports);
|
|
20
20
|
// OIDC discovery of the JWKS URL when only `issuer` is configured.
|
|
@@ -33,6 +33,19 @@ Object.defineProperty(exports, "LOGOUT_TOKEN_MAX_AGE_SECONDS", { enumerable: tru
|
|
|
33
33
|
Object.defineProperty(exports, "LogoutTokenVerifier", { enumerable: true, get: function () { return logout_token_1.LogoutTokenVerifier; } });
|
|
34
34
|
Object.defineProperty(exports, "memoryLogoutReplayStore", { enumerable: true, get: function () { return logout_token_1.memoryLogoutReplayStore; } });
|
|
35
35
|
Object.defineProperty(exports, "verifyLogoutToken", { enumerable: true, get: function () { return logout_token_1.verifyLogoutToken; } });
|
|
36
|
+
// Server-side OIDC relying party for the hosted-redirect integration:
|
|
37
|
+
// state + nonce + PKCE flow cookie, code exchange, RS256-pinned ID-token checks.
|
|
38
|
+
var oidc_1 = require("./oidc");
|
|
39
|
+
Object.defineProperty(exports, "AtlasOidcError", { enumerable: true, get: function () { return oidc_1.AtlasOidcError; } });
|
|
40
|
+
Object.defineProperty(exports, "OIDC_FLOW_COOKIE", { enumerable: true, get: function () { return oidc_1.OIDC_FLOW_COOKIE; } });
|
|
41
|
+
Object.defineProperty(exports, "OIDC_FLOW_MAX_AGE_SECONDS", { enumerable: true, get: function () { return oidc_1.OIDC_FLOW_MAX_AGE_SECONDS; } });
|
|
42
|
+
Object.defineProperty(exports, "oidc", { enumerable: true, get: function () { return oidc_1.oidc; } });
|
|
43
|
+
Object.defineProperty(exports, "oidcCallback", { enumerable: true, get: function () { return oidc_1.oidcCallback; } });
|
|
44
|
+
Object.defineProperty(exports, "oidcClearCookie", { enumerable: true, get: function () { return oidc_1.oidcClearCookie; } });
|
|
45
|
+
Object.defineProperty(exports, "oidcLogoutUrl", { enumerable: true, get: function () { return oidc_1.oidcLogoutUrl; } });
|
|
46
|
+
Object.defineProperty(exports, "oidcStart", { enumerable: true, get: function () { return oidc_1.oidcStart; } });
|
|
47
|
+
Object.defineProperty(exports, "oidcVerifyIdToken", { enumerable: true, get: function () { return oidc_1.oidcVerifyIdToken; } });
|
|
48
|
+
Object.defineProperty(exports, "resetOidcCaches", { enumerable: true, get: function () { return oidc_1.resetOidcCaches; } });
|
|
36
49
|
// §12.2 inbound webhook verification for consumers.
|
|
37
50
|
__exportStar(require("./webhooks"), exports);
|
|
38
51
|
// The typed management client for the secret-key Backend API.
|
|
@@ -44,6 +57,7 @@ __exportStar(require("./client"), exports);
|
|
|
44
57
|
// Its own module, so it never sits on the hot verification path.
|
|
45
58
|
var testing_1 = require("./testing");
|
|
46
59
|
Object.defineProperty(exports, "createTestIssuer", { enumerable: true, get: function () { return testing_1.createTestIssuer; } });
|
|
60
|
+
Object.defineProperty(exports, "TEST_TOKEN_TAMPERS", { enumerable: true, get: function () { return testing_1.TEST_TOKEN_TAMPERS; } });
|
|
47
61
|
// Proof-Carrying Authority (agentic auth): offline verifier + framework-agnostic guard,
|
|
48
62
|
// beside the session-token verifier above.
|
|
49
63
|
var verify_1 = require("./pca/verify");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,mEAAmE;AACnE,yCAA2G;AAAlG,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,yHAAA,4BAA4B,OAAA;AACrF,2CAAyB;AACzB,8CAA4B;AAE5B,6EAA6E;AAC7E,+CAOwB;AANtB,wHAAA,wBAAwB,OAAA;AACxB,+HAAA,+BAA+B,OAAA;AAC/B,4HAAA,4BAA4B,OAAA;AAC5B,mHAAA,mBAAmB,OAAA;AACnB,uHAAA,uBAAuB,OAAA;AACvB,iHAAA,iBAAiB,OAAA;AAUnB,oDAAoD;AACpD,6CAA2B;AAE3B,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,mEAAmE;AACnE,yCAA2G;AAAlG,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,yHAAA,4BAA4B,OAAA;AACrF,2CAAyB;AACzB,8CAA4B;AAE5B,6EAA6E;AAC7E,+CAOwB;AANtB,wHAAA,wBAAwB,OAAA;AACxB,+HAAA,+BAA+B,OAAA;AAC/B,4HAAA,4BAA4B,OAAA;AAC5B,mHAAA,mBAAmB,OAAA;AACnB,uHAAA,uBAAuB,OAAA;AACvB,iHAAA,iBAAiB,OAAA;AAUnB,sEAAsE;AACtE,iFAAiF;AACjF,+BAWgB;AAVd,sGAAA,cAAc,OAAA;AACd,wGAAA,gBAAgB,OAAA;AAChB,iHAAA,yBAAyB,OAAA;AACzB,4FAAA,IAAI,OAAA;AACJ,oGAAA,YAAY,OAAA;AACZ,uGAAA,eAAe,OAAA;AACf,qGAAA,aAAa,OAAA;AACb,iGAAA,SAAS,OAAA;AACT,yGAAA,iBAAiB,OAAA;AACjB,uGAAA,eAAe,OAAA;AAcjB,oDAAoD;AACpD,6CAA2B;AAE3B,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAAiE;AAAxD,2GAAA,gBAAgB,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAU7C,wFAAwF;AACxF,2CAA2C;AAC3C,uCAA4C;AAAnC,sGAAA,YAAY,OAAA;AAErB,iDAA+E;AAAtE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA"}
|
package/dist/logout-token.d.ts
CHANGED
|
@@ -37,6 +37,14 @@ export type LogoutTokenResult = {
|
|
|
37
37
|
*/
|
|
38
38
|
reason: 'malformed' | 'no_keys' | 'invalid' | 'replayed';
|
|
39
39
|
detail?: string;
|
|
40
|
+
/**
|
|
41
|
+
* True when the failure is on YOUR side and temporary (`no_keys`: the
|
|
42
|
+
* issuer's keys could not be fetched, e.g. a network error or a JWKS
|
|
43
|
+
* outage). Answer `503` with `Retry-After` so Atlas retries the delivery.
|
|
44
|
+
* False for a token that is itself bad: answer `400`, which Atlas never
|
|
45
|
+
* retries.
|
|
46
|
+
*/
|
|
47
|
+
retryable: boolean;
|
|
40
48
|
};
|
|
41
49
|
/**
|
|
42
50
|
* Remembers logout_token `jti`s so a captured token cannot be replayed. Return
|
package/dist/logout-token.js
CHANGED
|
@@ -92,26 +92,30 @@ function verifyLogoutToken(token, options) {
|
|
|
92
92
|
/** Shared by {@link LogoutTokenVerifier} and `AtlasBackend.verifyLogoutToken`. */
|
|
93
93
|
async function checkLogoutToken(token, cache, options) {
|
|
94
94
|
if (typeof token !== 'string' || token.split('.').length !== 3) {
|
|
95
|
-
return { ok: false, reason: 'malformed' };
|
|
95
|
+
return { ok: false, reason: 'malformed', retryable: false };
|
|
96
96
|
}
|
|
97
97
|
let header;
|
|
98
98
|
try {
|
|
99
99
|
header = (0, jose_1.decodeProtectedHeader)(token);
|
|
100
100
|
}
|
|
101
101
|
catch {
|
|
102
|
-
return { ok: false, reason: 'malformed' };
|
|
102
|
+
return { ok: false, reason: 'malformed', retryable: false };
|
|
103
103
|
}
|
|
104
104
|
if (header.typ !== undefined) {
|
|
105
105
|
const typ = String(header.typ).toLowerCase();
|
|
106
106
|
if (typ !== 'logout+jwt' && typ !== 'application/logout+jwt') {
|
|
107
|
-
return { ok: false, reason: 'invalid', detail: 'typ is not logout+jwt' };
|
|
107
|
+
return { ok: false, reason: 'invalid', detail: 'typ is not logout+jwt', retryable: false };
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
const
|
|
111
|
-
|
|
110
|
+
const kid = (0, jwks_cache_1.readKid)(token);
|
|
111
|
+
const keys = await cache.get(kid);
|
|
112
|
+
// No keys at all, or a key Atlas has just rotated to that could not be fetched
|
|
113
|
+
// because the refetch failed: both are temporary, on the receiver's side.
|
|
114
|
+
const missingAfterFailedFetch = kid !== undefined && cache.lastOutcome === 'failed' && !keys?.keys.some((k) => k.kid === kid);
|
|
115
|
+
if (!keys || keys.keys.length === 0 || missingAfterFailedFetch) {
|
|
112
116
|
return cache.lastError
|
|
113
|
-
? { ok: false, reason: 'no_keys', detail: cache.lastError }
|
|
114
|
-
: { ok: false, reason: 'no_keys' };
|
|
117
|
+
? { ok: false, reason: 'no_keys', detail: cache.lastError, retryable: true }
|
|
118
|
+
: { ok: false, reason: 'no_keys', retryable: true };
|
|
115
119
|
}
|
|
116
120
|
const nowMs = options.now ? options.now() : Date.now();
|
|
117
121
|
const audience = typeof options.clientId === 'string' ? options.clientId : [...options.clientId];
|
|
@@ -131,6 +135,7 @@ async function checkLogoutToken(token, cache, options) {
|
|
|
131
135
|
return {
|
|
132
136
|
ok: false,
|
|
133
137
|
reason: 'invalid',
|
|
138
|
+
retryable: false,
|
|
134
139
|
detail: code === 'ERR_JWT_EXPIRED'
|
|
135
140
|
? 'expired'
|
|
136
141
|
: code === 'ERR_JWT_CLAIM_VALIDATION_FAILED'
|
|
@@ -141,36 +146,36 @@ async function checkLogoutToken(token, cache, options) {
|
|
|
141
146
|
const nowSec = Math.floor(nowMs / 1000);
|
|
142
147
|
const iat = payload.iat;
|
|
143
148
|
if (typeof iat !== 'number')
|
|
144
|
-
return { ok: false, reason: 'invalid', detail: 'iat missing' };
|
|
149
|
+
return { ok: false, reason: 'invalid', detail: 'iat missing', retryable: false };
|
|
145
150
|
if (iat > nowSec + exports.LOGOUT_TOKEN_CLOCK_SKEW_SECONDS) {
|
|
146
|
-
return { ok: false, reason: 'invalid', detail: 'iat is in the future' };
|
|
151
|
+
return { ok: false, reason: 'invalid', detail: 'iat is in the future', retryable: false };
|
|
147
152
|
}
|
|
148
153
|
const maxAge = options.maxAgeSeconds ?? exports.LOGOUT_TOKEN_MAX_AGE_SECONDS;
|
|
149
154
|
if (nowSec - iat > maxAge + exports.LOGOUT_TOKEN_CLOCK_SKEW_SECONDS) {
|
|
150
|
-
return { ok: false, reason: 'invalid', detail: 'iat is too old' };
|
|
155
|
+
return { ok: false, reason: 'invalid', detail: 'iat is too old', retryable: false };
|
|
151
156
|
}
|
|
152
157
|
const jti = payload.jti;
|
|
153
158
|
if (typeof jti !== 'string' || !jti)
|
|
154
|
-
return { ok: false, reason: 'invalid', detail: 'jti missing' };
|
|
159
|
+
return { ok: false, reason: 'invalid', detail: 'jti missing', retryable: false };
|
|
155
160
|
const events = payload.events;
|
|
156
161
|
const event = events && typeof events === 'object' && !Array.isArray(events)
|
|
157
162
|
? events[exports.BACKCHANNEL_LOGOUT_EVENT]
|
|
158
163
|
: undefined;
|
|
159
164
|
if (!event || typeof event !== 'object' || Array.isArray(event)) {
|
|
160
|
-
return { ok: false, reason: 'invalid', detail: 'back-channel logout event missing' };
|
|
165
|
+
return { ok: false, reason: 'invalid', detail: 'back-channel logout event missing', retryable: false };
|
|
161
166
|
}
|
|
162
167
|
if ('nonce' in payload) {
|
|
163
|
-
return { ok: false, reason: 'invalid', detail: 'nonce must not be present' };
|
|
168
|
+
return { ok: false, reason: 'invalid', detail: 'nonce must not be present', retryable: false };
|
|
164
169
|
}
|
|
165
170
|
const sub = typeof payload.sub === 'string' && payload.sub ? payload.sub : undefined;
|
|
166
171
|
const sid = typeof payload.sid === 'string' && payload.sid ? payload.sid : undefined;
|
|
167
172
|
if (!sub && !sid)
|
|
168
|
-
return { ok: false, reason: 'invalid', detail: 'neither sid nor sub present' };
|
|
173
|
+
return { ok: false, reason: 'invalid', detail: 'neither sid nor sub present', retryable: false };
|
|
169
174
|
if (options.replayStore) {
|
|
170
175
|
const expiresAtMs = (iat + maxAge + exports.LOGOUT_TOKEN_CLOCK_SKEW_SECONDS) * 1000;
|
|
171
176
|
const fresh = await options.replayStore.remember(jti, expiresAtMs);
|
|
172
177
|
if (!fresh)
|
|
173
|
-
return { ok: false, reason: 'replayed' };
|
|
178
|
+
return { ok: false, reason: 'replayed', retryable: false };
|
|
174
179
|
}
|
|
175
180
|
const claims = { jti, iat };
|
|
176
181
|
if (sub)
|
package/dist/logout-token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout-token.js","sourceRoot":"","sources":["../src/logout-token.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"logout-token.js","sourceRoot":"","sources":["../src/logout-token.ts"],"names":[],"mappings":";;;AAmEA,0DAWC;AAiFD,8CAKC;AAGD,4CAoGC;AA3QD,+BAA2E;AAC3E,6CAA6D;AAC7D,2CAA0E;AAE1E;;;;;;;;GAQG;AAEH,qEAAqE;AACxD,QAAA,wBAAwB,GAAG,oDAAoD,CAAC;AAE7F,wDAAwD;AAC3C,QAAA,+BAA+B,GAAG,CAAC,CAAC;AAEjD,wGAAwG;AAC3F,QAAA,4BAA4B,GAAG,GAAG,CAAC;AA6ChD,yFAAyF;AACzF,SAAgB,uBAAuB,CAAC,MAAoB,IAAI,CAAC,GAAG;IAClE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,OAAO;QACL,QAAQ,CAAC,GAAG,EAAE,WAAW;YACvB,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;YAChB,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI;gBAAE,IAAI,GAAG,IAAI,CAAC;oBAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1D,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC;AAgCD;;;GAGG;AACH,MAAa,mBAAmB;IAGD;IAFZ,KAAK,CAAY;IAElC,YAA6B,OAAmC;QAAnC,YAAO,GAAP,OAAO,CAA4B;QAC9D,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACzF,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,SAAoC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,UAAU,GACd,OAAO,CAAC,UAAU;gBAClB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAA,wCAA4B,EAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC9F,SAAS,GAAG,IAAI,yBAAa,CAAC;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU;gBACV,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,sBAAS,CAAC;YACzB,GAAG,EAAE,OAAO,CAAC,OAAO;YACpB,UAAU,EAAE,OAAO,CAAC,IAAI;YACxB,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS;YAC7D,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,KAAK,CAAC,MAAM,CAAC,KAAa;QACxB,OAAO,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC;CACF;AAvCD,kDAuCC;AAED;;;GAGG;AACH,SAAgB,iBAAiB,CAC/B,KAAa,EACb,OAAmC;IAEnC,OAAO,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,kFAAkF;AAC3E,KAAK,UAAU,gBAAgB,CACpC,KAAa,EACb,KAAgB,EAChB,OAAgC;IAEhC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,MAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,IAAA,4BAAqB,EAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9D,CAAC;IACD,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7C,IAAI,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,wBAAwB,EAAE,CAAC;YAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QAC7F,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,oBAAO,EAAC,KAAK,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,+EAA+E;IAC/E,0EAA0E;IAC1E,MAAM,uBAAuB,GAC3B,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAChG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,uBAAuB,EAAE,CAAC;QAC/D,OAAO,KAAK,CAAC,SAAS;YACpB,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE;YAC5E,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACxD,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACvD,MAAM,QAAQ,GACZ,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClF,IAAI,OAAgC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAA,gBAAS,EAAC,KAAK,EAAE,IAAA,wBAAiB,EAAC,IAAa,CAAC,EAAE;YACxE,UAAU,EAAE,CAAC,OAAO,CAAC;YACrB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ;YACR,cAAc,EAAE,uCAA+B;YAC/C,WAAW,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC;SAC7B,CAAC,CAAC;QACH,OAAO,GAAG,QAAQ,CAAC,OAAkC,CAAC;IACxD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAI,KAA2B,CAAC,IAAI,CAAC;QAC/C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,KAAK;YAChB,MAAM,EACJ,IAAI,KAAK,iBAAiB;gBACxB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,KAAK,iCAAiC;oBAC1C,CAAC,CAAC,uBAAwB,KAA4B,CAAC,KAAK,IAAI,SAAS,EAAE;oBAC3E,CAAC,CAAC,kCAAkC;SAC3C,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9G,IAAI,GAAG,GAAG,MAAM,GAAG,uCAA+B,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,sBAAsB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC5F,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,IAAI,oCAA4B,CAAC;IACrE,IAAI,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,uCAA+B,EAAE,CAAC;QAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACtF,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAEtH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GACT,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5D,CAAC,CAAE,MAAkC,CAAC,gCAAwB,CAAC;QAC/D,CAAC,CAAC,SAAS,CAAC;IAChB,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,mCAAmC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACzG,CAAC;IACD,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,2BAA2B,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACjG,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACrF,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACrF,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,6BAA6B,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAEnH,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,CAAC,GAAG,GAAG,MAAM,GAAG,uCAA+B,CAAC,GAAG,IAAI,CAAC;QAC5E,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACnE,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACzE,CAAC;IAED,MAAM,MAAM,GAAsB,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAC/C,IAAI,GAAG;QAAE,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;IAC1B,IAAI,GAAG;QAAE,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;IAC1B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC"}
|
package/dist/oidc.d.ts
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { type JWTPayload } from 'jose';
|
|
2
|
+
/**
|
|
3
|
+
* Server-side OpenID Connect relying party for the hosted-redirect integration.
|
|
4
|
+
*
|
|
5
|
+
* The three calls an app needs, in order:
|
|
6
|
+
*
|
|
7
|
+
* const { url, cookie } = await oidc.start({ issuer, clientId, redirectUri, secret });
|
|
8
|
+
* // → Set-Cookie: cookie, 302 to url
|
|
9
|
+
* const identity = await oidc.callback({ issuer, clientId, clientSecret, redirectUri, query, cookie, secret });
|
|
10
|
+
* // → Set-Cookie: identity.clearCookie, start your own session for identity.namespacedSub
|
|
11
|
+
* const logout = await oidc.logoutUrl({ issuer, clientId, postLogoutRedirectUri, idTokenHint });
|
|
12
|
+
*
|
|
13
|
+
* What it does so the integrator does not have to:
|
|
14
|
+
* - state, nonce and a PKCE (S256) pair per sign-in, carried to the callback in
|
|
15
|
+
* ONE short-lived httpOnly flow cookie scoped to the callback path. With a
|
|
16
|
+
* `secret` the cookie is sealed (AES-256-GCM, key derived with HKDF), so it
|
|
17
|
+
* can be neither read nor forged; the verifier never reaches page JavaScript
|
|
18
|
+
* either way.
|
|
19
|
+
* - discovery (cached per issuer for an hour; a failure is remembered for a
|
|
20
|
+
* minute so a burst of callbacks cannot become an outbound request flood),
|
|
21
|
+
* the code exchange with the client's authentication method, and the JWKS
|
|
22
|
+
* (the package's rate-limited kid-miss cache).
|
|
23
|
+
* - ID-token verification with the algorithm PINNED to RS256 (so `alg: none`
|
|
24
|
+
* and HS* confusion are refused), `iss` exact, `aud` containing the client id
|
|
25
|
+
* (and `azp` equal to it when there are several audiences or an `azp` at all),
|
|
26
|
+
* `nonce` equal to the cookie's, `exp`/`iat` with a small tolerance, and
|
|
27
|
+
* `at_hash` when the token carries one.
|
|
28
|
+
*
|
|
29
|
+
* Every failure is an {@link AtlasOidcError} with a stable `code`. Only Web
|
|
30
|
+
* standard globals are used (fetch, crypto.subtle, TextEncoder, atob/btoa), so
|
|
31
|
+
* this runs unchanged on Node 18+, Bun, Deno and edge runtimes.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Stable failure codes. `access_denied` also stands for the OAuth `error` the
|
|
35
|
+
* authorization server redirected back with; that exact value is in
|
|
36
|
+
* {@link AtlasOidcError.oauthError}.
|
|
37
|
+
*/
|
|
38
|
+
export type AtlasOidcErrorCode = 'state_mismatch' | 'issuer_mismatch' | 'invalid_request' | 'invalid_token' | 'token_exchange_failed' | 'access_denied' | 'discovery_failed';
|
|
39
|
+
export declare class AtlasOidcError extends Error {
|
|
40
|
+
readonly code: AtlasOidcErrorCode;
|
|
41
|
+
/** The OAuth `error` value from the authorization or token endpoint, when there was one. */
|
|
42
|
+
readonly oauthError?: string;
|
|
43
|
+
/** The OAuth `error_description`, when there was one. */
|
|
44
|
+
readonly description?: string;
|
|
45
|
+
/** HTTP status of the token endpoint's answer, for `token_exchange_failed`. */
|
|
46
|
+
readonly status?: number;
|
|
47
|
+
/**
|
|
48
|
+
* A `Set-Cookie` value that removes the flow cookie. Send it with your error
|
|
49
|
+
* response too, so a failed sign-in leaves nothing behind. Set on every error
|
|
50
|
+
* thrown by {@link oidcCallback}.
|
|
51
|
+
*/
|
|
52
|
+
clearCookie?: string;
|
|
53
|
+
readonly cause?: unknown;
|
|
54
|
+
constructor(code: AtlasOidcErrorCode, message: string, extra?: {
|
|
55
|
+
cause?: unknown;
|
|
56
|
+
oauthError?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
status?: number;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
interface OidcBaseOptions {
|
|
62
|
+
/** Your instance's issuer: `https://` + its frontend API host. */
|
|
63
|
+
issuer: string;
|
|
64
|
+
/** The OAuth client id (`client_id`). */
|
|
65
|
+
clientId: string;
|
|
66
|
+
/**
|
|
67
|
+
* Override the discovery document URL. Defaults to
|
|
68
|
+
* `${issuer}/.well-known/openid-configuration`.
|
|
69
|
+
*/
|
|
70
|
+
discoveryUrl?: string;
|
|
71
|
+
fetchImpl?: typeof fetch;
|
|
72
|
+
/** A clock in epoch milliseconds, for deterministic tests. */
|
|
73
|
+
now?: () => number;
|
|
74
|
+
}
|
|
75
|
+
/** The default flow cookie name. */
|
|
76
|
+
export declare const OIDC_FLOW_COOKIE = "atlas_oidc";
|
|
77
|
+
/** How long a started sign-in stays valid, in seconds. */
|
|
78
|
+
export declare const OIDC_FLOW_MAX_AGE_SECONDS = 600;
|
|
79
|
+
export interface OidcStartOptions extends OidcBaseOptions {
|
|
80
|
+
/** The callback URL, registered on the client exactly. */
|
|
81
|
+
redirectUri: string;
|
|
82
|
+
/** Space-delimited scopes. Default `openid profile email`; `openid` is added if missing. */
|
|
83
|
+
scope?: string;
|
|
84
|
+
/** OIDC `prompt` (`login`, `none`, `consent`, `select_account`, `create`). */
|
|
85
|
+
prompt?: string;
|
|
86
|
+
/** OIDC `login_hint`: prefill the sign-in page with this email or identifier. */
|
|
87
|
+
loginHint?: string;
|
|
88
|
+
/** Sent as `audience_hint`. */
|
|
89
|
+
audienceHint?: string;
|
|
90
|
+
/**
|
|
91
|
+
* Any other authorize parameters. They cannot override the ones this helper
|
|
92
|
+
* owns (`response_type`, `client_id`, `redirect_uri`, `state`, `nonce`,
|
|
93
|
+
* `code_challenge`, `code_challenge_method`).
|
|
94
|
+
*/
|
|
95
|
+
extraParams?: Record<string, string | undefined>;
|
|
96
|
+
/** The flow cookie name. Default `atlas_oidc`. Pass the same name to `callback`. */
|
|
97
|
+
cookieName?: string;
|
|
98
|
+
/**
|
|
99
|
+
* A server-side secret (at least 32 characters) that seals the flow cookie.
|
|
100
|
+
* Strongly recommended: without it the cookie is still httpOnly but only
|
|
101
|
+
* encoded, not encrypted or signed. Pass the same value to `callback`.
|
|
102
|
+
*/
|
|
103
|
+
secret?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface OidcStartResult {
|
|
106
|
+
/** Redirect the browser here. */
|
|
107
|
+
url: string;
|
|
108
|
+
/** A `Set-Cookie` header value for the flow cookie. Send it with the redirect. */
|
|
109
|
+
cookie: string;
|
|
110
|
+
state: string;
|
|
111
|
+
nonce: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Begin a sign-in: build the authorize URL and the flow cookie. Send `cookie`
|
|
115
|
+
* as `Set-Cookie` and redirect to `url`.
|
|
116
|
+
*/
|
|
117
|
+
export declare function oidcStart(options: OidcStartOptions): Promise<OidcStartResult>;
|
|
118
|
+
export type OidcClientAuth = 'client_secret_basic' | 'client_secret_post' | 'none';
|
|
119
|
+
export interface OidcCallbackOptions extends OidcBaseOptions {
|
|
120
|
+
/** The same callback URL `start` used. */
|
|
121
|
+
redirectUri: string;
|
|
122
|
+
/** The client secret. Omit for a public client (`clientAuth: 'none'`). */
|
|
123
|
+
clientSecret?: string;
|
|
124
|
+
/**
|
|
125
|
+
* How to authenticate at the token endpoint. Default `client_secret_basic`
|
|
126
|
+
* when `clientSecret` is set, otherwise `none`.
|
|
127
|
+
*/
|
|
128
|
+
clientAuth?: OidcClientAuth;
|
|
129
|
+
/**
|
|
130
|
+
* The callback's query: a `URLSearchParams`, the request URL (or just its
|
|
131
|
+
* query string), or a framework's parsed query object.
|
|
132
|
+
*/
|
|
133
|
+
query: URLSearchParams | string | Record<string, string | string[] | undefined>;
|
|
134
|
+
/** The request's `Cookie` header, or just the flow cookie's value. */
|
|
135
|
+
cookie: string | null | undefined;
|
|
136
|
+
/** The flow cookie name `start` used. Default `atlas_oidc`. */
|
|
137
|
+
cookieName?: string;
|
|
138
|
+
/** The secret `start` used. */
|
|
139
|
+
secret?: string;
|
|
140
|
+
/** Allowed clock skew for `exp`/`iat`, in seconds. Default 60. */
|
|
141
|
+
clockToleranceSec?: number;
|
|
142
|
+
}
|
|
143
|
+
export interface OidcIdentity {
|
|
144
|
+
/** The Atlas user id (`sub`). Unique within one issuer. */
|
|
145
|
+
sub: string;
|
|
146
|
+
/**
|
|
147
|
+
* `${issuer}#${sub}`: unique across issuers. Key your users on this when you
|
|
148
|
+
* accept more than one instance (development and production, or several
|
|
149
|
+
* tenants), so two instances' users can never collide.
|
|
150
|
+
*/
|
|
151
|
+
namespacedSub: string;
|
|
152
|
+
email: string | null;
|
|
153
|
+
/** `true` only when the ID token says `email_verified: true`. */
|
|
154
|
+
emailVerified: boolean;
|
|
155
|
+
name: string | null;
|
|
156
|
+
/** The raw, verified ID token. Keep it for `logoutUrl({ idTokenHint })`. */
|
|
157
|
+
idToken: string;
|
|
158
|
+
accessToken: string;
|
|
159
|
+
/** Present when the client may use refresh tokens and the grant included one. */
|
|
160
|
+
refreshToken?: string;
|
|
161
|
+
/** When the access token expires, in epoch milliseconds. */
|
|
162
|
+
expiresAt: number;
|
|
163
|
+
/** Every verified ID-token claim. */
|
|
164
|
+
claims: JWTPayload & Record<string, unknown>;
|
|
165
|
+
/** A `Set-Cookie` value that removes the flow cookie. Send it with your response. */
|
|
166
|
+
clearCookie: string;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Finish a sign-in: check `state`, exchange the code (with PKCE and client
|
|
170
|
+
* authentication), verify the ID token, and return who signed in.
|
|
171
|
+
*/
|
|
172
|
+
export declare function oidcCallback(options: OidcCallbackOptions): Promise<OidcIdentity>;
|
|
173
|
+
/** Options for {@link verifyIdToken}. */
|
|
174
|
+
export interface VerifyIdTokenOptions {
|
|
175
|
+
issuer: string;
|
|
176
|
+
clientId: string;
|
|
177
|
+
/** The nonce sent on the authorize request. Required: an ID token without the right nonce is refused. */
|
|
178
|
+
nonce: string;
|
|
179
|
+
/** When given and the token has `at_hash`, the access token must match it. */
|
|
180
|
+
accessToken?: string;
|
|
181
|
+
clockToleranceSec?: number;
|
|
182
|
+
discoveryUrl?: string;
|
|
183
|
+
fetchImpl?: typeof fetch;
|
|
184
|
+
now?: () => number;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Verify an ID token on its own (for an app that does its own code exchange).
|
|
188
|
+
* Same checks as {@link oidcCallback}. Throws {@link AtlasOidcError}.
|
|
189
|
+
*/
|
|
190
|
+
export declare function oidcVerifyIdToken(idToken: string, options: VerifyIdTokenOptions): Promise<JWTPayload & Record<string, unknown>>;
|
|
191
|
+
export interface OidcLogoutUrlOptions extends OidcBaseOptions {
|
|
192
|
+
/** Where Atlas sends the user afterwards. Must be registered on the client exactly. */
|
|
193
|
+
postLogoutRedirectUri?: string;
|
|
194
|
+
/** The ID token from sign-in. Lets Atlas skip asking which session to end. */
|
|
195
|
+
idTokenHint?: string;
|
|
196
|
+
/** Echoed back on the post-logout redirect. */
|
|
197
|
+
state?: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* The RP-initiated logout URL (`end_session_endpoint` from discovery). End your
|
|
201
|
+
* own session first, then redirect here so the Atlas session ends too.
|
|
202
|
+
*/
|
|
203
|
+
export declare function oidcLogoutUrl(options: OidcLogoutUrlOptions): Promise<string>;
|
|
204
|
+
/** A `Set-Cookie` value that removes the flow cookie for this callback path. */
|
|
205
|
+
export declare function oidcClearCookie(options: {
|
|
206
|
+
redirectUri: string;
|
|
207
|
+
cookieName?: string;
|
|
208
|
+
}): string;
|
|
209
|
+
/**
|
|
210
|
+
* The relying-party helpers as one namespace: `oidc.start`, `oidc.callback`,
|
|
211
|
+
* `oidc.logoutUrl`, `oidc.verifyIdToken`, `oidc.clearCookie`. Import the
|
|
212
|
+
* standalone `oidcStart` / `oidcCallback` / … for the smallest bundle.
|
|
213
|
+
*/
|
|
214
|
+
export declare const oidc: {
|
|
215
|
+
readonly start: typeof oidcStart;
|
|
216
|
+
readonly callback: typeof oidcCallback;
|
|
217
|
+
readonly logoutUrl: typeof oidcLogoutUrl;
|
|
218
|
+
readonly verifyIdToken: typeof oidcVerifyIdToken;
|
|
219
|
+
readonly clearCookie: typeof oidcClearCookie;
|
|
220
|
+
};
|
|
221
|
+
/** The type of {@link oidc}. */
|
|
222
|
+
export type AtlasOidc = typeof oidc;
|
|
223
|
+
/** Clear the discovery and key caches (tests, or after an issuer change). */
|
|
224
|
+
export declare function resetOidcCaches(): void;
|
|
225
|
+
export {};
|