@atlasauth/backend 0.22.0 → 0.23.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 +11 -0
- package/dist/client/index.d.ts +13 -3
- package/dist/client/instance.d.ts +61 -1
- package/dist/client/instance.js +8 -0
- package/dist/client/instance.js.map +1 -1
- package/dist/client/jwt-templates.d.ts +29 -4
- package/dist/client/jwt-templates.js +1 -1
- package/dist/client/jwt-templates.js.map +1 -1
- package/dist/client/operator.d.ts +35 -0
- package/dist/client/operator.js +47 -12
- package/dist/client/operator.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/recent-auth.d.ts +21 -0
- package/dist/recent-auth.js +30 -0
- package/dist/recent-auth.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @atlasauth/backend changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.23.0 — 2026-10-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `jwtTemplates.create` and `jwtTemplates.update` take `settings` (`lifetime_seconds` 10–86400, `audience`, `algorithm`, `signing_secret`); `JwtTemplate` returns `settings`. `update` accepts claims, settings or both.
|
|
10
|
+
- `instance.integrations.rotateEventsSecret(id, { overlap_seconds })`: rotate an integration's event signing secret, with the old one still signing during the overlap.
|
|
11
|
+
- `startDeviceAuthorization({ issuer, clientId, clientSecret?, scope?, resource? })` and `pollDeviceAuthorization(start)`: the RFC 8628 device flow against any instance's OAuth server, for a CLI of your own. `startOperatorLogin` / `pollOperatorLogin` now use them.
|
|
12
|
+
- `authenticatedWithin(claims, maxAgeSeconds)` and `usedMultiFactor(claims)`: step-up checks on a verified token's `auth_time`, `acr` and `amr`.
|
|
13
|
+
|
|
3
14
|
## 0.22.0 — 2026-10-25
|
|
4
15
|
|
|
5
16
|
### Added
|
package/dist/client/index.d.ts
CHANGED
|
@@ -580,9 +580,7 @@ declare function buildNamespaces(request: RequestFn): {
|
|
|
580
580
|
list(): Promise<import("./types").ListPage<import("./jwt-templates").JwtTemplate>>;
|
|
581
581
|
get(name: string): Promise<import("./jwt-templates").JwtTemplate>;
|
|
582
582
|
create(body: import("./jwt-templates").CreateJwtTemplateBody): Promise<import("./jwt-templates").JwtTemplate>;
|
|
583
|
-
update(name: string, body:
|
|
584
|
-
claims: Record<string, string>;
|
|
585
|
-
}): Promise<import("./jwt-templates").JwtTemplate>;
|
|
583
|
+
update(name: string, body: import("./jwt-templates").UpdateJwtTemplateBody): Promise<import("./jwt-templates").JwtTemplate>;
|
|
586
584
|
delete(name: string): Promise<{
|
|
587
585
|
object: "jwt_template";
|
|
588
586
|
name: string;
|
|
@@ -1195,6 +1193,18 @@ declare function buildNamespaces(request: RequestFn): {
|
|
|
1195
1193
|
url: string;
|
|
1196
1194
|
secret: string;
|
|
1197
1195
|
}>;
|
|
1196
|
+
rotateEventsSecret(id: string, body?: {
|
|
1197
|
+
overlap_seconds?: number;
|
|
1198
|
+
}): Promise<{
|
|
1199
|
+
object: "integration_events_secret";
|
|
1200
|
+
integration: string;
|
|
1201
|
+
endpoint_id: string;
|
|
1202
|
+
url: string;
|
|
1203
|
+
secret: string;
|
|
1204
|
+
overlap_seconds: number;
|
|
1205
|
+
previous_secret_expires_at: number | null;
|
|
1206
|
+
warning: string;
|
|
1207
|
+
}>;
|
|
1198
1208
|
atlasIdToken(id: string, accessToken: string): Promise<import("./instance").IntegrationTokenResponse>;
|
|
1199
1209
|
chatly: {
|
|
1200
1210
|
get(): Promise<import("./instance").ChatlyIntegration>;
|
|
@@ -28,8 +28,31 @@ export interface Instance {
|
|
|
28
28
|
*/
|
|
29
29
|
allowed_origin_integrations?: Record<string, 'redirect' | 'embedded'>;
|
|
30
30
|
auth_config: Metadata;
|
|
31
|
+
/**
|
|
32
|
+
* Sign-in methods that are switched on but not offered to users, because they
|
|
33
|
+
* need an email provider and the instance has none (email is bring-your-own).
|
|
34
|
+
* They become active on their own once a provider is configured.
|
|
35
|
+
*/
|
|
36
|
+
inactive_methods?: InactiveMethod[];
|
|
37
|
+
/** Methods that still work, minus the parts that need email (e.g. password without reset). */
|
|
38
|
+
limited_methods?: LimitedMethod[];
|
|
31
39
|
created_at: number;
|
|
32
40
|
}
|
|
41
|
+
/** A switched-on sign-in method that is not offered to users, and why. */
|
|
42
|
+
export interface InactiveMethod {
|
|
43
|
+
method: 'password' | 'email_code' | 'email_link';
|
|
44
|
+
reason: 'email_provider_required';
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A sign-in method that works, minus parts that need email: password sign-in
|
|
48
|
+
* for users who already hold a password, without reset (and without sign-up
|
|
49
|
+
* while sign-up must verify the address by email).
|
|
50
|
+
*/
|
|
51
|
+
export interface LimitedMethod {
|
|
52
|
+
method: 'password';
|
|
53
|
+
reason: 'email_provider_required';
|
|
54
|
+
unavailable: Array<'password_reset' | 'password_sign_up'>;
|
|
55
|
+
}
|
|
33
56
|
/**
|
|
34
57
|
* How an allowed origin signs in: `redirect` (hosted-redirect OIDC: the app
|
|
35
58
|
* never runs the embedded components), `embedded` (the sign-in components run
|
|
@@ -55,12 +78,32 @@ export interface InstanceUpdateResult {
|
|
|
55
78
|
allowed_origins: string[];
|
|
56
79
|
allowed_origin_integrations?: Record<string, 'redirect' | 'embedded'>;
|
|
57
80
|
auth_config: Metadata;
|
|
81
|
+
/**
|
|
82
|
+
* The write is accepted even when a method needs an email provider the
|
|
83
|
+
* instance does not have yet (Terraform or config import may add it later in
|
|
84
|
+
* the same apply). Such methods are listed here and are not offered to users
|
|
85
|
+
* until a provider is configured.
|
|
86
|
+
*/
|
|
87
|
+
inactive_methods?: InactiveMethod[];
|
|
88
|
+
/** Methods that still work, minus the parts that need email. */
|
|
89
|
+
limited_methods?: LimitedMethod[];
|
|
58
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Setup-check codes about sign-in methods that need email. The full list is at
|
|
93
|
+
* `GET /v1/instance/preflight/codes`; a finding's `code` may be any of them.
|
|
94
|
+
*
|
|
95
|
+
* - `email_provider_missing`: an enabled method needs email and the instance has no
|
|
96
|
+
* email provider (`subject.methods` names them). A warning while the methods are
|
|
97
|
+
* inactive, an error while users with a password cannot reset it.
|
|
98
|
+
* - `instance_sign_in_unused` (info): the instance's own sign-in methods are on but
|
|
99
|
+
* every user signs in with Sign in with Atlas.
|
|
100
|
+
*/
|
|
101
|
+
export type EmailSignInPreflightCode = 'email_provider_missing' | 'email_sign_in_available' | 'instance_sign_in_unused' | 'no_usable_sign_in_methods' | 'sign_up_unreachable';
|
|
59
102
|
/** One problem (or note) the setup check found. */
|
|
60
103
|
export interface PreflightFinding {
|
|
61
104
|
severity: 'error' | 'warning' | 'info';
|
|
62
105
|
/** Stable snake_case identifier, e.g. `oauth_provider_missing_credentials`. */
|
|
63
|
-
code: string;
|
|
106
|
+
code: EmailSignInPreflightCode | (string & {});
|
|
64
107
|
/** What is wrong, in a plain sentence. */
|
|
65
108
|
message: string;
|
|
66
109
|
/** What to do about it, in a plain sentence. */
|
|
@@ -720,6 +763,23 @@ export declare function instanceResource(request: RequestFn): {
|
|
|
720
763
|
url: string;
|
|
721
764
|
secret: string;
|
|
722
765
|
}>;
|
|
766
|
+
/**
|
|
767
|
+
* Rotate the event receiver's signing secret (shown once). With
|
|
768
|
+
* `overlap_seconds` (at most 604800) the old secret keeps signing every
|
|
769
|
+
* delivery as a second Atlas-Signature entry until `previous_secret_expires_at`.
|
|
770
|
+
*/
|
|
771
|
+
rotateEventsSecret(id: string, body?: {
|
|
772
|
+
overlap_seconds?: number;
|
|
773
|
+
}): Promise<{
|
|
774
|
+
object: "integration_events_secret";
|
|
775
|
+
integration: string;
|
|
776
|
+
endpoint_id: string;
|
|
777
|
+
url: string;
|
|
778
|
+
secret: string;
|
|
779
|
+
overlap_seconds: number;
|
|
780
|
+
previous_secret_expires_at: number | null;
|
|
781
|
+
warning: string;
|
|
782
|
+
}>;
|
|
723
783
|
/** An integration token for a Sign in with Atlas user (their Atlas ID access token). */
|
|
724
784
|
atlasIdToken(id: string, accessToken: string): Promise<IntegrationTokenResponse>;
|
|
725
785
|
chatly: {
|
package/dist/client/instance.js
CHANGED
|
@@ -93,6 +93,14 @@ function instanceResource(request) {
|
|
|
93
93
|
revealEventsSecret(id) {
|
|
94
94
|
return request({ method: 'POST', path: `/v1/instance/integrations/${encodeURIComponent(id)}/events_secret` });
|
|
95
95
|
},
|
|
96
|
+
/**
|
|
97
|
+
* Rotate the event receiver's signing secret (shown once). With
|
|
98
|
+
* `overlap_seconds` (at most 604800) the old secret keeps signing every
|
|
99
|
+
* delivery as a second Atlas-Signature entry until `previous_secret_expires_at`.
|
|
100
|
+
*/
|
|
101
|
+
rotateEventsSecret(id, body = {}) {
|
|
102
|
+
return request({ method: 'POST', path: `/v1/instance/integrations/${encodeURIComponent(id)}/events_secret/rotate`, body });
|
|
103
|
+
},
|
|
96
104
|
/** An integration token for a Sign in with Atlas user (their Atlas ID access token). */
|
|
97
105
|
atlasIdToken(id, accessToken) {
|
|
98
106
|
return request({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/client/instance.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/client/instance.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,20 +4,45 @@ export interface JwtTemplate {
|
|
|
4
4
|
object: 'jwt_template';
|
|
5
5
|
name: string;
|
|
6
6
|
claims: Record<string, string>;
|
|
7
|
+
/** Non-secret mint settings; the HS256 secret is never returned. */
|
|
8
|
+
settings?: {
|
|
9
|
+
lifetime_seconds: number | null;
|
|
10
|
+
audience: string | null;
|
|
11
|
+
algorithm: 'RS256' | 'HS256';
|
|
12
|
+
has_signing_secret: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Per-template mint settings. `lifetime_seconds` is 10–86400 (default: the
|
|
17
|
+
* instance session-token lifetime, 60 s); null clears a value on update.
|
|
18
|
+
*/
|
|
19
|
+
export interface JwtTemplateSettingsInput {
|
|
20
|
+
lifetime_seconds?: number | null;
|
|
21
|
+
audience?: string | null;
|
|
22
|
+
algorithm?: 'RS256' | 'HS256';
|
|
23
|
+
/** HS256 shared secret, at least 16 characters. Write-only. */
|
|
24
|
+
signing_secret?: string;
|
|
7
25
|
}
|
|
8
26
|
export interface CreateJwtTemplateBody {
|
|
9
27
|
name: string;
|
|
28
|
+
/**
|
|
29
|
+
* Claim → expression. `{{org.id}}`, `{{org.membership_id}}` and `{{org.role}}`
|
|
30
|
+
* resolve per session from the active organization at mint time.
|
|
31
|
+
*/
|
|
10
32
|
claims: Record<string, string>;
|
|
33
|
+
settings?: JwtTemplateSettingsInput;
|
|
34
|
+
}
|
|
35
|
+
export interface UpdateJwtTemplateBody {
|
|
36
|
+
claims?: Record<string, string>;
|
|
37
|
+
settings?: JwtTemplateSettingsInput;
|
|
11
38
|
}
|
|
12
39
|
export declare function jwtTemplatesResource(request: RequestFn): {
|
|
13
40
|
list(): Promise<ListPage<JwtTemplate>>;
|
|
14
41
|
/** Fetched by template name. */
|
|
15
42
|
get(name: string): Promise<JwtTemplate>;
|
|
16
43
|
create(body: CreateJwtTemplateBody): Promise<JwtTemplate>;
|
|
17
|
-
/**
|
|
18
|
-
update(name: string, body:
|
|
19
|
-
claims: Record<string, string>;
|
|
20
|
-
}): Promise<JwtTemplate>;
|
|
44
|
+
/** Claims and/or settings; the name is the key and cannot change. */
|
|
45
|
+
update(name: string, body: UpdateJwtTemplateBody): Promise<JwtTemplate>;
|
|
21
46
|
delete(name: string): Promise<{
|
|
22
47
|
object: "jwt_template";
|
|
23
48
|
name: string;
|
|
@@ -14,7 +14,7 @@ function jwtTemplatesResource(request) {
|
|
|
14
14
|
create(body) {
|
|
15
15
|
return request({ method: 'POST', path: '/v1/jwt_templates', body });
|
|
16
16
|
},
|
|
17
|
-
/**
|
|
17
|
+
/** Claims and/or settings; the name is the key and cannot change. */
|
|
18
18
|
update(name, body) {
|
|
19
19
|
return request({ method: 'PATCH', path: `/v1/jwt_templates/${(0, request_1.enc)(name)}`, body });
|
|
20
20
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-templates.js","sourceRoot":"","sources":["../../src/client/jwt-templates.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"jwt-templates.js","sourceRoot":"","sources":["../../src/client/jwt-templates.ts"],"names":[],"mappings":";;AA2CA,oDAoBC;AA/DD,uCAAgD;AA2ChD,SAAgB,oBAAoB,CAAC,OAAkB;IACrD,OAAO;QACL,IAAI;YACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,gCAAgC;QAChC,GAAG,CAAC,IAAY;YACd,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,IAAA,aAAG,EAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,CAAC,IAA2B;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,qEAAqE;QACrE,MAAM,CAAC,IAAY,EAAE,IAA2B;YAC9C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,IAAA,aAAG,EAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,CAAC,IAAY;YACjB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAqB,IAAA,aAAG,EAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/E,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -54,6 +54,41 @@ interface Opts {
|
|
|
54
54
|
}
|
|
55
55
|
/** GET /v1/operator — where the operator device flow and token exchange live. */
|
|
56
56
|
export declare function operatorConfiguration(opts?: Opts): Promise<OperatorConfiguration>;
|
|
57
|
+
/**
|
|
58
|
+
* Start an RFC 8628 device flow against any Atlas instance's OAuth server, for a
|
|
59
|
+
* CLI or TV app of your own: `issuer` is the instance's issuer (its Frontend API
|
|
60
|
+
* host, e.g. `https://acme-fapi.atlasauth.net`) and `clientId` an OAuth client
|
|
61
|
+
* with the `urn:ietf:params:oauth:grant-type:device_code` grant. Show the person
|
|
62
|
+
* `verification_uri_complete` (or `verification_uri` + `user_code`), then
|
|
63
|
+
* {@link pollDeviceAuthorization}. A confidential client passes `clientSecret`.
|
|
64
|
+
*/
|
|
65
|
+
export declare function startDeviceAuthorization(params: {
|
|
66
|
+
issuer: string;
|
|
67
|
+
clientId: string;
|
|
68
|
+
clientSecret?: string;
|
|
69
|
+
scope?: string | string[];
|
|
70
|
+
resource?: string;
|
|
71
|
+
}, opts?: Pick<Opts, 'fetch'>): Promise<DeviceAuthorization & {
|
|
72
|
+
config: DeviceFlowEndpoints;
|
|
73
|
+
}>;
|
|
74
|
+
/** Where a device flow runs: {@link startDeviceAuthorization} fills it from the issuer. */
|
|
75
|
+
export interface DeviceFlowEndpoints {
|
|
76
|
+
device_authorization_endpoint: string;
|
|
77
|
+
token_endpoint: string;
|
|
78
|
+
client_id: string;
|
|
79
|
+
client_secret?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Poll the token endpoint until the person approves (resolves the tokens),
|
|
83
|
+
* denies (`access_denied`) or the code expires (`expired_token`); both throw an
|
|
84
|
+
* {@link OAuthFlowError}. Honours `interval` and adds 5 s on each `slow_down`.
|
|
85
|
+
*/
|
|
86
|
+
export declare function pollDeviceAuthorization(start: DeviceAuthorization & {
|
|
87
|
+
config: DeviceFlowEndpoints;
|
|
88
|
+
}, opts?: Pick<Opts, 'fetch'> & {
|
|
89
|
+
sleep?: (ms: number) => Promise<void>;
|
|
90
|
+
signal?: AbortSignal;
|
|
91
|
+
}): Promise<OAuthTokenResponse>;
|
|
57
92
|
/**
|
|
58
93
|
* Start the device flow. With `audience` (one of the configuration's
|
|
59
94
|
* `audiences`), the operator token is minted FOR that other product
|
package/dist/client/operator.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.openSealedBox = exports.sealBox = exports.OAuthFlowError = void 0;
|
|
4
4
|
exports.operatorConfiguration = operatorConfiguration;
|
|
5
|
+
exports.startDeviceAuthorization = startDeviceAuthorization;
|
|
6
|
+
exports.pollDeviceAuthorization = pollDeviceAuthorization;
|
|
5
7
|
exports.startOperatorLogin = startOperatorLogin;
|
|
6
8
|
exports.pollOperatorLogin = pollOperatorLogin;
|
|
7
9
|
exports.exchangeOperatorToken = exchangeOperatorToken;
|
|
@@ -42,27 +44,41 @@ async function operatorConfiguration(opts = {}) {
|
|
|
42
44
|
return (await res.json());
|
|
43
45
|
}
|
|
44
46
|
/**
|
|
45
|
-
* Start
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
47
|
+
* Start an RFC 8628 device flow against any Atlas instance's OAuth server, for a
|
|
48
|
+
* CLI or TV app of your own: `issuer` is the instance's issuer (its Frontend API
|
|
49
|
+
* host, e.g. `https://acme-fapi.atlasauth.net`) and `clientId` an OAuth client
|
|
50
|
+
* with the `urn:ietf:params:oauth:grant-type:device_code` grant. Show the person
|
|
51
|
+
* `verification_uri_complete` (or `verification_uri` + `user_code`), then
|
|
52
|
+
* {@link pollDeviceAuthorization}. A confidential client passes `clientSecret`.
|
|
49
53
|
*/
|
|
50
|
-
async function
|
|
51
|
-
const
|
|
52
|
-
const
|
|
54
|
+
async function startDeviceAuthorization(params, opts = {}) {
|
|
55
|
+
const base = params.issuer.replace(/\/+$/, '');
|
|
56
|
+
const config = {
|
|
57
|
+
device_authorization_endpoint: `${base}/oauth2/device_authorization`,
|
|
58
|
+
token_endpoint: `${base}/oauth2/token`,
|
|
59
|
+
client_id: params.clientId,
|
|
60
|
+
...(params.clientSecret ? { client_secret: params.clientSecret } : {}),
|
|
61
|
+
};
|
|
62
|
+
const scope = Array.isArray(params.scope) ? params.scope.join(' ') : params.scope;
|
|
63
|
+
return startDevice(opts.fetch ?? globalThis.fetch, config, { scope, resource: params.resource });
|
|
64
|
+
}
|
|
65
|
+
async function startDevice(f, config, params) {
|
|
66
|
+
const out = await form(f, config.device_authorization_endpoint, {
|
|
53
67
|
client_id: config.client_id,
|
|
54
|
-
|
|
55
|
-
...(
|
|
68
|
+
...(config.client_secret ? { client_secret: config.client_secret } : {}),
|
|
69
|
+
...(params.scope ? { scope: params.scope } : {}),
|
|
70
|
+
...(params.resource ? { resource: params.resource } : {}),
|
|
56
71
|
});
|
|
57
72
|
if (out._status !== 200)
|
|
58
73
|
throw new OAuthFlowError(String(out.error ?? 'error'), String(out.error_description ?? 'Device authorization failed.'), out._status);
|
|
59
74
|
return { ...out, config };
|
|
60
75
|
}
|
|
61
76
|
/**
|
|
62
|
-
* Poll until the person approves (resolves the
|
|
63
|
-
* code expires (
|
|
77
|
+
* Poll the token endpoint until the person approves (resolves the tokens),
|
|
78
|
+
* denies (`access_denied`) or the code expires (`expired_token`); both throw an
|
|
79
|
+
* {@link OAuthFlowError}. Honours `interval` and adds 5 s on each `slow_down`.
|
|
64
80
|
*/
|
|
65
|
-
async function
|
|
81
|
+
async function pollDeviceAuthorization(start, opts = {}) {
|
|
66
82
|
const f = opts.fetch ?? globalThis.fetch;
|
|
67
83
|
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
68
84
|
let interval = Math.max(1, start.interval) * 1000;
|
|
@@ -75,6 +91,7 @@ async function pollOperatorLogin(start, opts = {}) {
|
|
|
75
91
|
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
76
92
|
device_code: start.device_code,
|
|
77
93
|
client_id: start.config.client_id,
|
|
94
|
+
...(start.config.client_secret ? { client_secret: start.config.client_secret } : {}),
|
|
78
95
|
});
|
|
79
96
|
if (out._status === 200)
|
|
80
97
|
return out;
|
|
@@ -88,6 +105,24 @@ async function pollOperatorLogin(start, opts = {}) {
|
|
|
88
105
|
}
|
|
89
106
|
throw new OAuthFlowError('expired_token', 'The sign-in code expired. Run the login again.', 400);
|
|
90
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Start the device flow. With `audience` (one of the configuration's
|
|
110
|
+
* `audiences`), the operator token is minted FOR that other product
|
|
111
|
+
* (`aud=<audience>`, sent as the RFC 8707 `resource`): hand it to that product;
|
|
112
|
+
* Atlas's own token exchange refuses it.
|
|
113
|
+
*/
|
|
114
|
+
async function startOperatorLogin(opts = {}) {
|
|
115
|
+
const config = opts.config ?? (await operatorConfiguration(opts));
|
|
116
|
+
const out = await startDevice(opts.fetch ?? globalThis.fetch, config, { scope: config.scope, resource: opts.audience });
|
|
117
|
+
return { ...out, config };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Poll until the person approves (resolves the operator token), denies or the
|
|
121
|
+
* code expires (throws). Honours `interval` and `slow_down`.
|
|
122
|
+
*/
|
|
123
|
+
async function pollOperatorLogin(start, opts = {}) {
|
|
124
|
+
return pollDeviceAuthorization(start, opts);
|
|
125
|
+
}
|
|
91
126
|
/** RFC 8693: swap an operator token for a one-hour, resource-bound Atlas token. */
|
|
92
127
|
async function exchangeOperatorToken(subjectToken, params, opts = {}) {
|
|
93
128
|
const out = await form(opts.fetch ?? globalThis.fetch, `${(opts.apiUrl ?? DEFAULT_API).replace(/\/+$/, '')}/v1/oauth/token`, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operator.js","sourceRoot":"","sources":["../../src/client/operator.ts"],"names":[],"mappings":";;;AAmFA,sDAKC;AAQD,
|
|
1
|
+
{"version":3,"file":"operator.js","sourceRoot":"","sources":["../../src/client/operator.ts"],"names":[],"mappings":";;;AAmFA,sDAKC;AAUD,4DAaC;AA8BD,0DA0BC;AAQD,gDAMC;AAMD,8CAKC;AAGD,sDAmBC;AAGD,4CAUC;AAGD,kDAGC;AAGD,4CAEC;AAGD,4CAYC;AA7PD,6CAAiF;AAEjF,MAAM,KAAK,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjE,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAmDhF,MAAa,cAAe,SAAQ,KAAK;IAE5B;IAEA;IAHX,YACW,KAAa,EACtB,OAAe,EACN,MAAc;QAEvB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,UAAK,GAAL,KAAK,CAAQ;QAEb,WAAM,GAAN,MAAM,CAAQ;QAGvB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AATD,wCASC;AAOD,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEhD,KAAK,UAAU,IAAI,CAAC,SAAuB,EAAE,GAAW,EAAE,IAA4B;IACpF,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;QAC/B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE,MAAM,EAAE,kBAAkB,EAAE;QAC5F,IAAI,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;KAC3C,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAA4B,CAAC;IAC7E,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AAC1C,CAAC;AAED,iFAAiF;AAC1E,KAAK,UAAU,qBAAqB,CAAC,OAAa,EAAE;IACzD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACpI,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,cAAc,CAAC,gBAAgB,EAAE,2DAA2D,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,wBAAwB,CAC5C,MAAiH,EACjH,OAA4B,EAAE;IAE9B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAwB;QAClC,6BAA6B,EAAE,GAAG,IAAI,8BAA8B;QACpE,cAAc,EAAE,GAAG,IAAI,eAAe;QACtC,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;IAClF,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AACnG,CAAC;AAUD,KAAK,UAAU,WAAW,CACxB,CAAe,EACf,MAA2B,EAC3B,MAA6C;IAE7C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,6BAA6B,EAAE;QAC9D,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1D,CAAC,CAAC;IACH,IAAI,GAAG,CAAC,OAAO,KAAK,GAAG;QAAE,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,iBAAiB,IAAI,8BAA8B,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9J,OAAO,EAAE,GAAI,GAAsC,EAAE,MAAM,EAAE,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,uBAAuB,CAC3C,KAA4D,EAC5D,OAA8F,EAAE;IAEhG,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACpF,IAAI,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IACtD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO;YAAE,MAAM,IAAI,cAAc,CAAC,SAAS,EAAE,wBAAwB,EAAE,CAAC,CAAC,CAAC;QAC3F,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;YACrD,UAAU,EAAE,8CAA8C;YAC1D,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS;YACjC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrF,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,OAAO,KAAK,GAAG;YAAE,OAAO,GAAoC,CAAC;QACrE,IAAI,GAAG,CAAC,KAAK,KAAK,uBAAuB;YAAE,SAAS;QACpD,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC9B,QAAQ,IAAI,IAAI,CAAC;YACjB,SAAS;QACX,CAAC;QACD,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1H,CAAC;IACD,MAAM,IAAI,cAAc,CAAC,eAAe,EAAE,gDAAgD,EAAE,GAAG,CAAC,CAAC;AACnG,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,kBAAkB,CACtC,OAAqE,EAAE;IAEvE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxH,OAAO,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,iBAAiB,CACrC,KAA8D,EAC9D,OAA+E,EAAE;IAEjF,OAAO,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED,mFAAmF;AAC5E,KAAK,UAAU,qBAAqB,CACzC,YAAoB,EACpB,MAAsD,EACtD,OAAa,EAAE;IAEf,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,EAAE;QAC3H,UAAU,EAAE,iDAAiD;QAC7D,aAAa,EAAE,YAAY;QAC3B,kBAAkB,EAAE,+CAA+C;QACnE,QAAQ,EAAE,OAAO;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;KAC3E,CAAC,CAAC;IACH,IAAI,GAAG,CAAC,OAAO,KAAK,GAAG,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3G,MAAM,GAAG,GAAG,GAAG,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAA0B,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;QAC9I,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,GAA2D,CAAC;AACrE,CAAC;AAED,4FAA4F;AACrF,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,YAAoB,EACpB,OAAkC,EAAE;IAEpC,MAAM,IAAI,GAA2B,EAAE,UAAU,EAAE,oBAAoB,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;IAC5H,IAAI,IAAI,CAAC,KAAK;QAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IACnI,IAAI,GAAG,CAAC,OAAO,KAAK,GAAG;QAAE,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,iBAAiB,IAAI,uBAAuB,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACvJ,OAAO,GAAoC,CAAC;AAC9C,CAAC;AAED,mFAAmF;AACnF,SAAgB,mBAAmB;IACjC,MAAM,IAAI,GAAG,IAAA,gCAAG,GAAE,CAAC;IACnB,OAAO,EAAE,GAAG,IAAI,EAAE,eAAe,EAAE,UAAU,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;AACzE,CAAC;AAED,oFAAoF;AACpF,SAAgB,gBAAgB,CAAC,YAAoB,EAAE,OAAyD;IAC9G,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAA,0BAAI,EAAC,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AACrG,CAAC;AAED,qFAAqF;AAC9E,KAAK,UAAU,gBAAgB,CACpC,OAAiB,EACjB,OAAgC,EAAE;IAElC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,wBAAwB,EAAE;QAC/F,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE;QAC3E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;KAC1E,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,cAAc,CAAC,gBAAgB,EAAE,yBAAyB,GAAG,CAAC,MAAM,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7G,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA8G,CAAC;AACzI,CAAC;AACD,2CAAsD;AAA7C,qGAAA,OAAO,OAAA;AAAE,2GAAA,aAAa,OAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './jwks-cache';
|
|
2
2
|
export { DiscoveryError, JwksDiscovery, discoveryUrlFor, instanceIdFromPublishableKey } from './discovery';
|
|
3
3
|
export * from './verify';
|
|
4
|
+
export * from './recent-auth';
|
|
4
5
|
export * from './access-control';
|
|
5
6
|
export * from './handshake';
|
|
6
7
|
export * from './better-auth';
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "JwksDiscovery", { enumerable: true, get: functio
|
|
|
25
25
|
Object.defineProperty(exports, "discoveryUrlFor", { enumerable: true, get: function () { return discovery_1.discoveryUrlFor; } });
|
|
26
26
|
Object.defineProperty(exports, "instanceIdFromPublishableKey", { enumerable: true, get: function () { return discovery_1.instanceIdFromPublishableKey; } });
|
|
27
27
|
__exportStar(require("./verify"), exports);
|
|
28
|
+
__exportStar(require("./recent-auth"), exports);
|
|
28
29
|
__exportStar(require("./access-control"), exports);
|
|
29
30
|
__exportStar(require("./handshake"), exports);
|
|
30
31
|
// Moving from Better Auth: exchange its session cookie once, accept its JWTs for a window.
|
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,mDAAiC;AACjC,8CAA4B;AAC5B,2FAA2F;AAC3F,gDAA8B;AAC9B,mDAAoE;AAA3D,sHAAA,oBAAoB,OAAA;AAAE,4GAAA,UAAU,OAAA;AAGzC,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;AASnB,+EAA+E;AAC/E,+DAQgC;AAP9B,gIAAA,wBAAwB,OAAA;AACxB,gIAAA,wBAAwB,OAAA;AACxB,sIAAA,8BAA8B,OAAA;AAC9B,8HAAA,sBAAsB,OAAA;AACtB,+HAAA,uBAAuB,OAAA;AACvB,6HAAA,qBAAqB,OAAA;AACrB,uHAAA,eAAe,OAAA;AAIjB,sEAAsE;AACtE,iFAAiF;AACjF,+BAcgB;AAbd,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,0GAAA,kBAAkB,OAAA;AAClB,2GAAA,mBAAmB,OAAA;AACnB,iGAAA,SAAS,OAAA;AACT,uGAAA,eAAe,OAAA;AAkBjB,oDAAoD;AACpD,6CAA2B;AAE3B,uFAAuF;AACvF,8CAA4B;AAC5B,kDAAgC;AAEhC,0FAA0F;AAC1F,0CAAwB;AAExB,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAAmF;AAA1E,2GAAA,gBAAgB,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAU/D,6DAQ+B;AAP7B,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AACjB,+HAAA,wBAAwB,OAAA;AACxB,yHAAA,kBAAkB,OAAA;AAClB,2HAAA,oBAAoB,OAAA;AACpB,wHAAA,iBAAiB,OAAA;AACjB,4HAAA,qBAAqB,OAAA;AAWvB,wFAAwF;AACxF,2CAA2C;AAC3C,uCAA4C;AAAnC,sGAAA,YAAY,OAAA;AAErB,iDAA+E;AAAtE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA;AAGnD,8EAA8E;AAC9E,gFAAgF;AAChF,mDAY0B;AAXxB,iIAAA,+BAA+B,OAAA;AAC/B,4HAAA,0BAA0B,OAAA;AAC1B,sHAAA,oBAAoB,OAAA;AACpB,2HAAA,yBAAyB,OAAA;AACzB,oHAAA,kBAAkB,OAAA;AAClB,qHAAA,mBAAmB,OAAA;AACnB,uHAAA,qBAAqB,OAAA;AACrB,uHAAA,qBAAqB,OAAA;AACrB,2HAAA,yBAAyB,OAAA;AACzB,+HAAA,6BAA6B,OAAA;AAC7B,mHAAA,iBAAiB,OAAA"}
|
|
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,gDAA8B;AAC9B,mDAAiC;AACjC,8CAA4B;AAC5B,2FAA2F;AAC3F,gDAA8B;AAC9B,mDAAoE;AAA3D,sHAAA,oBAAoB,OAAA;AAAE,4GAAA,UAAU,OAAA;AAGzC,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;AASnB,+EAA+E;AAC/E,+DAQgC;AAP9B,gIAAA,wBAAwB,OAAA;AACxB,gIAAA,wBAAwB,OAAA;AACxB,sIAAA,8BAA8B,OAAA;AAC9B,8HAAA,sBAAsB,OAAA;AACtB,+HAAA,uBAAuB,OAAA;AACvB,6HAAA,qBAAqB,OAAA;AACrB,uHAAA,eAAe,OAAA;AAIjB,sEAAsE;AACtE,iFAAiF;AACjF,+BAcgB;AAbd,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,0GAAA,kBAAkB,OAAA;AAClB,2GAAA,mBAAmB,OAAA;AACnB,iGAAA,SAAS,OAAA;AACT,uGAAA,eAAe,OAAA;AAkBjB,oDAAoD;AACpD,6CAA2B;AAE3B,uFAAuF;AACvF,8CAA4B;AAC5B,kDAAgC;AAEhC,0FAA0F;AAC1F,0CAAwB;AAExB,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAAmF;AAA1E,2GAAA,gBAAgB,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAU/D,6DAQ+B;AAP7B,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AACjB,+HAAA,wBAAwB,OAAA;AACxB,yHAAA,kBAAkB,OAAA;AAClB,2HAAA,oBAAoB,OAAA;AACpB,wHAAA,iBAAiB,OAAA;AACjB,4HAAA,qBAAqB,OAAA;AAWvB,wFAAwF;AACxF,2CAA2C;AAC3C,uCAA4C;AAAnC,sGAAA,YAAY,OAAA;AAErB,iDAA+E;AAAtE,yGAAA,UAAU,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA;AAGnD,8EAA8E;AAC9E,gFAAgF;AAChF,mDAY0B;AAXxB,iIAAA,+BAA+B,OAAA;AAC/B,4HAAA,0BAA0B,OAAA;AAC1B,sHAAA,oBAAoB,OAAA;AACpB,2HAAA,yBAAyB,OAAA;AACzB,oHAAA,kBAAkB,OAAA;AAClB,qHAAA,mBAAmB,OAAA;AACnB,uHAAA,qBAAqB,OAAA;AACrB,uHAAA,qBAAqB,OAAA;AACrB,2HAAA,yBAAyB,OAAA;AACzB,+HAAA,6BAA6B,OAAA;AAC7B,mHAAA,iBAAiB,OAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step-up checks on a verified Atlas token. Session and template tokens carry
|
|
3
|
+
* `auth_time` (the first-factor sign-in, or the last step-up), `amr` and `acr`
|
|
4
|
+
* (`urn:atlas:acr:basic`, `urn:atlas:acr:mfa`, `urn:atlas:acr:step_up`).
|
|
5
|
+
*
|
|
6
|
+
* const auth = await atlas.authenticateRequest(req);
|
|
7
|
+
* if (!auth.ok) return res.status(401).end();
|
|
8
|
+
* if (!authenticatedWithin(auth.claims, 300)) {
|
|
9
|
+
* // Ask the browser to step up (POST /v1/client/me/step_up) and retry.
|
|
10
|
+
* return res.status(401).json({ error: 'reauthentication_required', max_age: 300 });
|
|
11
|
+
* }
|
|
12
|
+
*/
|
|
13
|
+
/** Whether `auth_time` is within `maxAgeSeconds` of now. A token without `auth_time` never is. */
|
|
14
|
+
export declare function authenticatedWithin(claims: {
|
|
15
|
+
auth_time?: unknown;
|
|
16
|
+
}, maxAgeSeconds: number, nowMs?: number): boolean;
|
|
17
|
+
/** Whether the session proved a second factor (`acr` is mfa or step_up after an MFA method, or `amr` includes `mfa`). */
|
|
18
|
+
export declare function usedMultiFactor(claims: {
|
|
19
|
+
acr?: unknown;
|
|
20
|
+
amr?: unknown;
|
|
21
|
+
}): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Step-up checks on a verified Atlas token. Session and template tokens carry
|
|
4
|
+
* `auth_time` (the first-factor sign-in, or the last step-up), `amr` and `acr`
|
|
5
|
+
* (`urn:atlas:acr:basic`, `urn:atlas:acr:mfa`, `urn:atlas:acr:step_up`).
|
|
6
|
+
*
|
|
7
|
+
* const auth = await atlas.authenticateRequest(req);
|
|
8
|
+
* if (!auth.ok) return res.status(401).end();
|
|
9
|
+
* if (!authenticatedWithin(auth.claims, 300)) {
|
|
10
|
+
* // Ask the browser to step up (POST /v1/client/me/step_up) and retry.
|
|
11
|
+
* return res.status(401).json({ error: 'reauthentication_required', max_age: 300 });
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.authenticatedWithin = authenticatedWithin;
|
|
16
|
+
exports.usedMultiFactor = usedMultiFactor;
|
|
17
|
+
/** Whether `auth_time` is within `maxAgeSeconds` of now. A token without `auth_time` never is. */
|
|
18
|
+
function authenticatedWithin(claims, maxAgeSeconds, nowMs = Date.now()) {
|
|
19
|
+
const at = claims.auth_time;
|
|
20
|
+
if (typeof at !== 'number' || !Number.isFinite(at))
|
|
21
|
+
return false;
|
|
22
|
+
return nowMs / 1000 - at <= maxAgeSeconds;
|
|
23
|
+
}
|
|
24
|
+
/** Whether the session proved a second factor (`acr` is mfa or step_up after an MFA method, or `amr` includes `mfa`). */
|
|
25
|
+
function usedMultiFactor(claims) {
|
|
26
|
+
if (claims.acr === 'urn:atlas:acr:mfa')
|
|
27
|
+
return true;
|
|
28
|
+
return Array.isArray(claims.amr) && claims.amr.includes('mfa');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=recent-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recent-auth.js","sourceRoot":"","sources":["../src/recent-auth.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AAGH,kDAIC;AAGD,0CAGC;AAXD,kGAAkG;AAClG,SAAgB,mBAAmB,CAAC,MAA+B,EAAE,aAAqB,EAAE,QAAgB,IAAI,CAAC,GAAG,EAAE;IACpH,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;IAC5B,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,OAAO,KAAK,GAAG,IAAI,GAAG,EAAE,IAAI,aAAa,CAAC;AAC5C,CAAC;AAED,yHAAyH;AACzH,SAAgB,eAAe,CAAC,MAAwC;IACtE,IAAI,MAAM,CAAC,GAAG,KAAK,mBAAmB;QAAE,OAAO,IAAI,CAAC;IACpD,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACjE,CAAC"}
|