@atlasauth/backend 0.22.0 → 0.24.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/auth0-session.d.ts +23 -0
- package/dist/auth0-session.js +80 -0
- package/dist/auth0-session.js.map +1 -0
- package/dist/better-auth.d.ts +4 -8
- package/dist/better-auth.js +42 -150
- package/dist/better-auth.js.map +1 -1
- package/dist/client/index.d.ts +67 -3
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -1
- 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/migrations.d.ts +286 -0
- package/dist/client/migrations.js +103 -0
- package/dist/client/migrations.js.map +1 -0
- 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/framework-bridge.d.ts +98 -0
- package/dist/framework-bridge.js +264 -0
- package/dist/framework-bridge.js.map +1 -0
- package/dist/framework-sessions.d.ts +147 -0
- package/dist/framework-sessions.js +544 -0
- package/dist/framework-sessions.js.map +1 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/legacy-issuer-presets.d.ts +85 -0
- package/dist/legacy-issuer-presets.js +165 -0
- package/dist/legacy-issuer-presets.js.map +1 -0
- package/dist/legacy-issuers.d.ts +16 -2
- package/dist/legacy-issuers.js +16 -1
- package/dist/legacy-issuers.js.map +1 -1
- package/dist/legacy-verify.d.ts +103 -0
- package/dist/legacy-verify.js +244 -0
- package/dist/legacy-verify.js.map +1 -0
- package/dist/migration-bridge.d.ts +153 -0
- package/dist/migration-bridge.js +328 -0
- package/dist/migration-bridge.js.map +1 -0
- package/dist/migration-presets.d.ts +150 -0
- package/dist/migration-presets.js +440 -0
- package/dist/migration-presets.js.map +1 -0
- 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
|
@@ -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"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { type BetterAuthImportActionItem } from './better-auth-imports';
|
|
2
|
+
import { type RequestFn } from './request';
|
|
3
|
+
import type { CursorPage, CursorParams } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Migrate to Atlas from any source: the vendor-neutral surface every vendor
|
|
6
|
+
* plugs into (`{source}`: `auth0`, `clerk`, `cognito`, `firebase`, …,
|
|
7
|
+
* `better_auth`, `custom`).
|
|
8
|
+
*
|
|
9
|
+
* imports `/v1/migrations/{source}/imports` — a sealed migration bundle
|
|
10
|
+
* (`@atlasauth/migrate`, or `atlas migrate export <vendor>`):
|
|
11
|
+
* `getPublicKey()`, `upload()` (create + parts + finalize), read the
|
|
12
|
+
* `report`, `apply()`; applying again after a failure resumes.
|
|
13
|
+
* bridge `/v1/migrations/{source}/bridge` — the zero-logout bridge settings
|
|
14
|
+
* (a vendor JWT preset, or imported sessions).
|
|
15
|
+
* sources `/v1/migrations/sources` — what each source supports.
|
|
16
|
+
*/
|
|
17
|
+
export type MigrationSourceId = 'better_auth' | 'auth0' | 'clerk' | 'cognito' | 'firebase' | 'supabase' | 'workos' | 'authjs' | 'okta' | 'stytch' | 'keycloak' | 'fusionauth' | 'kinde' | 'descope' | 'lucia' | 'ory' | 'frontegg' | 'custom';
|
|
18
|
+
export type MigrationImportStatus = 'uploading' | 'analyzing' | 'ready' | 'invalid' | 'queued' | 'applying' | 'completed' | 'failed';
|
|
19
|
+
export interface MigrationImportKey {
|
|
20
|
+
object: 'migration_import_key';
|
|
21
|
+
kid: string;
|
|
22
|
+
/** base64url raw X25519 public key. One key serves every source. */
|
|
23
|
+
public_key: string;
|
|
24
|
+
alg: 'X25519-HKDF-SHA256-A256GCM';
|
|
25
|
+
status: 'active' | 'retired';
|
|
26
|
+
fingerprint: string;
|
|
27
|
+
/** `kid:public_key`, the form the exporters take. */
|
|
28
|
+
compact: string;
|
|
29
|
+
created_at: number;
|
|
30
|
+
retired_at: number | null;
|
|
31
|
+
}
|
|
32
|
+
/** Options of a non-Better-Auth import (a `better_auth` import takes {@link BetterAuthImportOptions}). */
|
|
33
|
+
export interface MigrationImportOptions {
|
|
34
|
+
models?: Array<'organization' | 'role' | 'user' | 'identity' | 'mfa_factor' | 'passkey' | 'membership' | 'invitation' | 'api_key' | 'sso_connection' | 'jwks' | 'session'>;
|
|
35
|
+
on_email_conflict?: 'skip' | 'link';
|
|
36
|
+
create_app_roles?: boolean;
|
|
37
|
+
import_oauth_tokens?: boolean;
|
|
38
|
+
passkeys_on_rp_mismatch?: 'skip' | 'import';
|
|
39
|
+
import_sessions?: boolean;
|
|
40
|
+
import_jwks?: boolean;
|
|
41
|
+
jwks_cutover_days?: number;
|
|
42
|
+
/** Source provider name → Atlas provider key. */
|
|
43
|
+
provider_map?: Record<string, string>;
|
|
44
|
+
/** Hash parameters that live outside the export, per algorithm id (Firebase signer key …). */
|
|
45
|
+
password_hash_params?: Record<string, Record<string, string | number | boolean>>;
|
|
46
|
+
retain_bundle?: boolean;
|
|
47
|
+
[option: string]: unknown;
|
|
48
|
+
}
|
|
49
|
+
interface MigrationReportCommon {
|
|
50
|
+
skipped: Array<{
|
|
51
|
+
model: string;
|
|
52
|
+
row_id: string | null;
|
|
53
|
+
reason_code: string;
|
|
54
|
+
reason: string;
|
|
55
|
+
}>;
|
|
56
|
+
skipped_total: number;
|
|
57
|
+
skipped_by_code: Record<string, number>;
|
|
58
|
+
conflicts: Array<{
|
|
59
|
+
model: string;
|
|
60
|
+
row_id: string | null;
|
|
61
|
+
code: string;
|
|
62
|
+
message: string;
|
|
63
|
+
resolution: 'merge' | 'skip';
|
|
64
|
+
existing_id: string | null;
|
|
65
|
+
}>;
|
|
66
|
+
conflicts_total: number;
|
|
67
|
+
action_items: BetterAuthImportActionItem[];
|
|
68
|
+
warnings: string[];
|
|
69
|
+
notes: Record<string, unknown>;
|
|
70
|
+
}
|
|
71
|
+
export interface MigrationImportReport extends MigrationReportCommon {
|
|
72
|
+
models: Array<{
|
|
73
|
+
model: string;
|
|
74
|
+
label: string;
|
|
75
|
+
found: number;
|
|
76
|
+
will_create: number;
|
|
77
|
+
will_update: number;
|
|
78
|
+
will_skip: number;
|
|
79
|
+
}>;
|
|
80
|
+
/** Users per password-hash algorithm. */
|
|
81
|
+
password_algorithms?: Record<string, number>;
|
|
82
|
+
}
|
|
83
|
+
export interface MigrationImportResult extends MigrationReportCommon {
|
|
84
|
+
models: Array<{
|
|
85
|
+
model: string;
|
|
86
|
+
label: string;
|
|
87
|
+
found: number;
|
|
88
|
+
created: number;
|
|
89
|
+
updated: number;
|
|
90
|
+
unchanged: number;
|
|
91
|
+
skipped: number;
|
|
92
|
+
failed: number;
|
|
93
|
+
}>;
|
|
94
|
+
completed_at: number | null;
|
|
95
|
+
}
|
|
96
|
+
export interface MigrationImport {
|
|
97
|
+
object: 'migration_import';
|
|
98
|
+
id: string;
|
|
99
|
+
source: MigrationSourceId;
|
|
100
|
+
format: 'atlas-migration-bundle' | 'atlas-better-auth-bundle';
|
|
101
|
+
status: MigrationImportStatus;
|
|
102
|
+
key_id: string | null;
|
|
103
|
+
parts: number;
|
|
104
|
+
bytes: number;
|
|
105
|
+
bundle_sha256: string | null;
|
|
106
|
+
bundle_purged: boolean;
|
|
107
|
+
options: Record<string, unknown>;
|
|
108
|
+
manifest: {
|
|
109
|
+
exported_at: string;
|
|
110
|
+
exporter: {
|
|
111
|
+
name: string;
|
|
112
|
+
version: string;
|
|
113
|
+
};
|
|
114
|
+
origin: string | null;
|
|
115
|
+
source_version: string | null;
|
|
116
|
+
models: string[];
|
|
117
|
+
providers: string[];
|
|
118
|
+
rp_id: string | null;
|
|
119
|
+
warnings: string[];
|
|
120
|
+
} | null;
|
|
121
|
+
total: number;
|
|
122
|
+
progress: {
|
|
123
|
+
total: number;
|
|
124
|
+
processed: number;
|
|
125
|
+
succeeded: number;
|
|
126
|
+
failed: number;
|
|
127
|
+
percent: number;
|
|
128
|
+
} | null;
|
|
129
|
+
report: MigrationImportReport | null;
|
|
130
|
+
result: MigrationImportResult | null;
|
|
131
|
+
error: {
|
|
132
|
+
code: string;
|
|
133
|
+
message: string;
|
|
134
|
+
} | null;
|
|
135
|
+
created_at: number;
|
|
136
|
+
updated_at: number;
|
|
137
|
+
analyzed_at: number | null;
|
|
138
|
+
apply_started_at: number | null;
|
|
139
|
+
completed_at: number | null;
|
|
140
|
+
}
|
|
141
|
+
export interface MigrationClaimMap {
|
|
142
|
+
subject?: string;
|
|
143
|
+
email?: string;
|
|
144
|
+
email_verified?: string;
|
|
145
|
+
name?: string;
|
|
146
|
+
session_key?: string;
|
|
147
|
+
mfa?: string;
|
|
148
|
+
}
|
|
149
|
+
/** PUT body of the bridge settings; every field optional, merged onto the stored ones. */
|
|
150
|
+
export interface MigrationBridgeSettingsUpdate {
|
|
151
|
+
enabled?: boolean;
|
|
152
|
+
ends_at?: string | number | null;
|
|
153
|
+
mode?: 'jwt' | 'session_table' | 'remote';
|
|
154
|
+
preset?: string | null;
|
|
155
|
+
preset_vars?: Record<string, string>;
|
|
156
|
+
issuer?: string | null;
|
|
157
|
+
jwks_url?: string | null;
|
|
158
|
+
audience?: string[] | null;
|
|
159
|
+
algorithms?: string[] | null;
|
|
160
|
+
claim_map?: MigrationClaimMap;
|
|
161
|
+
expired_grace_seconds?: number;
|
|
162
|
+
cookie_names?: string[];
|
|
163
|
+
create_users?: boolean;
|
|
164
|
+
/** Write-only HS256 secret; omit to keep, null to clear. */
|
|
165
|
+
shared_secret?: string | null;
|
|
166
|
+
}
|
|
167
|
+
export interface MigrationBridgeSettings {
|
|
168
|
+
object: 'migration_bridge';
|
|
169
|
+
source: MigrationSourceId;
|
|
170
|
+
enabled: boolean;
|
|
171
|
+
ends_at: number | null;
|
|
172
|
+
mode: 'jwt' | 'session_table' | 'remote';
|
|
173
|
+
preset: string | null;
|
|
174
|
+
preset_vars: Record<string, string>;
|
|
175
|
+
issuer: string | null;
|
|
176
|
+
jwks_url: string | null;
|
|
177
|
+
audience: string[] | null;
|
|
178
|
+
algorithms: string[];
|
|
179
|
+
claim_map: Record<string, string>;
|
|
180
|
+
expired_grace_seconds: number;
|
|
181
|
+
cookie_names: string[];
|
|
182
|
+
create_users: boolean;
|
|
183
|
+
has_shared_secret: boolean;
|
|
184
|
+
exchange_path: string;
|
|
185
|
+
stats: {
|
|
186
|
+
exchanged: number;
|
|
187
|
+
from_import: number;
|
|
188
|
+
from_jwt: number;
|
|
189
|
+
};
|
|
190
|
+
created_at: number | null;
|
|
191
|
+
updated_at: number | null;
|
|
192
|
+
}
|
|
193
|
+
export interface MigrationSourceView {
|
|
194
|
+
object: 'migration_source';
|
|
195
|
+
source: MigrationSourceId;
|
|
196
|
+
label: string;
|
|
197
|
+
models: string[];
|
|
198
|
+
passwords: 'export' | 'ticket' | 'lazy' | 'none';
|
|
199
|
+
export_via: Array<'api' | 'file' | 'database' | 'support_ticket'>;
|
|
200
|
+
bridge: {
|
|
201
|
+
mode: 'jwt' | 'session_table' | 'remote' | 'none';
|
|
202
|
+
preset: string | null;
|
|
203
|
+
vars: Record<string, string>;
|
|
204
|
+
cookies: string[];
|
|
205
|
+
};
|
|
206
|
+
lazy_migration: {
|
|
207
|
+
preset: string;
|
|
208
|
+
config: Record<string, {
|
|
209
|
+
label: string;
|
|
210
|
+
required: boolean;
|
|
211
|
+
}>;
|
|
212
|
+
secret: {
|
|
213
|
+
label: string;
|
|
214
|
+
required: boolean;
|
|
215
|
+
} | null;
|
|
216
|
+
} | null;
|
|
217
|
+
password_algorithms: string[];
|
|
218
|
+
limits: string | null;
|
|
219
|
+
}
|
|
220
|
+
export declare function migrationsResource(request: RequestFn): {
|
|
221
|
+
/** Every migration source and what it supports. */
|
|
222
|
+
sources(): Promise<CursorPage<MigrationSourceView>>;
|
|
223
|
+
/** The import surface of one source: `migrations.imports('auth0').upload(text)`. */
|
|
224
|
+
imports: (source: MigrationSourceId | string) => {
|
|
225
|
+
/** The import public key (created on first read; shared by every source). */
|
|
226
|
+
getPublicKey(): Promise<MigrationImportKey>;
|
|
227
|
+
/** Replace the import key; bundles sealed to the old one no longer finalize. */
|
|
228
|
+
rotatePublicKey(): Promise<MigrationImportKey>;
|
|
229
|
+
create(body?: {
|
|
230
|
+
options?: MigrationImportOptions;
|
|
231
|
+
}, idempotencyKey?: string): Promise<MigrationImport>;
|
|
232
|
+
list(params?: CursorParams): Promise<CursorPage<MigrationImport>>;
|
|
233
|
+
get(id: string): Promise<MigrationImport>;
|
|
234
|
+
/** Upload part `part` (1-based) of the sealed bundle text. */
|
|
235
|
+
uploadPart(id: string, part: number, data: string): Promise<{
|
|
236
|
+
object: "migration_import_part";
|
|
237
|
+
import_id: string;
|
|
238
|
+
part: number;
|
|
239
|
+
bytes: number;
|
|
240
|
+
sha256: string;
|
|
241
|
+
}>;
|
|
242
|
+
/** Close the upload; Atlas checks the key and the format, then runs the dry run. */
|
|
243
|
+
finalize(id: string): Promise<MigrationImport>;
|
|
244
|
+
dryRun(id: string, body?: {
|
|
245
|
+
options?: MigrationImportOptions;
|
|
246
|
+
}): Promise<MigrationImport>;
|
|
247
|
+
/** Import (or resume). Pass confirm_conflicts when the dry run reported conflicts. */
|
|
248
|
+
apply(id: string, body?: {
|
|
249
|
+
confirm_conflicts?: boolean;
|
|
250
|
+
}): Promise<MigrationImport>;
|
|
251
|
+
delete(id: string): Promise<{
|
|
252
|
+
object: "migration_import";
|
|
253
|
+
id: string;
|
|
254
|
+
deleted: true;
|
|
255
|
+
}>;
|
|
256
|
+
/**
|
|
257
|
+
* Create an import (or continue `importId`), upload the sealed bundle text
|
|
258
|
+
* in parts from `resumeFrom` (1-based) and finalize it.
|
|
259
|
+
*/
|
|
260
|
+
upload(bundleText: string, opts?: {
|
|
261
|
+
options?: MigrationImportOptions;
|
|
262
|
+
partBytes?: number;
|
|
263
|
+
importId?: string;
|
|
264
|
+
resumeFrom?: number;
|
|
265
|
+
onPart?: (n: number, of: number) => void;
|
|
266
|
+
}): Promise<MigrationImport>;
|
|
267
|
+
/** Poll until the import leaves analyzing / queued / applying. */
|
|
268
|
+
waitFor(id: string, opts?: {
|
|
269
|
+
intervalMs?: number;
|
|
270
|
+
timeoutMs?: number;
|
|
271
|
+
onProgress?: (imp: MigrationImport) => void;
|
|
272
|
+
sleep?: (ms: number) => Promise<void>;
|
|
273
|
+
}): Promise<MigrationImport>;
|
|
274
|
+
};
|
|
275
|
+
/** The zero-logout bridge settings of one source. */
|
|
276
|
+
bridge: (source: MigrationSourceId | string) => {
|
|
277
|
+
get(): Promise<MigrationBridgeSettings>;
|
|
278
|
+
update(body: MigrationBridgeSettingsUpdate): Promise<MigrationBridgeSettings>;
|
|
279
|
+
delete(): Promise<{
|
|
280
|
+
object: "migration_bridge";
|
|
281
|
+
source: string;
|
|
282
|
+
deleted: true;
|
|
283
|
+
}>;
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrationsResource = migrationsResource;
|
|
4
|
+
const better_auth_imports_1 = require("./better-auth-imports");
|
|
5
|
+
const request_1 = require("./request");
|
|
6
|
+
const TERMINAL = ['ready', 'invalid', 'completed', 'failed'];
|
|
7
|
+
function migrationsResource(request) {
|
|
8
|
+
const importsFor = (source) => {
|
|
9
|
+
const base = `/v1/migrations/${(0, request_1.enc)(source)}/imports`;
|
|
10
|
+
const self = {
|
|
11
|
+
/** The import public key (created on first read; shared by every source). */
|
|
12
|
+
getPublicKey() {
|
|
13
|
+
return request({ method: 'GET', path: `${base}/public_key` });
|
|
14
|
+
},
|
|
15
|
+
/** Replace the import key; bundles sealed to the old one no longer finalize. */
|
|
16
|
+
rotatePublicKey() {
|
|
17
|
+
return request({ method: 'POST', path: `${base}/public_key/rotate` });
|
|
18
|
+
},
|
|
19
|
+
create(body = {}, idempotencyKey) {
|
|
20
|
+
return request({ method: 'POST', path: base, body, idempotencyKey });
|
|
21
|
+
},
|
|
22
|
+
list(params = {}) {
|
|
23
|
+
return request({ method: 'GET', path: base, query: { ...params } });
|
|
24
|
+
},
|
|
25
|
+
get(id) {
|
|
26
|
+
return request({ method: 'GET', path: `${base}/${(0, request_1.enc)(id)}` });
|
|
27
|
+
},
|
|
28
|
+
/** Upload part `part` (1-based) of the sealed bundle text. */
|
|
29
|
+
uploadPart(id, part, data) {
|
|
30
|
+
return request({ method: 'PUT', path: `${base}/${(0, request_1.enc)(id)}/parts/${part}`, body: { data } });
|
|
31
|
+
},
|
|
32
|
+
/** Close the upload; Atlas checks the key and the format, then runs the dry run. */
|
|
33
|
+
finalize(id) {
|
|
34
|
+
return request({ method: 'POST', path: `${base}/${(0, request_1.enc)(id)}/finalize` });
|
|
35
|
+
},
|
|
36
|
+
dryRun(id, body = {}) {
|
|
37
|
+
return request({ method: 'POST', path: `${base}/${(0, request_1.enc)(id)}/dry_run`, body });
|
|
38
|
+
},
|
|
39
|
+
/** Import (or resume). Pass confirm_conflicts when the dry run reported conflicts. */
|
|
40
|
+
apply(id, body = {}) {
|
|
41
|
+
return request({ method: 'POST', path: `${base}/${(0, request_1.enc)(id)}/apply`, body });
|
|
42
|
+
},
|
|
43
|
+
delete(id) {
|
|
44
|
+
return request({ method: 'DELETE', path: `${base}/${(0, request_1.enc)(id)}` });
|
|
45
|
+
},
|
|
46
|
+
/**
|
|
47
|
+
* Create an import (or continue `importId`), upload the sealed bundle text
|
|
48
|
+
* in parts from `resumeFrom` (1-based) and finalize it.
|
|
49
|
+
*/
|
|
50
|
+
async upload(bundleText, opts = {}) {
|
|
51
|
+
const parts = (0, better_auth_imports_1.splitBundleParts)(bundleText, opts.partBytes);
|
|
52
|
+
if (parts.length === 0)
|
|
53
|
+
throw new Error('The bundle is empty.');
|
|
54
|
+
const id = opts.importId ?? (await self.create(opts.options ? { options: opts.options } : {})).id;
|
|
55
|
+
for (let i = Math.max(0, (opts.resumeFrom ?? 1) - 1); i < parts.length; i++) {
|
|
56
|
+
await self.uploadPart(id, i + 1, parts[i]);
|
|
57
|
+
opts.onPart?.(i + 1, parts.length);
|
|
58
|
+
}
|
|
59
|
+
return self.finalize(id);
|
|
60
|
+
},
|
|
61
|
+
/** Poll until the import leaves analyzing / queued / applying. */
|
|
62
|
+
async waitFor(id, opts = {}) {
|
|
63
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
64
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 6 * 3600_000);
|
|
65
|
+
for (;;) {
|
|
66
|
+
const imp = await self.get(id);
|
|
67
|
+
opts.onProgress?.(imp);
|
|
68
|
+
if (TERMINAL.includes(imp.status) || imp.status === 'uploading')
|
|
69
|
+
return imp;
|
|
70
|
+
if (Date.now() > deadline)
|
|
71
|
+
throw new Error(`Timed out waiting for migration import ${id} (status ${imp.status}).`);
|
|
72
|
+
await sleep(opts.intervalMs ?? 2000);
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
return self;
|
|
77
|
+
};
|
|
78
|
+
const bridgeFor = (source) => {
|
|
79
|
+
const path = `/v1/migrations/${(0, request_1.enc)(source)}/bridge`;
|
|
80
|
+
return {
|
|
81
|
+
get() {
|
|
82
|
+
return request({ method: 'GET', path });
|
|
83
|
+
},
|
|
84
|
+
update(body) {
|
|
85
|
+
return request({ method: 'PUT', path, body });
|
|
86
|
+
},
|
|
87
|
+
delete() {
|
|
88
|
+
return request({ method: 'DELETE', path });
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
/** Every migration source and what it supports. */
|
|
94
|
+
sources() {
|
|
95
|
+
return request({ method: 'GET', path: '/v1/migrations/sources' });
|
|
96
|
+
},
|
|
97
|
+
/** The import surface of one source: `migrations.imports('auth0').upload(text)`. */
|
|
98
|
+
imports: importsFor,
|
|
99
|
+
/** The zero-logout bridge settings of one source. */
|
|
100
|
+
bridge: bridgeFor,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/client/migrations.ts"],"names":[],"mappings":";;AAkMA,gDAkGC;AApSD,+DAA0F;AAC1F,uCAAgD;AA+LhD,MAAM,QAAQ,GAAqC,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;AAE/F,SAAgB,kBAAkB,CAAC,OAAkB;IACnD,MAAM,UAAU,GAAG,CAAC,MAAkC,EAAE,EAAE;QACxD,MAAM,IAAI,GAAG,kBAAkB,IAAA,aAAG,EAAC,MAAM,CAAC,UAAU,CAAC;QACrD,MAAM,IAAI,GAAG;YACX,6EAA6E;YAC7E,YAAY;gBACV,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,aAAa,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,gFAAgF;YAChF,eAAe;gBACb,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,oBAAoB,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,MAAM,CAAC,OAA6C,EAAE,EAAE,cAAuB;gBAC7E,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;YACvE,CAAC;YACD,IAAI,CAAC,SAAuB,EAAE;gBAC5B,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;YACtE,CAAC;YACD,GAAG,CAAC,EAAU;gBACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,8DAA8D;YAC9D,UAAU,CAAC,EAAU,EAAE,IAAY,EAAE,IAAY;gBAC/C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAA,aAAG,EAAC,EAAE,CAAC,UAAU,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAC9F,CAAC;YACD,oFAAoF;YACpF,QAAQ,CAAC,EAAU;gBACjB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAA,aAAG,EAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YAC1E,CAAC;YACD,MAAM,CAAC,EAAU,EAAE,OAA6C,EAAE;gBAChE,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAA,aAAG,EAAC,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/E,CAAC;YACD,sFAAsF;YACtF,KAAK,CAAC,EAAU,EAAE,OAAwC,EAAE;gBAC1D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAA,aAAG,EAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7E,CAAC;YACD,MAAM,CAAC,EAAU;gBACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACnE,CAAC;YACD;;;eAGG;YACH,KAAK,CAAC,MAAM,CACV,UAAkB,EAClB,OAAmJ,EAAE;gBAErJ,MAAM,KAAK,GAAG,IAAA,sCAAgB,EAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;gBAChE,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClG,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC5E,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;oBAC5C,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBACrC,CAAC;gBACD,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;YACD,kEAAkE;YAClE,KAAK,CAAC,OAAO,CACX,EAAU,EACV,OAAwI,EAAE;gBAE1I,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC1F,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;gBAC/D,SAAS,CAAC;oBACR,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAC/B,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC;oBACvB,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW;wBAAE,OAAO,GAAG,CAAC;oBAC5E,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ;wBAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,EAAE,YAAY,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;oBACnH,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;SACF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,MAAkC,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,kBAAkB,IAAA,aAAG,EAAC,MAAM,CAAC,SAAS,CAAC;QACpD,OAAO;YACL,GAAG;gBACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1C,CAAC;YACD,MAAM,CAAC,IAAmC;gBACxC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,CAAC;YACD,MAAM;gBACJ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;IACF,OAAO;QACL,mDAAmD;QACnD,OAAO;YACL,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,oFAAoF;QACpF,OAAO,EAAE,UAAU;QACnB,qDAAqD;QACrD,MAAM,EAAE,SAAS;KAClB,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
|