@atlasauth/cli 0.10.0 → 0.12.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 +14 -0
- package/dist/args.d.ts +145 -0
- package/dist/args.js +53 -0
- package/dist/args.js.map +1 -1
- package/dist/commands/admin.d.ts +49 -0
- package/dist/commands/admin.js +353 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/id-accounts.d.ts +13 -0
- package/dist/commands/id-accounts.js +195 -0
- package/dist/commands/id-accounts.js.map +1 -0
- package/dist/commands/init.js +13 -8
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate.d.ts +6 -2
- package/dist/commands/migrate.js +13 -3
- package/dist/commands/migrate.js.map +1 -1
- package/dist/config-http.d.ts +2 -0
- package/dist/config-http.js +1 -0
- package/dist/config-http.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +1 -0
- package/dist/context.js +1 -1
- package/dist/context.js.map +1 -1
- package/dist/help.d.ts +1 -1
- package/dist/help.js +99 -0
- package/dist/help.js.map +1 -1
- package/dist/migrate/auth0/plugin.d.ts +2 -0
- package/dist/migrate/auth0/plugin.js +126 -0
- package/dist/migrate/auth0/plugin.js.map +1 -0
- package/dist/migrate/clerk/plugin.d.ts +2 -0
- package/dist/migrate/clerk/plugin.js +76 -0
- package/dist/migrate/clerk/plugin.js.map +1 -0
- package/dist/migrate/descope/plugin.d.ts +2 -0
- package/dist/migrate/descope/plugin.js +83 -0
- package/dist/migrate/descope/plugin.js.map +1 -0
- package/dist/migrate/export/auth0-config.d.ts +29 -0
- package/dist/migrate/export/auth0-config.js +249 -0
- package/dist/migrate/export/auth0-config.js.map +1 -0
- package/dist/migrate/export/auth0.d.ts +62 -0
- package/dist/migrate/export/auth0.js +575 -0
- package/dist/migrate/export/auth0.js.map +1 -0
- package/dist/migrate/export/clerk-config.d.ts +26 -0
- package/dist/migrate/export/clerk-config.js +227 -0
- package/dist/migrate/export/clerk-config.js.map +1 -0
- package/dist/migrate/export/clerk.d.ts +46 -0
- package/dist/migrate/export/clerk.js +486 -0
- package/dist/migrate/export/clerk.js.map +1 -0
- package/dist/migrate/export/descope.d.ts +35 -0
- package/dist/migrate/export/descope.js +208 -0
- package/dist/migrate/export/descope.js.map +1 -0
- package/dist/migrate/export/fake-vendor.test-helper.d.ts +27 -0
- package/dist/migrate/export/fake-vendor.test-helper.js +41 -0
- package/dist/migrate/export/fake-vendor.test-helper.js.map +1 -0
- package/dist/migrate/export/frameworks/app-users.d.ts +42 -0
- package/dist/migrate/export/frameworks/app-users.js +161 -0
- package/dist/migrate/export/frameworks/app-users.js.map +1 -0
- package/dist/migrate/export/frameworks/authjs.d.ts +41 -0
- package/dist/migrate/export/frameworks/authjs.js +146 -0
- package/dist/migrate/export/frameworks/authjs.js.map +1 -0
- package/dist/migrate/export/frameworks/devise.d.ts +39 -0
- package/dist/migrate/export/frameworks/devise.js +218 -0
- package/dist/migrate/export/frameworks/devise.js.map +1 -0
- package/dist/migrate/export/frameworks/django.d.ts +45 -0
- package/dist/migrate/export/frameworks/django.js +315 -0
- package/dist/migrate/export/frameworks/django.js.map +1 -0
- package/dist/migrate/export/frameworks/lucia.d.ts +42 -0
- package/dist/migrate/export/frameworks/lucia.js +263 -0
- package/dist/migrate/export/frameworks/lucia.js.map +1 -0
- package/dist/migrate/export/frameworks/tables.d.ts +90 -0
- package/dist/migrate/export/frameworks/tables.js +325 -0
- package/dist/migrate/export/frameworks/tables.js.map +1 -0
- package/dist/migrate/export/frameworks/webauthn.d.ts +25 -0
- package/dist/migrate/export/frameworks/webauthn.js +130 -0
- package/dist/migrate/export/frameworks/webauthn.js.map +1 -0
- package/dist/migrate/export/kinde-descope-config.d.ts +38 -0
- package/dist/migrate/export/kinde-descope-config.js +172 -0
- package/dist/migrate/export/kinde-descope-config.js.map +1 -0
- package/dist/migrate/export/kinde.d.ts +57 -0
- package/dist/migrate/export/kinde.js +333 -0
- package/dist/migrate/export/kinde.js.map +1 -0
- package/dist/migrate/export/okta-config.d.ts +30 -0
- package/dist/migrate/export/okta-config.js +205 -0
- package/dist/migrate/export/okta-config.js.map +1 -0
- package/dist/migrate/export/okta.d.ts +43 -0
- package/dist/migrate/export/okta.js +337 -0
- package/dist/migrate/export/okta.js.map +1 -0
- package/dist/migrate/export/plugin-kit.d.ts +25 -0
- package/dist/migrate/export/plugin-kit.js +82 -0
- package/dist/migrate/export/plugin-kit.js.map +1 -0
- package/dist/migrate/export/record-set.d.ts +44 -0
- package/dist/migrate/export/record-set.js +98 -0
- package/dist/migrate/export/record-set.js.map +1 -0
- package/dist/migrate/export/translate-kit.d.ts +46 -0
- package/dist/migrate/export/translate-kit.js +148 -0
- package/dist/migrate/export/translate-kit.js.map +1 -0
- package/dist/migrate/export/vendor-http.d.ts +46 -0
- package/dist/migrate/export/vendor-http.js +138 -0
- package/dist/migrate/export/vendor-http.js.map +1 -0
- package/dist/migrate/export/zip.d.ts +8 -0
- package/dist/migrate/export/zip.js +66 -0
- package/dist/migrate/export/zip.js.map +1 -0
- package/dist/migrate/framework/builtins.d.ts +2 -0
- package/dist/migrate/framework/builtins.js +23 -0
- package/dist/migrate/framework/builtins.js.map +1 -0
- package/dist/migrate/framework/commands.d.ts +20 -0
- package/dist/migrate/framework/commands.js +58 -0
- package/dist/migrate/framework/commands.js.map +1 -0
- package/dist/migrate/framework/custom.d.ts +12 -0
- package/dist/migrate/framework/custom.js +96 -0
- package/dist/migrate/framework/custom.js.map +1 -0
- package/dist/migrate/framework/orchestrator.d.ts +113 -0
- package/dist/migrate/framework/orchestrator.js +531 -0
- package/dist/migrate/framework/orchestrator.js.map +1 -0
- package/dist/migrate/framework/plugin.d.ts +165 -0
- package/dist/migrate/framework/plugin.js +3 -0
- package/dist/migrate/framework/plugin.js.map +1 -0
- package/dist/migrate/framework/registry.d.ts +11 -0
- package/dist/migrate/framework/registry.js +44 -0
- package/dist/migrate/framework/registry.js.map +1 -0
- package/dist/migrate/framework/report.d.ts +17 -0
- package/dist/migrate/framework/report.js +103 -0
- package/dist/migrate/framework/report.js.map +1 -0
- package/dist/migrate/frameworks/plugins.d.ts +29 -0
- package/dist/migrate/frameworks/plugins.js +402 -0
- package/dist/migrate/frameworks/plugins.js.map +1 -0
- package/dist/migrate/frameworks/report.d.ts +92 -0
- package/dist/migrate/frameworks/report.js +207 -0
- package/dist/migrate/frameworks/report.js.map +1 -0
- package/dist/migrate/frameworks/translate-js.d.ts +5 -0
- package/dist/migrate/frameworks/translate-js.js +503 -0
- package/dist/migrate/frameworks/translate-js.js.map +1 -0
- package/dist/migrate/frameworks/translate-rails-django.d.ts +3 -0
- package/dist/migrate/frameworks/translate-rails-django.js +1391 -0
- package/dist/migrate/frameworks/translate-rails-django.js.map +1 -0
- package/dist/migrate/kinde/plugin.d.ts +2 -0
- package/dist/migrate/kinde/plugin.js +105 -0
- package/dist/migrate/kinde/plugin.js.map +1 -0
- package/dist/migrate/okta/plugin.d.ts +2 -0
- package/dist/migrate/okta/plugin.js +105 -0
- package/dist/migrate/okta/plugin.js.map +1 -0
- package/dist/project.d.ts +1 -0
- package/dist/project.js.map +1 -1
- package/dist/run.js +4 -0
- package/dist/run.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TranslationResult } from '../framework/plugin';
|
|
2
|
+
import { type Obj } from './record-set';
|
|
3
|
+
import { type VendorHttp } from './vendor-http';
|
|
4
|
+
/**
|
|
5
|
+
* `atlas migrate kinde config` — what Kinde's Management API exposes:
|
|
6
|
+
* applications (callback and logout URLs), connections (social and
|
|
7
|
+
* enterprise), roles and permissions, and registered APIs. Kinde does not
|
|
8
|
+
* expose its authentication settings (password, MFA, session lifetimes) by
|
|
9
|
+
* API: the report lists them as manual, with where to find them.
|
|
10
|
+
*/
|
|
11
|
+
export interface KindeConfigSnapshot {
|
|
12
|
+
domain: string;
|
|
13
|
+
applications: Array<Obj & {
|
|
14
|
+
redirects?: string[];
|
|
15
|
+
}>;
|
|
16
|
+
connections: Obj[];
|
|
17
|
+
roles: Array<Obj & {
|
|
18
|
+
permissions?: Obj[];
|
|
19
|
+
}>;
|
|
20
|
+
permissions: Obj[];
|
|
21
|
+
apis: Obj[];
|
|
22
|
+
}
|
|
23
|
+
export declare function fetchKindeConfig(http: VendorHttp, domain: string): Promise<KindeConfigSnapshot>;
|
|
24
|
+
export declare function translateKindeConfig(snap: KindeConfigSnapshot): TranslationResult;
|
|
25
|
+
/**
|
|
26
|
+
* `atlas migrate descope config` — a Descope project's password settings,
|
|
27
|
+
* roles and permissions (management key, on this machine). Flows, connectors
|
|
28
|
+
* and styles are Descope-specific: reported as manual. Tenant SSO moves with
|
|
29
|
+
* the data export.
|
|
30
|
+
*/
|
|
31
|
+
export interface DescopeConfigSnapshot {
|
|
32
|
+
projectId: string;
|
|
33
|
+
passwordSettings: Obj | null;
|
|
34
|
+
roles: Obj[];
|
|
35
|
+
permissions: Obj[];
|
|
36
|
+
}
|
|
37
|
+
export declare function fetchDescopeConfig(http: VendorHttp, projectId: string): Promise<DescopeConfigSnapshot>;
|
|
38
|
+
export declare function translateDescopeConfig(snap: DescopeConfigSnapshot): TranslationResult;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchKindeConfig = fetchKindeConfig;
|
|
4
|
+
exports.translateKindeConfig = translateKindeConfig;
|
|
5
|
+
exports.fetchDescopeConfig = fetchDescopeConfig;
|
|
6
|
+
exports.translateDescopeConfig = translateDescopeConfig;
|
|
7
|
+
const record_set_1 = require("./record-set");
|
|
8
|
+
const translate_kit_1 = require("./translate-kit");
|
|
9
|
+
const vendor_http_1 = require("./vendor-http");
|
|
10
|
+
async function optional(fn, fallback) {
|
|
11
|
+
try {
|
|
12
|
+
return await fn();
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
if (err instanceof vendor_http_1.VendorApiError && [400, 403, 404].includes(err.status))
|
|
16
|
+
return fallback;
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function fetchKindeConfig(http, domain) {
|
|
21
|
+
const list = (path, key) => optional(async () => (0, record_set_1.objs)((await http.get(path)).body?.[key]), []);
|
|
22
|
+
const applications = (await list('/applications?page_size=500', 'applications'));
|
|
23
|
+
for (const a of applications) {
|
|
24
|
+
const raw = await optional(async () => (await http.get(`/applications/${(0, record_set_1.str)(a.id)}/auth_redirect_urls`)).body?.redirect_urls, undefined);
|
|
25
|
+
const urls = Array.isArray(raw) ? raw : [];
|
|
26
|
+
a.redirects = urls.map((u) => (typeof u === 'string' ? u : (0, record_set_1.isObj)(u) ? ((0, record_set_1.str)(u.redirect_url) ?? (0, record_set_1.str)(u.url)) : undefined)).filter((u) => !!u);
|
|
27
|
+
}
|
|
28
|
+
const roles = (await list('/roles?page_size=500', 'roles'));
|
|
29
|
+
for (const r of roles)
|
|
30
|
+
r.permissions = await list(`/roles/${(0, record_set_1.str)(r.id)}/permissions?page_size=500`, 'permissions');
|
|
31
|
+
return {
|
|
32
|
+
domain,
|
|
33
|
+
applications,
|
|
34
|
+
connections: await list('/connections?page_size=500', 'connections'),
|
|
35
|
+
roles,
|
|
36
|
+
permissions: await list('/permissions?page_size=500', 'permissions'),
|
|
37
|
+
apis: await list('/apis', 'apis'),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function translateKindeConfig(snap) {
|
|
41
|
+
const b = new translate_kit_1.ConfigBuilder();
|
|
42
|
+
for (const c of snap.connections) {
|
|
43
|
+
const strategy = (0, record_set_1.str)(c.strategy) ?? '';
|
|
44
|
+
const name = (0, record_set_1.str)(c.display_name) ?? (0, record_set_1.str)(c.name) ?? strategy;
|
|
45
|
+
if (strategy === 'email:password' || strategy === 'username:password') {
|
|
46
|
+
b.set('strategies.password', true);
|
|
47
|
+
if (strategy === 'username:password')
|
|
48
|
+
b.set('strategies.username', true);
|
|
49
|
+
b.add('mapped', 'authentication', `connection ${name}`, 'Password sign-in; hashes move with Kinde\'s "All data" export.', 'auth_config.strategies.password');
|
|
50
|
+
}
|
|
51
|
+
else if (strategy === 'email:otp' || strategy === 'username:otp') {
|
|
52
|
+
b.set('strategies.emailCode', true);
|
|
53
|
+
b.add('mapped', 'authentication', `connection ${name}`, 'Passwordless email code.', 'auth_config.strategies.emailCode');
|
|
54
|
+
}
|
|
55
|
+
else if (strategy === 'phone:otp') {
|
|
56
|
+
b.set('strategies.phoneCode', true);
|
|
57
|
+
b.add('mapped', 'authentication', `connection ${name}`, 'SMS code.', 'auth_config.strategies.phoneCode');
|
|
58
|
+
}
|
|
59
|
+
else if (/^(saml|wsfed|oauth2:(azure_ad|microsoft_entra))/.test(strategy)) {
|
|
60
|
+
b.add('mapped', 'enterprise', `connection ${name} (${strategy})`, 'Moves with the data export as an Atlas SSO connection (add the client secret / confirm the certificate after the import).', 'sso_connections');
|
|
61
|
+
}
|
|
62
|
+
else if (strategy.startsWith('oauth2:')) {
|
|
63
|
+
const key = (0, translate_kit_1.socialKey)(strategy);
|
|
64
|
+
if (key)
|
|
65
|
+
b.socialProvider({ atlasKey: key, vendorName: name, area: 'authentication', setting: `connection ${name} (${strategy})` });
|
|
66
|
+
else
|
|
67
|
+
b.add('manual', 'authentication', `connection ${name} (${strategy})`, 'No built-in Atlas provider: add it as a custom OAuth provider.', 'custom_oauth_providers');
|
|
68
|
+
}
|
|
69
|
+
else if (strategy) {
|
|
70
|
+
b.add('manual', 'authentication', `connection ${name} (${strategy})`, 'Review this connection by hand.');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const redirects = new Set();
|
|
74
|
+
for (const a of snap.applications)
|
|
75
|
+
for (const u of a.redirects ?? [])
|
|
76
|
+
redirects.add(u);
|
|
77
|
+
for (const url of redirects)
|
|
78
|
+
b.push('redirect_urls', { url });
|
|
79
|
+
if (redirects.size)
|
|
80
|
+
b.add('mapped', 'applications', 'allowed callback URLs', `${redirects.size} callback URL(s).`, 'redirect_urls');
|
|
81
|
+
for (const a of snap.applications)
|
|
82
|
+
if ((0, record_set_1.str)(a.type) === 'm2m')
|
|
83
|
+
b.add('manual', `applications ${(0, record_set_1.str)(a.name) ?? (0, record_set_1.str)(a.id)}`, 'type m2m', 'Machine-to-machine application: create an Atlas M2M client.', 'oauth_clients');
|
|
84
|
+
for (const p of snap.permissions) {
|
|
85
|
+
const key = (0, record_set_1.str)(p.key);
|
|
86
|
+
if (key)
|
|
87
|
+
b.push('permissions', { key, name: (0, record_set_1.str)(p.name) ?? key, description: (0, record_set_1.str)(p.description) ?? '' });
|
|
88
|
+
}
|
|
89
|
+
for (const r of snap.roles) {
|
|
90
|
+
const key = (0, record_set_1.str)(r.key);
|
|
91
|
+
if (!key)
|
|
92
|
+
continue;
|
|
93
|
+
const atlasKey = `org:${(0, translate_kit_1.keyOf)(key.replace(/^org:/, ''))}`;
|
|
94
|
+
b.roles[key] = atlasKey;
|
|
95
|
+
b.push('roles', { key: atlasKey, name: (0, record_set_1.str)(r.name) ?? key, description: (0, record_set_1.str)(r.description) ?? '', permissions: (r.permissions ?? []).map((p) => (0, record_set_1.str)(p.key)).filter((p) => !!p) });
|
|
96
|
+
}
|
|
97
|
+
if (snap.roles.length)
|
|
98
|
+
b.add('mapped', 'roles', 'roles', `${snap.roles.length} organization role(s) with permissions (Kinde roles apply inside organizations).`, 'roles');
|
|
99
|
+
for (const api of snap.apis) {
|
|
100
|
+
const audience = (0, record_set_1.str)(api.audience);
|
|
101
|
+
if (audience && !audience.endsWith('/api')) {
|
|
102
|
+
b.push('resource_servers', { identifier: audience, name: (0, record_set_1.str)(api.name) ?? audience, scopes: [] });
|
|
103
|
+
b.add('mapped', 'APIs', `apis ${(0, record_set_1.str)(api.name) ?? audience}`, `Access tokens keep "aud": "${audience}".`, `resource_servers ${audience}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
for (const [setting, where] of [
|
|
107
|
+
['multi-factor authentication', 'Settings → Environment → Multi-factor auth'],
|
|
108
|
+
['password rules and breached-password checks', 'Settings → Environment → Authentication'],
|
|
109
|
+
['session and token lifetimes', 'Applications → <app> → Tokens'],
|
|
110
|
+
['feature flags', 'Feature flags (no Atlas counterpart: keep them in your own flag service)'],
|
|
111
|
+
]) {
|
|
112
|
+
b.add('manual', 'settings not in the API', setting, `Kinde does not expose this by API; copy it from Kinde (${where}).`);
|
|
113
|
+
}
|
|
114
|
+
return b.result(`Kinde business ${snap.domain}`, { bridge: { preset: 'kinde', vars: { domain: snap.domain } } });
|
|
115
|
+
}
|
|
116
|
+
async function fetchDescopeConfig(http, projectId) {
|
|
117
|
+
return {
|
|
118
|
+
projectId,
|
|
119
|
+
passwordSettings: await optional(async () => (await http.get('/v1/mgmt/password/settings')).body ?? null, null),
|
|
120
|
+
roles: await optional(async () => (0, record_set_1.objs)((await http.get('/v1/mgmt/role/all')).body?.roles), []),
|
|
121
|
+
permissions: await optional(async () => (0, record_set_1.objs)((await http.get('/v1/mgmt/permission/all')).body?.permissions), []),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function translateDescopeConfig(snap) {
|
|
125
|
+
const b = new translate_kit_1.ConfigBuilder();
|
|
126
|
+
const pw = snap.passwordSettings;
|
|
127
|
+
if (pw && (0, record_set_1.isObj)(pw)) {
|
|
128
|
+
b.set('strategies.password', pw.enabled !== false);
|
|
129
|
+
b.add('mapped', 'password', 'enabled', pw.enabled === false ? 'Password sign-in off.' : 'Password sign-in. Descope keeps hashes (Argon2id) unless its support exports them: the descope lazy-migration preset moves each password on first sign-in.', 'auth_config.strategies.password');
|
|
130
|
+
if (typeof pw.minLength === 'number') {
|
|
131
|
+
b.set('passwordPolicy.minLength', Math.max(8, pw.minLength));
|
|
132
|
+
b.add(pw.minLength < 8 ? 'differs' : 'mapped', 'password', 'minLength', `${pw.minLength}${pw.minLength < 8 ? ' (Atlas requires at least 8)' : ''}.`, 'auth_config.passwordPolicy.minLength');
|
|
133
|
+
}
|
|
134
|
+
if (['lowercase', 'uppercase', 'number', 'nonAlphanumeric'].some((k) => pw[k] === true))
|
|
135
|
+
b.add('differs', 'password', 'character classes', 'Atlas follows NIST 800-63B (length and breached-password checks, no character-class rules).', 'auth_config.passwordPolicy');
|
|
136
|
+
if (pw.expiration === true)
|
|
137
|
+
b.add('manual', 'password', 'expiration', 'Atlas does not expire passwords.');
|
|
138
|
+
if (pw.reuse === true)
|
|
139
|
+
b.add('manual', 'password', 'reuse', 'Atlas does not keep a password history.');
|
|
140
|
+
if (pw.lock === true)
|
|
141
|
+
b.add('mapped', 'password', 'lock', `Descope locks after ${pw.lockAttempts ?? '?'} attempts; Atlas throttles failed sign-ins per account and IP.`, 'auth_config.rateLimit');
|
|
142
|
+
}
|
|
143
|
+
for (const p of snap.permissions) {
|
|
144
|
+
const name = (0, record_set_1.str)(p.name);
|
|
145
|
+
if (name)
|
|
146
|
+
b.push('permissions', { key: (0, translate_kit_1.keyOf)(name), name, description: (0, record_set_1.str)(p.description) ?? '' });
|
|
147
|
+
}
|
|
148
|
+
const seen = new Set();
|
|
149
|
+
for (const r of snap.roles) {
|
|
150
|
+
const name = (0, record_set_1.str)(r.name);
|
|
151
|
+
if (!name || (0, record_set_1.str)(r.tenantId))
|
|
152
|
+
continue;
|
|
153
|
+
const key = (0, translate_kit_1.keyOf)(name);
|
|
154
|
+
if (seen.has(key))
|
|
155
|
+
continue;
|
|
156
|
+
seen.add(key);
|
|
157
|
+
b.roles[name] = key;
|
|
158
|
+
b.push('roles', { key, name, description: (0, record_set_1.str)(r.description) ?? '', permissions: (0, record_set_1.strs)(r.permissionNames).map(translate_kit_1.keyOf) });
|
|
159
|
+
}
|
|
160
|
+
if (seen.size)
|
|
161
|
+
b.add('mapped', 'authorization', 'roles', `${seen.size} role(s) (project roles become app roles; the same keys seat tenant members).`, 'roles');
|
|
162
|
+
const tenantRoles = snap.roles.filter((r) => (0, record_set_1.str)(r.tenantId)).length;
|
|
163
|
+
if (tenantRoles)
|
|
164
|
+
b.add('differs', 'authorization', 'tenant-scoped roles', `${tenantRoles} role(s) defined inside one tenant: they move with the data export as that organization's custom roles.`, 'roles');
|
|
165
|
+
b.add('manual', 'flows', 'flows and screens', 'Descope flows (sign-up-or-in, step-up, MFA screens) are replaced by Atlas\'s hosted pages and components; recreate custom steps (forms, connectors) as Atlas actions.', 'actions');
|
|
166
|
+
b.add('manual', 'authentication methods', 'magic link / OTP / social / passkeys', 'Descope does not expose its enabled authentication methods by API: turn the same ones on in Atlas (strategies, oauth_providers).', 'auth_config.strategies');
|
|
167
|
+
return b.result(`Descope project ${snap.projectId}`, {
|
|
168
|
+
bridge: { preset: 'descope', vars: { project_id: snap.projectId } },
|
|
169
|
+
lazy: { preset: 'descope', config: { project_id: snap.projectId } },
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=kinde-descope-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kinde-descope-config.js","sourceRoot":"","sources":["../../../src/migrate/export/kinde-descope-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { PasswordHash, UserRecord } from '@atlasauth/migrate';
|
|
2
|
+
import { RecordSet, type Obj } from './record-set';
|
|
3
|
+
/**
|
|
4
|
+
* `atlas migrate export kinde` — Kinde onto the canonical bundle models.
|
|
5
|
+
*
|
|
6
|
+
* Two sources, merged by Kinde user id (`kp_…`):
|
|
7
|
+
* - Kinde's DATA EXPORT (Settings → Business → Details → Export data). Choose
|
|
8
|
+
* "All data" to include password hashes (owners approve it; the file is
|
|
9
|
+
* available once). It downloads as an AES-256-CTR encrypted `.dat` with a
|
|
10
|
+
* Key and IV shown at download; this command decrypts it locally, or takes
|
|
11
|
+
* the already decrypted zip / `users.ndjson`. Each user carries
|
|
12
|
+
* `password: { hashed_password, hashing_algorithm, hashing_config }`;
|
|
13
|
+
* - the Management API (a machine-to-machine application's client id +
|
|
14
|
+
* secret, on this machine): organizations with their members and roles,
|
|
15
|
+
* roles with permissions, and enterprise connections.
|
|
16
|
+
*
|
|
17
|
+
* Kinde has no password-verifying API (no password grant), so there is no
|
|
18
|
+
* lazy migration from Kinde: the data export is the way passwords move.
|
|
19
|
+
* Kinde does not export second-factor secrets; users re-enrol. Sessions are
|
|
20
|
+
* Kinde-issued JWTs, bridged by the `kinde` bridge preset.
|
|
21
|
+
*/
|
|
22
|
+
export interface KindeExportOptions {
|
|
23
|
+
/** `https://acme.kinde.com` (KINDE_ISSUER_URL / KINDE_DOMAIN). */
|
|
24
|
+
domain?: string;
|
|
25
|
+
clientId?: string;
|
|
26
|
+
clientSecret?: string;
|
|
27
|
+
/** The encrypted `.dat` export, with the Key and IV Kinde showed at download (hex). */
|
|
28
|
+
encryptedExport?: {
|
|
29
|
+
data: Buffer;
|
|
30
|
+
key: string;
|
|
31
|
+
iv: string;
|
|
32
|
+
};
|
|
33
|
+
/** The decrypted export zip. */
|
|
34
|
+
zip?: Buffer;
|
|
35
|
+
/** `users.ndjson` text, when extracted already. */
|
|
36
|
+
usersNdjson?: string;
|
|
37
|
+
organizationsNdjson?: string;
|
|
38
|
+
/** Include Kinde's default organization (every user is a member of it). */
|
|
39
|
+
includeDefaultOrganization?: boolean;
|
|
40
|
+
fetchImpl?: typeof fetch;
|
|
41
|
+
sleep?: (ms: number) => Promise<void>;
|
|
42
|
+
onProgress?: (message: string) => void;
|
|
43
|
+
}
|
|
44
|
+
/** AES-256-CTR, the scheme of Kinde's `.dat` export (`openssl aes-256-ctr -d -nosalt -K <key> -iv <iv>`). */
|
|
45
|
+
export declare function decryptKindeExport(data: Buffer, keyHex: string, ivHex: string): Buffer;
|
|
46
|
+
export declare function exportKinde(opts: KindeExportOptions): Promise<RecordSet>;
|
|
47
|
+
/** One Kinde user (export row and/or API row) → a user record. */
|
|
48
|
+
export declare function mapKindeUser(u: Obj, set?: RecordSet): UserRecord | null;
|
|
49
|
+
/**
|
|
50
|
+
* Kinde's exported `password` object → the bundle's password hash. Kinde
|
|
51
|
+
* stores bcrypt; users imported into Kinde keep the algorithm they came with
|
|
52
|
+
* (crypt, md5, sha256, wordpress, pbkdf2, firebase-scrypt, aspnet-identity-v2).
|
|
53
|
+
*/
|
|
54
|
+
export declare function kindePasswordHash(p: Obj): PasswordHash | {
|
|
55
|
+
reason: string;
|
|
56
|
+
};
|
|
57
|
+
export declare function m2mToken(base: string, opts: KindeExportOptions): Promise<string>;
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decryptKindeExport = decryptKindeExport;
|
|
4
|
+
exports.exportKinde = exportKinde;
|
|
5
|
+
exports.mapKindeUser = mapKindeUser;
|
|
6
|
+
exports.kindePasswordHash = kindePasswordHash;
|
|
7
|
+
exports.m2mToken = m2mToken;
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const record_set_1 = require("./record-set");
|
|
10
|
+
const vendor_http_1 = require("./vendor-http");
|
|
11
|
+
const zip_1 = require("./zip");
|
|
12
|
+
/** AES-256-CTR, the scheme of Kinde's `.dat` export (`openssl aes-256-ctr -d -nosalt -K <key> -iv <iv>`). */
|
|
13
|
+
function decryptKindeExport(data, keyHex, ivHex) {
|
|
14
|
+
const key = Buffer.from(keyHex.trim(), 'hex');
|
|
15
|
+
const iv = Buffer.from(ivHex.trim(), 'hex');
|
|
16
|
+
if (key.length !== 32)
|
|
17
|
+
throw new Error('The Kinde export Key must be 64 hex characters (AES-256).');
|
|
18
|
+
if (iv.length !== 16)
|
|
19
|
+
throw new Error('The Kinde export Initialization Vector must be 32 hex characters.');
|
|
20
|
+
const d = (0, node_crypto_1.createDecipheriv)('aes-256-ctr', key, iv);
|
|
21
|
+
return Buffer.concat([d.update(data), d.final()]);
|
|
22
|
+
}
|
|
23
|
+
async function exportKinde(opts) {
|
|
24
|
+
const set = new record_set_1.RecordSet();
|
|
25
|
+
const progress = opts.onProgress ?? (() => undefined);
|
|
26
|
+
// ── the data export (users + passwords) ──
|
|
27
|
+
let usersText = opts.usersNdjson;
|
|
28
|
+
let orgsText = opts.organizationsNdjson;
|
|
29
|
+
if (opts.encryptedExport || opts.zip) {
|
|
30
|
+
const zip = opts.zip ?? decryptKindeExport(opts.encryptedExport.data, opts.encryptedExport.key, opts.encryptedExport.iv);
|
|
31
|
+
if (zip.readUInt32LE(0) !== 0x04034b50)
|
|
32
|
+
throw new Error('The decrypted Kinde export is not a zip: check the Key and IV.');
|
|
33
|
+
const files = (0, zip_1.readZip)(zip);
|
|
34
|
+
usersText ??= (0, zip_1.zipFile)(files, 'users.ndjson')?.toString('utf8');
|
|
35
|
+
orgsText ??= (0, zip_1.zipFile)(files, 'organizations.ndjson')?.toString('utf8');
|
|
36
|
+
if (usersText === undefined)
|
|
37
|
+
throw new Error('The Kinde export has no users.ndjson.');
|
|
38
|
+
}
|
|
39
|
+
const exported = usersText !== undefined ? ndjson(usersText) : [];
|
|
40
|
+
const online = Boolean(opts.domain && opts.clientId && opts.clientSecret);
|
|
41
|
+
if (!online && usersText === undefined) {
|
|
42
|
+
throw new Error('Kinde export needs the data export file (with its Key and IV) and/or a machine-to-machine application (domain, client id, secret).');
|
|
43
|
+
}
|
|
44
|
+
const base = opts.domain ? `https://${opts.domain.replace(/^https?:\/\//, '').replace(/\/+$/, '')}` : '';
|
|
45
|
+
let token;
|
|
46
|
+
const http = new vendor_http_1.VendorHttp({
|
|
47
|
+
vendor: 'Kinde',
|
|
48
|
+
baseUrl: `${base}/api/v1`,
|
|
49
|
+
headers: async () => ({ authorization: `Bearer ${(token ??= await m2mToken(base, opts))}` }),
|
|
50
|
+
fetchImpl: opts.fetchImpl,
|
|
51
|
+
sleep: opts.sleep,
|
|
52
|
+
});
|
|
53
|
+
// ── organizations ──
|
|
54
|
+
progress('organizations');
|
|
55
|
+
const orgCodes = new Set();
|
|
56
|
+
let defaultOrg;
|
|
57
|
+
const orgRows = online ? await tokenAll(http, '/organizations?page_size=500', 'organizations') : orgsText ? ndjson(orgsText) : [];
|
|
58
|
+
for (const o of orgRows) {
|
|
59
|
+
const code = (0, record_set_1.str)(o.code) ?? (0, record_set_1.str)(o.organization_code);
|
|
60
|
+
const name = (0, record_set_1.str)(o.name);
|
|
61
|
+
if (!code || !name)
|
|
62
|
+
continue;
|
|
63
|
+
// The API flags it; the export file does not, so it is known there by Kinde's default name.
|
|
64
|
+
if (o.is_default === true || (o.is_default === undefined && name === 'Default Organization'))
|
|
65
|
+
defaultOrg = code;
|
|
66
|
+
if (code === defaultOrg && !opts.includeDefaultOrganization)
|
|
67
|
+
continue;
|
|
68
|
+
orgCodes.add(code);
|
|
69
|
+
set.add('organization', (0, record_set_1.compact)({ id: code, name, slug: (0, record_set_1.str)(o.handle), created_at: (0, record_set_1.str)(o.created_on) }));
|
|
70
|
+
}
|
|
71
|
+
if (defaultOrg && !opts.includeDefaultOrganization) {
|
|
72
|
+
set.warn(`Kinde's default organization (${defaultOrg}) holds every user and was not exported as an organization (pass --kinde-include-default-org to keep it).`);
|
|
73
|
+
}
|
|
74
|
+
// ── roles ──
|
|
75
|
+
const roleById = new Map();
|
|
76
|
+
if (online) {
|
|
77
|
+
progress('roles');
|
|
78
|
+
for (const r of await tokenAll(http, '/roles?page_size=500', 'roles')) {
|
|
79
|
+
const id = (0, record_set_1.str)(r.id);
|
|
80
|
+
const key = (0, record_set_1.str)(r.key);
|
|
81
|
+
if (!id || !key)
|
|
82
|
+
continue;
|
|
83
|
+
roleById.set(id, key);
|
|
84
|
+
const permissions = (await tokenAll(http, `/roles/${id}/permissions?page_size=500`, 'permissions')).map((p) => (0, record_set_1.str)(p.key)).filter((p) => !!p);
|
|
85
|
+
set.add('role', (0, record_set_1.compact)({ key, name: (0, record_set_1.str)(r.name), description: (0, record_set_1.str)(r.description), scope: 'organization', permissions }), key);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// ── users: the export (with passwords) first, the API fills the rest ──
|
|
89
|
+
progress('users');
|
|
90
|
+
const users = new Map();
|
|
91
|
+
for (const u of exported)
|
|
92
|
+
if ((0, record_set_1.str)(u.id))
|
|
93
|
+
users.set(u.id, u);
|
|
94
|
+
if (online) {
|
|
95
|
+
for (const u of await tokenAll(http, '/users?page_size=500&expand=organizations,identities', 'users')) {
|
|
96
|
+
const id = (0, record_set_1.str)(u.id);
|
|
97
|
+
if (!id)
|
|
98
|
+
continue;
|
|
99
|
+
users.set(id, { ...u, ...(users.get(id) ?? {}) });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
let withPassword = 0;
|
|
103
|
+
for (const u of users.values()) {
|
|
104
|
+
const user = mapKindeUser(u, set);
|
|
105
|
+
if (!user) {
|
|
106
|
+
set.omit('user', 'no email, phone number or username');
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (user.password)
|
|
110
|
+
withPassword++;
|
|
111
|
+
set.add('user', user);
|
|
112
|
+
// Without API access, memberships come from the export's organization codes.
|
|
113
|
+
if (!online) {
|
|
114
|
+
for (const code of (0, record_set_1.strs)(u.organizations)) {
|
|
115
|
+
if (orgCodes.has(code))
|
|
116
|
+
set.add('membership', { organization_id: code, user_id: user.id, role: 'member' }, `${code}:${user.id}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (exported.length === 0) {
|
|
121
|
+
set.warn('No data export given: password hashes come only from Kinde\'s data export ("All data"). Without them users set a new password (Kinde has no API to verify one).');
|
|
122
|
+
}
|
|
123
|
+
else if (withPassword === 0) {
|
|
124
|
+
set.warn('The data export has no passwords: request "All data" (not "All data except passwords") to carry them.');
|
|
125
|
+
}
|
|
126
|
+
// ── memberships with roles ──
|
|
127
|
+
if (online) {
|
|
128
|
+
progress('organization members');
|
|
129
|
+
const userIds = new Set(set.list('user').map((u) => u.id));
|
|
130
|
+
for (const code of orgCodes) {
|
|
131
|
+
for (const m of await tokenAll(http, `/organizations/${code}/users?page_size=500`, 'organization_users')) {
|
|
132
|
+
const uid = (0, record_set_1.str)(m.id);
|
|
133
|
+
if (!uid || !userIds.has(uid))
|
|
134
|
+
continue;
|
|
135
|
+
const role = (0, record_set_1.strs)(m.roles)[0] ?? 'member';
|
|
136
|
+
set.add('membership', (0, record_set_1.compact)({ organization_id: code, user_id: uid, role, created_at: (0, record_set_1.str)(m.joined_on) }), `${code}:${uid}`);
|
|
137
|
+
if ((0, record_set_1.strs)(m.roles).length > 1)
|
|
138
|
+
set.warn('Some organization members hold several Kinde roles; Atlas seats each member with one role (the first).');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
progress('connections');
|
|
142
|
+
await addConnections(set, http);
|
|
143
|
+
}
|
|
144
|
+
set.warn('Kinde does not export second-factor secrets or passkeys: those users re-enrol in Atlas.');
|
|
145
|
+
set.manifest = { origin: base || null, providers: [...new Set(set.list('identity').map((i) => i.provider))].sort() };
|
|
146
|
+
return set;
|
|
147
|
+
}
|
|
148
|
+
/** One Kinde user (export row and/or API row) → a user record. */
|
|
149
|
+
function mapKindeUser(u, set) {
|
|
150
|
+
const id = (0, record_set_1.str)(u.id);
|
|
151
|
+
if (!id)
|
|
152
|
+
return null;
|
|
153
|
+
const identities = (0, record_set_1.objs)(u.identities);
|
|
154
|
+
const email = ((0, record_set_1.str)(u.email) ?? (0, record_set_1.str)(u.preferred_email))?.toLowerCase();
|
|
155
|
+
const emailIdentity = identities.find((i) => (0, record_set_1.str)(i.type) === 'email' && (0, record_set_1.str)(i.identity)?.toLowerCase() === email);
|
|
156
|
+
const phone = (0, record_set_1.e164)(u.phone) ?? (0, record_set_1.e164)(identities.find((i) => (0, record_set_1.str)(i.type) === 'phone')?.identity);
|
|
157
|
+
const username = (0, record_set_1.str)(u.username) ?? (0, record_set_1.str)(identities.find((i) => (0, record_set_1.str)(i.type) === 'username')?.identity);
|
|
158
|
+
const user = (0, record_set_1.compact)({
|
|
159
|
+
id,
|
|
160
|
+
emails: email
|
|
161
|
+
? [{ email, verified: u.email_verified === true || emailIdentity?.is_confirmed === true || (u.email_verified === undefined && identities.some((i) => (0, record_set_1.str)(i.type)?.startsWith('oauth2:'))), primary: true }]
|
|
162
|
+
: [],
|
|
163
|
+
phones: phone ? [{ phone, verified: false, primary: !email }] : [],
|
|
164
|
+
username,
|
|
165
|
+
first_name: (0, record_set_1.str)(u.first_name),
|
|
166
|
+
last_name: (0, record_set_1.str)(u.last_name),
|
|
167
|
+
image_url: (0, record_set_1.str)(u.picture),
|
|
168
|
+
banned: u.is_suspended === true ? true : undefined,
|
|
169
|
+
private_metadata: (0, record_set_1.bag)((0, record_set_1.compact)({ kinde_external_id: (0, record_set_1.str)(u.external_id) ?? (0, record_set_1.str)(u.provided_id) })),
|
|
170
|
+
created_at: (0, record_set_1.str)(u.created_on),
|
|
171
|
+
last_sign_in_at: (0, record_set_1.str)(u.last_signed_in),
|
|
172
|
+
});
|
|
173
|
+
if ((0, record_set_1.isObj)(u.password)) {
|
|
174
|
+
const mapped = kindePasswordHash(u.password);
|
|
175
|
+
if ('reason' in mapped)
|
|
176
|
+
set?.omit('password', mapped.reason);
|
|
177
|
+
else
|
|
178
|
+
user.password = mapped;
|
|
179
|
+
}
|
|
180
|
+
const social = identities.filter((i) => (0, record_set_1.str)(i.type)?.startsWith('oauth2:'));
|
|
181
|
+
if (social.length)
|
|
182
|
+
set?.omit('identity', "Kinde does not export social accounts' provider user ids: they relink by verified email on first social sign-in", social.length);
|
|
183
|
+
return user.emails?.length || user.phones?.length || user.username ? user : null;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Kinde's exported `password` object → the bundle's password hash. Kinde
|
|
187
|
+
* stores bcrypt; users imported into Kinde keep the algorithm they came with
|
|
188
|
+
* (crypt, md5, sha256, wordpress, pbkdf2, firebase-scrypt, aspnet-identity-v2).
|
|
189
|
+
*/
|
|
190
|
+
function kindePasswordHash(p) {
|
|
191
|
+
const hash = (0, record_set_1.str)(p.hashed_password);
|
|
192
|
+
if (!hash)
|
|
193
|
+
return { reason: 'empty Kinde password hash' };
|
|
194
|
+
const algorithm = ((0, record_set_1.str)(p.hashing_algorithm) ?? '').toLowerCase().replace(/_/g, '-');
|
|
195
|
+
const config = (0, record_set_1.isObj)(p.hashing_config) ? p.hashing_config : {};
|
|
196
|
+
const salt = (0, record_set_1.str)(config.salt);
|
|
197
|
+
const position = ((0, record_set_1.str)(config.salt_position) ?? (0, record_set_1.str)(config.salt_location) ?? (0, record_set_1.str)(config.position) ?? 'suffix').toLowerCase();
|
|
198
|
+
switch (algorithm) {
|
|
199
|
+
case '':
|
|
200
|
+
case 'bcrypt':
|
|
201
|
+
return { algorithm: 'bcrypt', hash };
|
|
202
|
+
case 'crypt':
|
|
203
|
+
case 'wordpress':
|
|
204
|
+
case 'phpass':
|
|
205
|
+
// Self-describing ($1$, $5$, $6$, $2y$, $P$): the registry recognises them.
|
|
206
|
+
return { algorithm: 'auto', hash };
|
|
207
|
+
case 'md5':
|
|
208
|
+
case 'sha256':
|
|
209
|
+
if (!salt)
|
|
210
|
+
return { algorithm, hash, params: { encoding: /^[0-9a-f]+$/i.test(hash) ? 'hex' : 'base64' } };
|
|
211
|
+
return {
|
|
212
|
+
algorithm: `${algorithm}_salted`,
|
|
213
|
+
hash,
|
|
214
|
+
salt,
|
|
215
|
+
params: { encoding: /^[0-9a-f]+$/i.test(hash) ? 'hex' : 'base64', salt_position: position === 'prefix' ? 'prefix' : 'suffix' },
|
|
216
|
+
};
|
|
217
|
+
case 'pbkdf2': {
|
|
218
|
+
if (hash.includes('$'))
|
|
219
|
+
return { algorithm: 'auto', hash };
|
|
220
|
+
const iterations = Number(config.iterations ?? config.rounds);
|
|
221
|
+
if (!salt || !Number.isInteger(iterations))
|
|
222
|
+
return { reason: 'Kinde pbkdf2 hash without salt or iterations' };
|
|
223
|
+
return {
|
|
224
|
+
algorithm: 'pbkdf2',
|
|
225
|
+
hash,
|
|
226
|
+
salt,
|
|
227
|
+
params: { digest: (0, record_set_1.str)(config.digest)?.toLowerCase() ?? 'sha256', iterations, ...((0, record_set_1.str)(config.salt_encoding) ? { salt_encoding: (0, record_set_1.str)(config.salt_encoding) } : {}) },
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
case 'firebase-scrypt': {
|
|
231
|
+
const signer = (0, record_set_1.str)(config.signer_key) ?? (0, record_set_1.str)(config.base64_signer_key);
|
|
232
|
+
if (!signer)
|
|
233
|
+
return { reason: 'Kinde firebase-scrypt hash without the project signer key' };
|
|
234
|
+
return {
|
|
235
|
+
algorithm: 'scrypt_firebase',
|
|
236
|
+
hash,
|
|
237
|
+
salt: salt ?? '',
|
|
238
|
+
params: {
|
|
239
|
+
signer_key: signer,
|
|
240
|
+
salt_separator: (0, record_set_1.str)(config.salt_separator) ?? (0, record_set_1.str)(config.base64_salt_separator) ?? 'Bw==',
|
|
241
|
+
rounds: Number(config.rounds ?? 8),
|
|
242
|
+
mem_cost: Number(config.mem_cost ?? config.memory_cost ?? 14),
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
case 'aspnet-identity-v2':
|
|
247
|
+
case 'aspnet-identity-v3':
|
|
248
|
+
return { algorithm: 'aspnet_identity', hash };
|
|
249
|
+
default:
|
|
250
|
+
return { reason: `Kinde password algorithm "${algorithm}" is not supported` };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async function addConnections(set, http) {
|
|
254
|
+
let conns;
|
|
255
|
+
try {
|
|
256
|
+
conns = await tokenAll(http, '/connections?page_size=500', 'connections');
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
if (err instanceof vendor_http_1.VendorApiError && (err.status === 403 || err.status === 404))
|
|
260
|
+
return;
|
|
261
|
+
throw err;
|
|
262
|
+
}
|
|
263
|
+
for (const c of conns) {
|
|
264
|
+
const id = (0, record_set_1.str)(c.id);
|
|
265
|
+
const strategy = (0, record_set_1.str)(c.strategy) ?? '';
|
|
266
|
+
if (!id || !/^(saml|wsfed|oidc|oauth2:(azure_ad|microsoft_entra|okta|google_workspace))/.test(strategy))
|
|
267
|
+
continue;
|
|
268
|
+
let detail = c;
|
|
269
|
+
try {
|
|
270
|
+
const { body } = await http.get(`/connections/${id}`);
|
|
271
|
+
detail = (0, record_set_1.isObj)(body) && (0, record_set_1.isObj)(body.connection) ? body.connection : (0, record_set_1.isObj)(body) ? body : c;
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
if (!(err instanceof vendor_http_1.VendorApiError))
|
|
275
|
+
throw err;
|
|
276
|
+
}
|
|
277
|
+
const o = (0, record_set_1.isObj)(detail.options) ? detail.options : {};
|
|
278
|
+
const domains = (0, record_set_1.strs)(o.home_realm_domains);
|
|
279
|
+
const name = (0, record_set_1.str)(c.display_name) ?? (0, record_set_1.str)(c.name);
|
|
280
|
+
if (strategy.startsWith('saml')) {
|
|
281
|
+
set.add('sso_connection', (0, record_set_1.compact)({
|
|
282
|
+
id,
|
|
283
|
+
name,
|
|
284
|
+
protocol: 'saml',
|
|
285
|
+
domains,
|
|
286
|
+
saml: (0, record_set_1.compact)({
|
|
287
|
+
idp_entity_id: (0, record_set_1.str)(o.saml_entity_id),
|
|
288
|
+
idp_metadata_url: (0, record_set_1.str)(o.saml_idp_metadata_url),
|
|
289
|
+
idp_sso_url: (0, record_set_1.str)(o.saml_sign_in_url) ?? (0, record_set_1.str)(o.saml_sso_url),
|
|
290
|
+
idp_certificate: (0, record_set_1.str)(o.saml_signing_certificate) ?? (0, record_set_1.str)(o.saml_certificate),
|
|
291
|
+
sp_acs_url: (0, record_set_1.str)(o.saml_acs_url),
|
|
292
|
+
}),
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
set.add('sso_connection', (0, record_set_1.compact)({ id, name, protocol: 'oidc', domains, oidc: (0, record_set_1.compact)({ issuer: (0, record_set_1.str)(o.issuer) ?? (0, record_set_1.str)(o.entra_id_domain), client_id: (0, record_set_1.str)(o.client_id) }) }));
|
|
297
|
+
set.warn(`Enterprise connection ${name ?? id}: Kinde does not return its client secret; enter it in Atlas after the import.`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
async function m2mToken(base, opts) {
|
|
302
|
+
const res = await (opts.fetchImpl ?? fetch)(`${base}/oauth2/token`, {
|
|
303
|
+
method: 'POST',
|
|
304
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded', accept: 'application/json' },
|
|
305
|
+
body: new URLSearchParams({ grant_type: 'client_credentials', client_id: opts.clientId, client_secret: opts.clientSecret, audience: `${base}/api` }).toString(),
|
|
306
|
+
});
|
|
307
|
+
const body = (await res.json().catch(() => ({})));
|
|
308
|
+
if (!res.ok || !body.access_token)
|
|
309
|
+
throw new vendor_http_1.VendorApiError('Kinde', res.status, '/oauth2/token', body.error_description ?? 'could not get a Management API token');
|
|
310
|
+
return body.access_token;
|
|
311
|
+
}
|
|
312
|
+
/** Kinde's `next_token` paging. */
|
|
313
|
+
async function tokenAll(http, path, key) {
|
|
314
|
+
const out = [];
|
|
315
|
+
let next;
|
|
316
|
+
do {
|
|
317
|
+
const { body } = await http.get(`${path}${next ? `&next_token=${encodeURIComponent(next)}` : ''}`);
|
|
318
|
+
const rows = (0, record_set_1.isObj)(body) ? (0, record_set_1.objs)(body[key]) : [];
|
|
319
|
+
out.push(...rows);
|
|
320
|
+
next = (0, record_set_1.isObj)(body) ? (0, record_set_1.str)(body.next_token) : undefined;
|
|
321
|
+
if (rows.length === 0)
|
|
322
|
+
break;
|
|
323
|
+
} while (next);
|
|
324
|
+
return out;
|
|
325
|
+
}
|
|
326
|
+
function ndjson(text) {
|
|
327
|
+
return text
|
|
328
|
+
.split(/\r?\n/)
|
|
329
|
+
.filter((l) => l.trim())
|
|
330
|
+
.map((l) => JSON.parse(l))
|
|
331
|
+
.filter(record_set_1.isObj);
|
|
332
|
+
}
|
|
333
|
+
//# sourceMappingURL=kinde.js.map
|