@atlasauth/cli 0.23.0 → 0.25.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 +13 -0
- package/package.json +3 -3
- package/dist/args.d.ts +0 -601
- package/dist/args.js +0 -289
- package/dist/args.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -19
- package/dist/cli.js.map +0 -1
- package/dist/commands/actions-gallery.d.ts +0 -8
- package/dist/commands/actions-gallery.js +0 -197
- package/dist/commands/actions-gallery.js.map +0 -1
- package/dist/commands/actions.d.ts +0 -13
- package/dist/commands/actions.js +0 -135
- package/dist/commands/actions.js.map +0 -1
- package/dist/commands/admin.d.ts +0 -49
- package/dist/commands/admin.js +0 -353
- package/dist/commands/admin.js.map +0 -1
- package/dist/commands/api-keys.d.ts +0 -4
- package/dist/commands/api-keys.js +0 -96
- package/dist/commands/api-keys.js.map +0 -1
- package/dist/commands/auth.d.ts +0 -25
- package/dist/commands/auth.js +0 -102
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/config.d.ts +0 -90
- package/dist/commands/config.js +0 -1430
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/csp.d.ts +0 -32
- package/dist/commands/csp.js +0 -180
- package/dist/commands/csp.js.map +0 -1
- package/dist/commands/dev.d.ts +0 -8
- package/dist/commands/dev.js +0 -84
- package/dist/commands/dev.js.map +0 -1
- package/dist/commands/fga.d.ts +0 -10
- package/dist/commands/fga.js +0 -146
- package/dist/commands/fga.js.map +0 -1
- package/dist/commands/golive.d.ts +0 -40
- package/dist/commands/golive.js +0 -285
- package/dist/commands/golive.js.map +0 -1
- package/dist/commands/id-accounts.d.ts +0 -13
- package/dist/commands/id-accounts.js +0 -195
- package/dist/commands/id-accounts.js.map +0 -1
- package/dist/commands/import-better-auth.d.ts +0 -3
- package/dist/commands/import-better-auth.js +0 -164
- package/dist/commands/import-better-auth.js.map +0 -1
- package/dist/commands/import.d.ts +0 -3
- package/dist/commands/import.js +0 -123
- package/dist/commands/import.js.map +0 -1
- package/dist/commands/info.d.ts +0 -75
- package/dist/commands/info.js +0 -362
- package/dist/commands/info.js.map +0 -1
- package/dist/commands/init.d.ts +0 -3
- package/dist/commands/init.js +0 -438
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/integrations.d.ts +0 -8
- package/dist/commands/integrations.js +0 -112
- package/dist/commands/integrations.js.map +0 -1
- package/dist/commands/listen.d.ts +0 -17
- package/dist/commands/listen.js +0 -223
- package/dist/commands/listen.js.map +0 -1
- package/dist/commands/mcp.d.ts +0 -38
- package/dist/commands/mcp.js +0 -111
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/migrate.d.ts +0 -16
- package/dist/commands/migrate.js +0 -114
- package/dist/commands/migrate.js.map +0 -1
- package/dist/commands/move-origin.d.ts +0 -11
- package/dist/commands/move-origin.js +0 -95
- package/dist/commands/move-origin.js.map +0 -1
- package/dist/commands/operator.d.ts +0 -18
- package/dist/commands/operator.js +0 -238
- package/dist/commands/operator.js.map +0 -1
- package/dist/commands/orgs.d.ts +0 -4
- package/dist/commands/orgs.js +0 -72
- package/dist/commands/orgs.js.map +0 -1
- package/dist/commands/pages.d.ts +0 -14
- package/dist/commands/pages.js +0 -113
- package/dist/commands/pages.js.map +0 -1
- package/dist/commands/partner-platforms.d.ts +0 -10
- package/dist/commands/partner-platforms.js +0 -157
- package/dist/commands/partner-platforms.js.map +0 -1
- package/dist/commands/project-commands.d.ts +0 -38
- package/dist/commands/project-commands.js +0 -361
- package/dist/commands/project-commands.js.map +0 -1
- package/dist/commands/referrals.d.ts +0 -69
- package/dist/commands/referrals.js +0 -1056
- package/dist/commands/referrals.js.map +0 -1
- package/dist/commands/resources.d.ts +0 -44
- package/dist/commands/resources.js +0 -234
- package/dist/commands/resources.js.map +0 -1
- package/dist/commands/sessions.d.ts +0 -4
- package/dist/commands/sessions.js +0 -28
- package/dist/commands/sessions.js.map +0 -1
- package/dist/commands/shared.d.ts +0 -38
- package/dist/commands/shared.js +0 -69
- package/dist/commands/shared.js.map +0 -1
- package/dist/commands/status.d.ts +0 -3
- package/dist/commands/status.js +0 -77
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/users.d.ts +0 -4
- package/dist/commands/users.js +0 -100
- package/dist/commands/users.js.map +0 -1
- package/dist/commands/webhooks.d.ts +0 -34
- package/dist/commands/webhooks.js +0 -301
- package/dist/commands/webhooks.js.map +0 -1
- package/dist/config-http.d.ts +0 -29
- package/dist/config-http.js +0 -64
- package/dist/config-http.js.map +0 -1
- package/dist/config.d.ts +0 -64
- package/dist/config.js +0 -69
- package/dist/config.js.map +0 -1
- package/dist/context.d.ts +0 -72
- package/dist/context.js +0 -27
- package/dist/context.js.map +0 -1
- package/dist/errors.d.ts +0 -15
- package/dist/errors.js +0 -25
- package/dist/errors.js.map +0 -1
- package/dist/help.d.ts +0 -8
- package/dist/help.js +0 -868
- package/dist/help.js.map +0 -1
- package/dist/import/csv.d.ts +0 -6
- package/dist/import/csv.js +0 -63
- package/dist/import/csv.js.map +0 -1
- package/dist/import/vendors.d.ts +0 -57
- package/dist/import/vendors.js +0 -568
- package/dist/import/vendors.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.js +0 -79
- package/dist/index.js.map +0 -1
- package/dist/io.d.ts +0 -21
- package/dist/io.js +0 -28
- package/dist/io.js.map +0 -1
- package/dist/migrate/appwrite/plugin.d.ts +0 -2
- package/dist/migrate/appwrite/plugin.js +0 -103
- package/dist/migrate/appwrite/plugin.js.map +0 -1
- package/dist/migrate/auth0/plugin.d.ts +0 -2
- package/dist/migrate/auth0/plugin.js +0 -126
- package/dist/migrate/auth0/plugin.js.map +0 -1
- package/dist/migrate/authentik/plugin.d.ts +0 -2
- package/dist/migrate/authentik/plugin.js +0 -135
- package/dist/migrate/authentik/plugin.js.map +0 -1
- package/dist/migrate/azure-ad-b2c/plugin.d.ts +0 -8
- package/dist/migrate/azure-ad-b2c/plugin.js +0 -165
- package/dist/migrate/azure-ad-b2c/plugin.js.map +0 -1
- package/dist/migrate/better-auth/integration.d.ts +0 -59
- package/dist/migrate/better-auth/integration.js +0 -81
- package/dist/migrate/better-auth/integration.js.map +0 -1
- package/dist/migrate/better-auth/orchestrator.d.ts +0 -43
- package/dist/migrate/better-auth/orchestrator.js +0 -525
- package/dist/migrate/better-auth/orchestrator.js.map +0 -1
- package/dist/migrate/better-auth/output.d.ts +0 -20
- package/dist/migrate/better-auth/output.js +0 -146
- package/dist/migrate/better-auth/output.js.map +0 -1
- package/dist/migrate/better-auth/translate.d.ts +0 -77
- package/dist/migrate/better-auth/translate.js +0 -1989
- package/dist/migrate/better-auth/translate.js.map +0 -1
- package/dist/migrate/clerk/plugin.d.ts +0 -2
- package/dist/migrate/clerk/plugin.js +0 -76
- package/dist/migrate/clerk/plugin.js.map +0 -1
- package/dist/migrate/cognito/plugin.d.ts +0 -5
- package/dist/migrate/cognito/plugin.js +0 -170
- package/dist/migrate/cognito/plugin.js.map +0 -1
- package/dist/migrate/corbado/plugin.d.ts +0 -2
- package/dist/migrate/corbado/plugin.js +0 -63
- package/dist/migrate/corbado/plugin.js.map +0 -1
- package/dist/migrate/descope/plugin.d.ts +0 -2
- package/dist/migrate/descope/plugin.js +0 -83
- package/dist/migrate/descope/plugin.js.map +0 -1
- package/dist/migrate/entra-external-id/plugin.d.ts +0 -8
- package/dist/migrate/entra-external-id/plugin.js +0 -12
- package/dist/migrate/entra-external-id/plugin.js.map +0 -1
- package/dist/migrate/export/appwrite-config.d.ts +0 -28
- package/dist/migrate/export/appwrite-config.js +0 -170
- package/dist/migrate/export/appwrite-config.js.map +0 -1
- package/dist/migrate/export/appwrite.d.ts +0 -51
- package/dist/migrate/export/appwrite.js +0 -288
- package/dist/migrate/export/appwrite.js.map +0 -1
- package/dist/migrate/export/auth0-config.d.ts +0 -29
- package/dist/migrate/export/auth0-config.js +0 -249
- package/dist/migrate/export/auth0-config.js.map +0 -1
- package/dist/migrate/export/auth0.d.ts +0 -62
- package/dist/migrate/export/auth0.js +0 -575
- package/dist/migrate/export/auth0.js.map +0 -1
- package/dist/migrate/export/authentik-config.d.ts +0 -45
- package/dist/migrate/export/authentik-config.js +0 -357
- package/dist/migrate/export/authentik-config.js.map +0 -1
- package/dist/migrate/export/authentik.d.ts +0 -110
- package/dist/migrate/export/authentik.js +0 -838
- package/dist/migrate/export/authentik.js.map +0 -1
- package/dist/migrate/export/azure-config.d.ts +0 -58
- package/dist/migrate/export/azure-config.js +0 -344
- package/dist/migrate/export/azure-config.js.map +0 -1
- package/dist/migrate/export/azure.d.ts +0 -85
- package/dist/migrate/export/azure.js +0 -373
- package/dist/migrate/export/azure.js.map +0 -1
- package/dist/migrate/export/clerk-config.d.ts +0 -26
- package/dist/migrate/export/clerk-config.js +0 -227
- package/dist/migrate/export/clerk-config.js.map +0 -1
- package/dist/migrate/export/clerk.d.ts +0 -46
- package/dist/migrate/export/clerk.js +0 -486
- package/dist/migrate/export/clerk.js.map +0 -1
- package/dist/migrate/export/cognito-config.d.ts +0 -25
- package/dist/migrate/export/cognito-config.js +0 -273
- package/dist/migrate/export/cognito-config.js.map +0 -1
- package/dist/migrate/export/cognito.d.ts +0 -103
- package/dist/migrate/export/cognito.js +0 -441
- package/dist/migrate/export/cognito.js.map +0 -1
- package/dist/migrate/export/corbado-config.d.ts +0 -20
- package/dist/migrate/export/corbado-config.js +0 -63
- package/dist/migrate/export/corbado-config.js.map +0 -1
- package/dist/migrate/export/corbado.d.ts +0 -37
- package/dist/migrate/export/corbado.js +0 -132
- package/dist/migrate/export/corbado.js.map +0 -1
- package/dist/migrate/export/descope.d.ts +0 -35
- package/dist/migrate/export/descope.js +0 -208
- package/dist/migrate/export/descope.js.map +0 -1
- package/dist/migrate/export/fake-vendor.test-helper.d.ts +0 -27
- package/dist/migrate/export/fake-vendor.test-helper.js +0 -41
- package/dist/migrate/export/fake-vendor.test-helper.js.map +0 -1
- package/dist/migrate/export/firebase-config.d.ts +0 -24
- package/dist/migrate/export/firebase-config.js +0 -215
- package/dist/migrate/export/firebase-config.js.map +0 -1
- package/dist/migrate/export/firebase.d.ts +0 -102
- package/dist/migrate/export/firebase.js +0 -464
- package/dist/migrate/export/firebase.js.map +0 -1
- package/dist/migrate/export/frameworks/app-users.d.ts +0 -42
- package/dist/migrate/export/frameworks/app-users.js +0 -161
- package/dist/migrate/export/frameworks/app-users.js.map +0 -1
- package/dist/migrate/export/frameworks/authjs.d.ts +0 -41
- package/dist/migrate/export/frameworks/authjs.js +0 -146
- package/dist/migrate/export/frameworks/authjs.js.map +0 -1
- package/dist/migrate/export/frameworks/devise.d.ts +0 -39
- package/dist/migrate/export/frameworks/devise.js +0 -218
- package/dist/migrate/export/frameworks/devise.js.map +0 -1
- package/dist/migrate/export/frameworks/django.d.ts +0 -45
- package/dist/migrate/export/frameworks/django.js +0 -315
- package/dist/migrate/export/frameworks/django.js.map +0 -1
- package/dist/migrate/export/frameworks/lucia.d.ts +0 -42
- package/dist/migrate/export/frameworks/lucia.js +0 -263
- package/dist/migrate/export/frameworks/lucia.js.map +0 -1
- package/dist/migrate/export/frameworks/tables.d.ts +0 -90
- package/dist/migrate/export/frameworks/tables.js +0 -325
- package/dist/migrate/export/frameworks/tables.js.map +0 -1
- package/dist/migrate/export/frameworks/webauthn.d.ts +0 -25
- package/dist/migrate/export/frameworks/webauthn.js +0 -130
- package/dist/migrate/export/frameworks/webauthn.js.map +0 -1
- package/dist/migrate/export/frontegg-config.d.ts +0 -29
- package/dist/migrate/export/frontegg-config.js +0 -238
- package/dist/migrate/export/frontegg-config.js.map +0 -1
- package/dist/migrate/export/frontegg.d.ts +0 -67
- package/dist/migrate/export/frontegg.js +0 -410
- package/dist/migrate/export/frontegg.js.map +0 -1
- package/dist/migrate/export/fusionauth-config.d.ts +0 -26
- package/dist/migrate/export/fusionauth-config.js +0 -226
- package/dist/migrate/export/fusionauth-config.js.map +0 -1
- package/dist/migrate/export/fusionauth.d.ts +0 -99
- package/dist/migrate/export/fusionauth.js +0 -642
- package/dist/migrate/export/fusionauth.js.map +0 -1
- package/dist/migrate/export/hanko-config.d.ts +0 -27
- package/dist/migrate/export/hanko-config.js +0 -265
- package/dist/migrate/export/hanko-config.js.map +0 -1
- package/dist/migrate/export/hanko.d.ts +0 -52
- package/dist/migrate/export/hanko.js +0 -605
- package/dist/migrate/export/hanko.js.map +0 -1
- package/dist/migrate/export/keycloak-config.d.ts +0 -19
- package/dist/migrate/export/keycloak-config.js +0 -219
- package/dist/migrate/export/keycloak-config.js.map +0 -1
- package/dist/migrate/export/keycloak.d.ts +0 -155
- package/dist/migrate/export/keycloak.js +0 -878
- package/dist/migrate/export/keycloak.js.map +0 -1
- package/dist/migrate/export/kinde-descope-config.d.ts +0 -38
- package/dist/migrate/export/kinde-descope-config.js +0 -172
- package/dist/migrate/export/kinde-descope-config.js.map +0 -1
- package/dist/migrate/export/kinde.d.ts +0 -57
- package/dist/migrate/export/kinde.js +0 -333
- package/dist/migrate/export/kinde.js.map +0 -1
- package/dist/migrate/export/ldap.d.ts +0 -53
- package/dist/migrate/export/ldap.js +0 -277
- package/dist/migrate/export/ldap.js.map +0 -1
- package/dist/migrate/export/logto-config.d.ts +0 -27
- package/dist/migrate/export/logto-config.js +0 -264
- package/dist/migrate/export/logto-config.js.map +0 -1
- package/dist/migrate/export/logto.d.ts +0 -150
- package/dist/migrate/export/logto.js +0 -809
- package/dist/migrate/export/logto.js.map +0 -1
- package/dist/migrate/export/magic-config.d.ts +0 -14
- package/dist/migrate/export/magic-config.js +0 -28
- package/dist/migrate/export/magic-config.js.map +0 -1
- package/dist/migrate/export/magic.d.ts +0 -31
- package/dist/migrate/export/magic.js +0 -93
- package/dist/migrate/export/magic.js.map +0 -1
- package/dist/migrate/export/mini-yaml.d.ts +0 -19
- package/dist/migrate/export/mini-yaml.js +0 -581
- package/dist/migrate/export/mini-yaml.js.map +0 -1
- package/dist/migrate/export/nhost-config.d.ts +0 -26
- package/dist/migrate/export/nhost-config.js +0 -360
- package/dist/migrate/export/nhost-config.js.map +0 -1
- package/dist/migrate/export/nhost.d.ts +0 -64
- package/dist/migrate/export/nhost.js +0 -304
- package/dist/migrate/export/nhost.js.map +0 -1
- package/dist/migrate/export/okta-config.d.ts +0 -30
- package/dist/migrate/export/okta-config.js +0 -205
- package/dist/migrate/export/okta-config.js.map +0 -1
- package/dist/migrate/export/okta.d.ts +0 -43
- package/dist/migrate/export/okta.js +0 -337
- package/dist/migrate/export/okta.js.map +0 -1
- package/dist/migrate/export/onelogin.d.ts +0 -22
- package/dist/migrate/export/onelogin.js +0 -123
- package/dist/migrate/export/onelogin.js.map +0 -1
- package/dist/migrate/export/ory-config.d.ts +0 -58
- package/dist/migrate/export/ory-config.js +0 -451
- package/dist/migrate/export/ory-config.js.map +0 -1
- package/dist/migrate/export/ory.d.ts +0 -81
- package/dist/migrate/export/ory.js +0 -555
- package/dist/migrate/export/ory.js.map +0 -1
- package/dist/migrate/export/password-detect.d.ts +0 -29
- package/dist/migrate/export/password-detect.js +0 -81
- package/dist/migrate/export/password-detect.js.map +0 -1
- package/dist/migrate/export/pingone.d.ts +0 -36
- package/dist/migrate/export/pingone.js +0 -218
- package/dist/migrate/export/pingone.js.map +0 -1
- package/dist/migrate/export/plugin-kit.d.ts +0 -25
- package/dist/migrate/export/plugin-kit.js +0 -82
- package/dist/migrate/export/plugin-kit.js.map +0 -1
- package/dist/migrate/export/pocketbase-config.d.ts +0 -28
- package/dist/migrate/export/pocketbase-config.js +0 -180
- package/dist/migrate/export/pocketbase-config.js.map +0 -1
- package/dist/migrate/export/pocketbase.d.ts +0 -52
- package/dist/migrate/export/pocketbase.js +0 -243
- package/dist/migrate/export/pocketbase.js.map +0 -1
- package/dist/migrate/export/project-files.d.ts +0 -15
- package/dist/migrate/export/project-files.js +0 -43
- package/dist/migrate/export/project-files.js.map +0 -1
- package/dist/migrate/export/propelauth-config.d.ts +0 -18
- package/dist/migrate/export/propelauth-config.js +0 -58
- package/dist/migrate/export/propelauth-config.js.map +0 -1
- package/dist/migrate/export/propelauth-harness.test-helper.d.ts +0 -62
- package/dist/migrate/export/propelauth-harness.test-helper.js +0 -109
- package/dist/migrate/export/propelauth-harness.test-helper.js.map +0 -1
- package/dist/migrate/export/propelauth.d.ts +0 -48
- package/dist/migrate/export/propelauth.js +0 -255
- package/dist/migrate/export/propelauth.js.map +0 -1
- package/dist/migrate/export/record-set.d.ts +0 -44
- package/dist/migrate/export/record-set.js +0 -98
- package/dist/migrate/export/record-set.js.map +0 -1
- package/dist/migrate/export/source-lines.d.ts +0 -17
- package/dist/migrate/export/source-lines.js +0 -43
- package/dist/migrate/export/source-lines.js.map +0 -1
- package/dist/migrate/export/sso-metadata.d.ts +0 -47
- package/dist/migrate/export/sso-metadata.js +0 -180
- package/dist/migrate/export/sso-metadata.js.map +0 -1
- package/dist/migrate/export/stytch-config.d.ts +0 -22
- package/dist/migrate/export/stytch-config.js +0 -102
- package/dist/migrate/export/stytch-config.js.map +0 -1
- package/dist/migrate/export/stytch.d.ts +0 -68
- package/dist/migrate/export/stytch.js +0 -510
- package/dist/migrate/export/stytch.js.map +0 -1
- package/dist/migrate/export/supabase-config.d.ts +0 -48
- package/dist/migrate/export/supabase-config.js +0 -408
- package/dist/migrate/export/supabase-config.js.map +0 -1
- package/dist/migrate/export/supabase.d.ts +0 -86
- package/dist/migrate/export/supabase.js +0 -524
- package/dist/migrate/export/supabase.js.map +0 -1
- package/dist/migrate/export/supertokens-config.d.ts +0 -20
- package/dist/migrate/export/supertokens-config.js +0 -150
- package/dist/migrate/export/supertokens-config.js.map +0 -1
- package/dist/migrate/export/supertokens.d.ts +0 -125
- package/dist/migrate/export/supertokens.js +0 -464
- package/dist/migrate/export/supertokens.js.map +0 -1
- package/dist/migrate/export/table.d.ts +0 -35
- package/dist/migrate/export/table.js +0 -248
- package/dist/migrate/export/table.js.map +0 -1
- package/dist/migrate/export/translate-kit.d.ts +0 -46
- package/dist/migrate/export/translate-kit.js +0 -148
- package/dist/migrate/export/translate-kit.js.map +0 -1
- package/dist/migrate/export/userfront-config.d.ts +0 -15
- package/dist/migrate/export/userfront-config.js +0 -49
- package/dist/migrate/export/userfront-config.js.map +0 -1
- package/dist/migrate/export/userfront.d.ts +0 -38
- package/dist/migrate/export/userfront.js +0 -189
- package/dist/migrate/export/userfront.js.map +0 -1
- package/dist/migrate/export/vendor-http.d.ts +0 -46
- package/dist/migrate/export/vendor-http.js +0 -138
- package/dist/migrate/export/vendor-http.js.map +0 -1
- package/dist/migrate/export/workos-config.d.ts +0 -23
- package/dist/migrate/export/workos-config.js +0 -125
- package/dist/migrate/export/workos-config.js.map +0 -1
- package/dist/migrate/export/workos.d.ts +0 -46
- package/dist/migrate/export/workos.js +0 -272
- package/dist/migrate/export/workos.js.map +0 -1
- package/dist/migrate/export/zip.d.ts +0 -8
- package/dist/migrate/export/zip.js +0 -66
- package/dist/migrate/export/zip.js.map +0 -1
- package/dist/migrate/export/zitadel-config.d.ts +0 -37
- package/dist/migrate/export/zitadel-config.js +0 -279
- package/dist/migrate/export/zitadel-config.js.map +0 -1
- package/dist/migrate/export/zitadel.d.ts +0 -82
- package/dist/migrate/export/zitadel.js +0 -447
- package/dist/migrate/export/zitadel.js.map +0 -1
- package/dist/migrate/firebase/plugin.d.ts +0 -2
- package/dist/migrate/firebase/plugin.js +0 -152
- package/dist/migrate/firebase/plugin.js.map +0 -1
- package/dist/migrate/framework/builtins.d.ts +0 -2
- package/dist/migrate/framework/builtins.js +0 -52
- package/dist/migrate/framework/builtins.js.map +0 -1
- package/dist/migrate/framework/commands.d.ts +0 -20
- package/dist/migrate/framework/commands.js +0 -58
- package/dist/migrate/framework/commands.js.map +0 -1
- package/dist/migrate/framework/custom.d.ts +0 -12
- package/dist/migrate/framework/custom.js +0 -96
- package/dist/migrate/framework/custom.js.map +0 -1
- package/dist/migrate/framework/orchestrator.d.ts +0 -113
- package/dist/migrate/framework/orchestrator.js +0 -532
- package/dist/migrate/framework/orchestrator.js.map +0 -1
- package/dist/migrate/framework/plugin.d.ts +0 -167
- package/dist/migrate/framework/plugin.js +0 -3
- package/dist/migrate/framework/plugin.js.map +0 -1
- package/dist/migrate/framework/registry.d.ts +0 -11
- package/dist/migrate/framework/registry.js +0 -44
- package/dist/migrate/framework/registry.js.map +0 -1
- package/dist/migrate/framework/report.d.ts +0 -17
- package/dist/migrate/framework/report.js +0 -103
- package/dist/migrate/framework/report.js.map +0 -1
- package/dist/migrate/frameworks/plugins.d.ts +0 -29
- package/dist/migrate/frameworks/plugins.js +0 -402
- package/dist/migrate/frameworks/plugins.js.map +0 -1
- package/dist/migrate/frameworks/report.d.ts +0 -92
- package/dist/migrate/frameworks/report.js +0 -207
- package/dist/migrate/frameworks/report.js.map +0 -1
- package/dist/migrate/frameworks/translate-js.d.ts +0 -5
- package/dist/migrate/frameworks/translate-js.js +0 -503
- package/dist/migrate/frameworks/translate-js.js.map +0 -1
- package/dist/migrate/frameworks/translate-rails-django.d.ts +0 -3
- package/dist/migrate/frameworks/translate-rails-django.js +0 -1391
- package/dist/migrate/frameworks/translate-rails-django.js.map +0 -1
- package/dist/migrate/frontegg/plugin.d.ts +0 -2
- package/dist/migrate/frontegg/plugin.js +0 -78
- package/dist/migrate/frontegg/plugin.js.map +0 -1
- package/dist/migrate/fusionauth/plugin.d.ts +0 -2
- package/dist/migrate/fusionauth/plugin.js +0 -109
- package/dist/migrate/fusionauth/plugin.js.map +0 -1
- package/dist/migrate/hanko/plugin.d.ts +0 -2
- package/dist/migrate/hanko/plugin.js +0 -100
- package/dist/migrate/hanko/plugin.js.map +0 -1
- package/dist/migrate/keycloak/plugin.d.ts +0 -2
- package/dist/migrate/keycloak/plugin.js +0 -148
- package/dist/migrate/keycloak/plugin.js.map +0 -1
- package/dist/migrate/kinde/plugin.d.ts +0 -2
- package/dist/migrate/kinde/plugin.js +0 -105
- package/dist/migrate/kinde/plugin.js.map +0 -1
- package/dist/migrate/ldap/plugin.d.ts +0 -2
- package/dist/migrate/ldap/plugin.js +0 -73
- package/dist/migrate/ldap/plugin.js.map +0 -1
- package/dist/migrate/logto/plugin.d.ts +0 -2
- package/dist/migrate/logto/plugin.js +0 -131
- package/dist/migrate/logto/plugin.js.map +0 -1
- package/dist/migrate/magic/plugin.d.ts +0 -2
- package/dist/migrate/magic/plugin.js +0 -56
- package/dist/migrate/magic/plugin.js.map +0 -1
- package/dist/migrate/nhost/plugin.d.ts +0 -2
- package/dist/migrate/nhost/plugin.js +0 -115
- package/dist/migrate/nhost/plugin.js.map +0 -1
- package/dist/migrate/oidc/plugin.d.ts +0 -2
- package/dist/migrate/oidc/plugin.js +0 -73
- package/dist/migrate/oidc/plugin.js.map +0 -1
- package/dist/migrate/okta/plugin.d.ts +0 -2
- package/dist/migrate/okta/plugin.js +0 -105
- package/dist/migrate/okta/plugin.js.map +0 -1
- package/dist/migrate/onelogin/plugin.d.ts +0 -2
- package/dist/migrate/onelogin/plugin.js +0 -61
- package/dist/migrate/onelogin/plugin.js.map +0 -1
- package/dist/migrate/ory/plugin.d.ts +0 -2
- package/dist/migrate/ory/plugin.js +0 -186
- package/dist/migrate/ory/plugin.js.map +0 -1
- package/dist/migrate/ping-identity/plugin.d.ts +0 -2
- package/dist/migrate/ping-identity/plugin.js +0 -100
- package/dist/migrate/ping-identity/plugin.js.map +0 -1
- package/dist/migrate/pocketbase/plugin.d.ts +0 -2
- package/dist/migrate/pocketbase/plugin.js +0 -99
- package/dist/migrate/pocketbase/plugin.js.map +0 -1
- package/dist/migrate/propelauth/plugin.d.ts +0 -2
- package/dist/migrate/propelauth/plugin.js +0 -65
- package/dist/migrate/propelauth/plugin.js.map +0 -1
- package/dist/migrate/saml/plugin.d.ts +0 -2
- package/dist/migrate/saml/plugin.js +0 -79
- package/dist/migrate/saml/plugin.js.map +0 -1
- package/dist/migrate/stytch/plugin.d.ts +0 -2
- package/dist/migrate/stytch/plugin.js +0 -97
- package/dist/migrate/stytch/plugin.js.map +0 -1
- package/dist/migrate/supabase/plugin.d.ts +0 -2
- package/dist/migrate/supabase/plugin.js +0 -149
- package/dist/migrate/supabase/plugin.js.map +0 -1
- package/dist/migrate/supertokens/plugin.d.ts +0 -2
- package/dist/migrate/supertokens/plugin.js +0 -114
- package/dist/migrate/supertokens/plugin.js.map +0 -1
- package/dist/migrate/user-table/plugin.d.ts +0 -2
- package/dist/migrate/user-table/plugin.js +0 -62
- package/dist/migrate/user-table/plugin.js.map +0 -1
- package/dist/migrate/userfront/plugin.d.ts +0 -2
- package/dist/migrate/userfront/plugin.js +0 -60
- package/dist/migrate/userfront/plugin.js.map +0 -1
- package/dist/migrate/workos/plugin.d.ts +0 -2
- package/dist/migrate/workos/plugin.js +0 -81
- package/dist/migrate/workos/plugin.js.map +0 -1
- package/dist/migrate/zitadel/plugin.d.ts +0 -2
- package/dist/migrate/zitadel/plugin.js +0 -114
- package/dist/migrate/zitadel/plugin.js.map +0 -1
- package/dist/output.d.ts +0 -41
- package/dist/output.js +0 -72
- package/dist/output.js.map +0 -1
- package/dist/project.d.ts +0 -64
- package/dist/project.js +0 -86
- package/dist/project.js.map +0 -1
- package/dist/prompt.d.ts +0 -15
- package/dist/prompt.js +0 -46
- package/dist/prompt.js.map +0 -1
- package/dist/run.d.ts +0 -12
- package/dist/run.js +0 -157
- package/dist/run.js.map +0 -1
- package/dist/secrets.d.ts +0 -41
- package/dist/secrets.js +0 -142
- package/dist/secrets.js.map +0 -1
- package/dist/serialize.d.ts +0 -30
- package/dist/serialize.js +0 -131
- package/dist/serialize.js.map +0 -1
- package/dist/version.d.ts +0 -7
- package/dist/version.js +0 -21
- package/dist/version.js.map +0 -1
|
@@ -1,838 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AUTHENTIK_SUB_MODES = void 0;
|
|
4
|
-
exports.exportAuthentik = exportAuthentik;
|
|
5
|
-
exports.authentikUid = authentikUid;
|
|
6
|
-
exports.authentikSubject = authentikSubject;
|
|
7
|
-
exports.djangoPassword = djangoPassword;
|
|
8
|
-
exports.base32 = base32;
|
|
9
|
-
exports.exportAuthentikDump = exportAuthentikDump;
|
|
10
|
-
exports.authentikList = authentikList;
|
|
11
|
-
exports.exportAuthentikApi = exportAuthentikApi;
|
|
12
|
-
const node_crypto_1 = require("node:crypto");
|
|
13
|
-
const tables_1 = require("./frameworks/tables");
|
|
14
|
-
const record_set_1 = require("./record-set");
|
|
15
|
-
const translate_kit_1 = require("./translate-kit");
|
|
16
|
-
const vendor_http_1 = require("./vendor-http");
|
|
17
|
-
exports.AUTHENTIK_SUB_MODES = ['hashed_user_id', 'user_id', 'user_uuid', 'user_username', 'user_email', 'user_upn'];
|
|
18
|
-
const SERVICE_TYPES = new Set(['service_account', 'internal_service_account']);
|
|
19
|
-
/** authentik's OAuth source types that are generic OIDC rather than a social network. */
|
|
20
|
-
const OIDC_SOURCE_TYPES = new Set(['openidconnect', 'okta', 'keycloak', 'authentik', 'entraid_oidc']);
|
|
21
|
-
/** Source types Atlas has under another key. */
|
|
22
|
-
const SOURCE_ALIASES = { azuread: 'microsoft', entraid: 'microsoft', mailcow: '', patreon: '', plex: '' };
|
|
23
|
-
async function exportAuthentik(opts) {
|
|
24
|
-
if (opts.tables)
|
|
25
|
-
return exportAuthentikDump(opts.tables, opts);
|
|
26
|
-
if (!opts.baseUrl || !opts.token) {
|
|
27
|
-
throw new Error('authentik export needs a database dump directory (AUTHENTIK_DUMP) or the authentik URL and an API token (AUTHENTIK_URL, AUTHENTIK_TOKEN).');
|
|
28
|
-
}
|
|
29
|
-
return exportAuthentikApi(opts);
|
|
30
|
-
}
|
|
31
|
-
// ── the user id ─────────────────────────────────────────────────────────────
|
|
32
|
-
/** `User.uid` (authentik/core/models.py): sha256 of "<pk>-<install id>", hex. */
|
|
33
|
-
function authentikUid(pk, installId) {
|
|
34
|
-
return (0, node_crypto_1.createHash)('sha256').update(`${pk}-${installId}`, 'utf8').digest('hex');
|
|
35
|
-
}
|
|
36
|
-
/** The id a user's tokens carry as `sub` under a provider's sub_mode; undefined when the user has none. */
|
|
37
|
-
function authentikSubject(u, mode, installId) {
|
|
38
|
-
const uid = u.uid ?? (installId ? authentikUid(u.pk, installId) : undefined);
|
|
39
|
-
switch (mode) {
|
|
40
|
-
case 'hashed_user_id':
|
|
41
|
-
return uid;
|
|
42
|
-
case 'user_id':
|
|
43
|
-
return u.pk;
|
|
44
|
-
case 'user_uuid':
|
|
45
|
-
return u.uuid;
|
|
46
|
-
case 'user_username':
|
|
47
|
-
return u.username;
|
|
48
|
-
case 'user_email':
|
|
49
|
-
return u.email;
|
|
50
|
-
case 'user_upn':
|
|
51
|
-
return (0, record_set_1.str)(u.attributes.upn) ?? uid;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// ── passwords ───────────────────────────────────────────────────────────────
|
|
55
|
-
const DJANGO_ARGON2 = /^argon2(\$argon2(?:id|i|d))\$(v=\d+\$)?(m=\d+,t=\d+,p=\d+\$[A-Za-z0-9+/]+\$[A-Za-z0-9+/]+)$/;
|
|
56
|
-
const DJANGO_BCRYPT = /^bcrypt\$(\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53})$/;
|
|
57
|
-
const DJANGO_SCRYPT = /^scrypt\$(\d+)\$([^$]+)\$(\d+)\$(\d+)\$([A-Za-z0-9+/=]+)$/;
|
|
58
|
-
/**
|
|
59
|
-
* A Django password digest (authentik uses Django's default hashers) as a
|
|
60
|
-
* bundle password, in a form Atlas's registry verifies:
|
|
61
|
-
* pbkdf2_sha256$… / pbkdf2_sha1$… → pbkdf2_django (verbatim)
|
|
62
|
-
* bcrypt_sha256$$2b$… → bcrypt_sha256_django (verbatim)
|
|
63
|
-
* argon2$argon2id$v=19$… → argon2, the argon2-cffi PHC string
|
|
64
|
-
* (a version-less hash is Argon2 v1.0: `v=16`)
|
|
65
|
-
* bcrypt$$2b$… → bcrypt, the plain bcrypt digest
|
|
66
|
-
* scrypt$<n>$<salt>$<r>$<p>$<hash> → scrypt with its parameters (64-byte key)
|
|
67
|
-
* Null for an unusable (`!…`) or unknown digest.
|
|
68
|
-
*/
|
|
69
|
-
function djangoPassword(digest) {
|
|
70
|
-
const d = digest?.trim();
|
|
71
|
-
if (!d || d.startsWith('!'))
|
|
72
|
-
return null;
|
|
73
|
-
if (/^pbkdf2_sha(1|256)\$\d+\$[^$]+\$.+$/.test(d))
|
|
74
|
-
return { algorithm: 'pbkdf2_django', hash: d };
|
|
75
|
-
if (/^bcrypt_sha256\$\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53}$/.test(d))
|
|
76
|
-
return { algorithm: 'bcrypt_sha256_django', hash: d };
|
|
77
|
-
const a = DJANGO_ARGON2.exec(d);
|
|
78
|
-
if (a)
|
|
79
|
-
return { algorithm: 'argon2', hash: `${a[1]}$${a[2] ?? 'v=16$'}${a[3]}` };
|
|
80
|
-
const b = DJANGO_BCRYPT.exec(d);
|
|
81
|
-
if (b)
|
|
82
|
-
return { algorithm: 'bcrypt', hash: b[1] };
|
|
83
|
-
const s = DJANGO_SCRYPT.exec(d);
|
|
84
|
-
if (s) {
|
|
85
|
-
return {
|
|
86
|
-
algorithm: 'scrypt',
|
|
87
|
-
hash: s[5],
|
|
88
|
-
salt: s[2],
|
|
89
|
-
params: { n: Number(s[1]), r: Number(s[3]), p: Number(s[4]), encoding: 'base64', salt_encoding: 'utf8' },
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
// ── TOTP ────────────────────────────────────────────────────────────────────
|
|
95
|
-
const B32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
96
|
-
/** RFC 4648 base32, unpadded. */
|
|
97
|
-
function base32(bytes) {
|
|
98
|
-
let out = '';
|
|
99
|
-
let bits = 0;
|
|
100
|
-
let value = 0;
|
|
101
|
-
for (const byte of bytes) {
|
|
102
|
-
value = (value << 8) | byte;
|
|
103
|
-
bits += 8;
|
|
104
|
-
while (bits >= 5) {
|
|
105
|
-
out += B32[(value >>> (bits - 5)) & 31];
|
|
106
|
-
bits -= 5;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (bits > 0)
|
|
110
|
-
out += B32[(value << (5 - bits)) & 31];
|
|
111
|
-
return out;
|
|
112
|
-
}
|
|
113
|
-
/** One authentik user → a user record (null, with the reason omitted, when it is left out). */
|
|
114
|
-
function addUser(c, u, roles) {
|
|
115
|
-
if (u.username === 'AnonymousUser')
|
|
116
|
-
return; // django-guardian's placeholder, never a person
|
|
117
|
-
if (u.type && SERVICE_TYPES.has(u.type)) {
|
|
118
|
-
c.set.omit('user', 'service account (tokens only, no sign-in): recreate it as an Atlas machine client');
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const id = authentikSubject(u, c.subMode, c.installId);
|
|
122
|
-
if (!id) {
|
|
123
|
-
c.set.omit('user', c.subMode === 'user_email' ? 'no email address (the sub mode is user_email)' : `no ${c.subMode} value`);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
const email = u.email?.toLowerCase();
|
|
127
|
-
if (!email && !u.username) {
|
|
128
|
-
c.set.omit('user', 'no email or username');
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (c.used.has(id)) {
|
|
132
|
-
c.set.omit('user', `two users share the same ${c.subMode} (the first one is kept)`);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
const verified = c.trustEmails || u.attributes.email_verified === true || u.attributes.email_verified === 'true';
|
|
136
|
-
const attributes = Object.fromEntries(Object.entries(u.attributes).filter(([k]) => k !== 'email_verified'));
|
|
137
|
-
const uid = u.uid ?? (c.installId ? authentikUid(u.pk, c.installId) : undefined);
|
|
138
|
-
const password = djangoPassword(u.password);
|
|
139
|
-
const user = (0, record_set_1.compact)({
|
|
140
|
-
id,
|
|
141
|
-
emails: email ? [{ email, verified, primary: true }] : undefined,
|
|
142
|
-
username: u.username && u.username.toLowerCase() !== email ? u.username : undefined,
|
|
143
|
-
name: u.name,
|
|
144
|
-
password: password ?? undefined,
|
|
145
|
-
roles: roles?.length ? roles : undefined,
|
|
146
|
-
banned: u.isActive ? undefined : true,
|
|
147
|
-
ban_reason: u.isActive ? undefined : 'Deactivated in authentik (is_active false)',
|
|
148
|
-
private_metadata: (0, record_set_1.bag)({
|
|
149
|
-
...(Object.keys(attributes).length ? { authentik_attributes: attributes } : {}),
|
|
150
|
-
authentik_pk: u.pk,
|
|
151
|
-
...(u.uuid ? { authentik_uuid: u.uuid } : {}),
|
|
152
|
-
...(uid ? { authentik_uid: uid } : {}),
|
|
153
|
-
...(u.path && u.path !== 'users' ? { authentik_path: u.path } : {}),
|
|
154
|
-
...(u.type && u.type !== 'internal' ? { authentik_type: u.type } : {}),
|
|
155
|
-
}),
|
|
156
|
-
created_at: u.dateJoined,
|
|
157
|
-
last_sign_in_at: u.lastLogin,
|
|
158
|
-
});
|
|
159
|
-
c.ids.set(u.pk, id);
|
|
160
|
-
c.used.add(id);
|
|
161
|
-
c.set.add('user', user);
|
|
162
|
-
}
|
|
163
|
-
/** Groups (with their ancestors) → role keys / organizations; returns pk → role keys for the users. */
|
|
164
|
-
class GroupMapper {
|
|
165
|
-
set;
|
|
166
|
-
groups;
|
|
167
|
-
mode;
|
|
168
|
-
key = new Map();
|
|
169
|
-
byId = new Map();
|
|
170
|
-
constructor(set, groups, mode) {
|
|
171
|
-
this.set = set;
|
|
172
|
-
this.groups = groups;
|
|
173
|
-
this.mode = mode;
|
|
174
|
-
const used = new Set();
|
|
175
|
-
for (const g of groups) {
|
|
176
|
-
this.byId.set(g.id, g);
|
|
177
|
-
let key = (0, translate_kit_1.keyOf)(g.name);
|
|
178
|
-
while (used.has(key))
|
|
179
|
-
key = `${key}_${g.id.replace(/-/g, '').slice(0, 6)}`;
|
|
180
|
-
used.add(key);
|
|
181
|
-
this.key.set(g.id, key);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
write() {
|
|
185
|
-
if (this.mode === 'skip')
|
|
186
|
-
return;
|
|
187
|
-
for (const g of this.groups) {
|
|
188
|
-
const parents = g.parents.map((p) => this.byId.get(p)?.name).filter((n) => !!n);
|
|
189
|
-
if (this.mode === 'organizations') {
|
|
190
|
-
this.set.add('organization', (0, record_set_1.compact)({
|
|
191
|
-
id: g.id,
|
|
192
|
-
name: g.name,
|
|
193
|
-
slug: this.key.get(g.id).replace(/[_:]/g, '-'),
|
|
194
|
-
public_metadata: (0, record_set_1.bag)({ ...(parents.length ? { authentik_parent_groups: parents } : {}), ...(g.isSuperuser ? { authentik_superuser: true } : {}) }),
|
|
195
|
-
private_metadata: (0, record_set_1.bag)(g.attributes),
|
|
196
|
-
}));
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
this.set.add('role', (0, record_set_1.compact)({ key: this.key.get(g.id), name: g.name, description: parents.length ? `Child of ${parents.join(', ')} in authentik` : undefined, scope: 'app' }));
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if (this.mode === 'organizations' && this.groups.length)
|
|
203
|
-
this.set.add('role', { key: 'member', name: 'Member', scope: 'organization' }, 'member');
|
|
204
|
-
if (this.groups.some((g) => g.parents.length)) {
|
|
205
|
-
this.set.warn('authentik group hierarchy is flattened: each group moves on its own (its parents are noted on it), and a member of a child group is not made a member of the parents.');
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
/** A group and every ancestor (cycles are cut). */
|
|
209
|
-
ancestry(id, seen = new Set()) {
|
|
210
|
-
if (seen.has(id))
|
|
211
|
-
return [];
|
|
212
|
-
seen.add(id);
|
|
213
|
-
const g = this.byId.get(id);
|
|
214
|
-
if (!g)
|
|
215
|
-
return [];
|
|
216
|
-
return [id, ...g.parents.flatMap((p) => this.ancestry(p, seen))];
|
|
217
|
-
}
|
|
218
|
-
/** Superuser through a group or one of its ancestors (authentik's `all_groups()`). */
|
|
219
|
-
superuser(groupIds) {
|
|
220
|
-
return groupIds.some((id) => this.ancestry(id).some((a) => this.byId.get(a)?.isSuperuser));
|
|
221
|
-
}
|
|
222
|
-
has(id) {
|
|
223
|
-
return this.byId.has(id);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
/** Identity provider name + kind for an authentik source. */
|
|
227
|
-
function sourceProvider(slug, providerType) {
|
|
228
|
-
const type = providerType?.toLowerCase();
|
|
229
|
-
if (type && OIDC_SOURCE_TYPES.has(type))
|
|
230
|
-
return { provider: slug, kind: 'oidc' };
|
|
231
|
-
const alias = type !== undefined ? SOURCE_ALIASES[type] : undefined;
|
|
232
|
-
if (alias)
|
|
233
|
-
return { provider: alias, kind: 'oauth' };
|
|
234
|
-
const social = type && alias === undefined ? (0, translate_kit_1.socialKey)(type) : null;
|
|
235
|
-
return { provider: social ?? slug, kind: 'oauth' };
|
|
236
|
-
}
|
|
237
|
-
/** Every user's role keys from groups and RBAC roles. */
|
|
238
|
-
function rolesFor(groups, groupsAs, memberOf, rbac) {
|
|
239
|
-
const out = [];
|
|
240
|
-
if (groupsAs === 'roles')
|
|
241
|
-
for (const g of memberOf)
|
|
242
|
-
if (groups.key.has(g))
|
|
243
|
-
out.push(groups.key.get(g));
|
|
244
|
-
if (groups.superuser(memberOf))
|
|
245
|
-
out.push('admin');
|
|
246
|
-
out.push(...rbac);
|
|
247
|
-
return [...new Set(out)];
|
|
248
|
-
}
|
|
249
|
-
const pushTo = (m, k, v) => m.set(k, [...(m.get(k) ?? []), v]);
|
|
250
|
-
// ── database dump ───────────────────────────────────────────────────────────
|
|
251
|
-
/** A sub mode every OAuth2 provider in the dump agrees on, else undefined (several, or none). */
|
|
252
|
-
function providersSubMode(tables) {
|
|
253
|
-
const modes = [...new Set(tables.rows('authentik_providers_oauth2_oauth2provider').map((r) => (0, tables_1.text)((0, tables_1.col)(r, 'sub_mode')) ?? 'hashed_user_id'))].sort();
|
|
254
|
-
const only = modes.length === 1 ? modes[0] : undefined;
|
|
255
|
-
return { mode: only && exports.AUTHENTIK_SUB_MODES.includes(only) ? only : undefined, modes };
|
|
256
|
-
}
|
|
257
|
-
function exportAuthentikDump(tables, opts = {}) {
|
|
258
|
-
const set = new record_set_1.RecordSet();
|
|
259
|
-
const now = (opts.now ?? new Date()).getTime();
|
|
260
|
-
const userRows = tables.rows('authentik_core_user');
|
|
261
|
-
if (!userRows.length) {
|
|
262
|
-
set.warn('No authentik_core_user rows in the dump: dump authentik\'s database tables (see the guide) and pass the directory.');
|
|
263
|
-
return set;
|
|
264
|
-
}
|
|
265
|
-
const providers = providersSubMode(tables);
|
|
266
|
-
const subMode = opts.subMode ?? providers.mode ?? 'hashed_user_id';
|
|
267
|
-
if (providers.modes.length > 1) {
|
|
268
|
-
set.warn(`authentik providers use different sub modes (${providers.modes.join(', ')}): users are keyed by ${subMode}; tokens from the other providers do not bridge (their ids are kept in private metadata).`);
|
|
269
|
-
}
|
|
270
|
-
else if (opts.subMode && providers.mode && providers.mode !== opts.subMode) {
|
|
271
|
-
set.warn(`The dump's OAuth2 providers use sub mode ${providers.mode}, but the export keys users by ${opts.subMode}: bridged tokens will not match.`);
|
|
272
|
-
}
|
|
273
|
-
const installId = opts.installId ?? (0, tables_1.text)((0, tables_1.col)(tables.rows('authentik_install_id')[0] ?? {}, 'id'));
|
|
274
|
-
if (!installId && subMode === 'hashed_user_id') {
|
|
275
|
-
throw new Error('The authentik install id is needed for the hashed user ids your tokens carry: dump the authentik_install_id table too, or pass --set authentik-install-id=<id> (SELECT id FROM authentik_install_id).');
|
|
276
|
-
}
|
|
277
|
-
const groupsAs = opts.groupsAs ?? 'roles';
|
|
278
|
-
// Groups: the parent column (before 2025.10) or the parentage table (since).
|
|
279
|
-
const parentage = new Map();
|
|
280
|
-
for (const r of tables.rows('authentik_core_groupparentage')) {
|
|
281
|
-
const child = (0, tables_1.text)((0, tables_1.col)(r, 'child_id'));
|
|
282
|
-
const parent = (0, tables_1.text)((0, tables_1.col)(r, 'parent_id'));
|
|
283
|
-
if (child && parent)
|
|
284
|
-
pushTo(parentage, child, parent);
|
|
285
|
-
}
|
|
286
|
-
const groups = [];
|
|
287
|
-
for (const r of tables.rows('authentik_core_group')) {
|
|
288
|
-
const id = (0, tables_1.text)((0, tables_1.col)(r, 'group_uuid', 'id'));
|
|
289
|
-
const name = (0, tables_1.text)((0, tables_1.col)(r, 'name'));
|
|
290
|
-
if (!id || !name)
|
|
291
|
-
continue;
|
|
292
|
-
const legacyParent = (0, tables_1.text)((0, tables_1.col)(r, 'parent_id'));
|
|
293
|
-
groups.push({ id, name, isSuperuser: (0, tables_1.bool)((0, tables_1.col)(r, 'is_superuser')), parents: parentage.get(id) ?? (legacyParent ? [legacyParent] : []), attributes: (0, record_set_1.bag)((0, tables_1.json)((0, tables_1.col)(r, 'attributes'))) });
|
|
294
|
-
}
|
|
295
|
-
const gm = new GroupMapper(set, groups, groupsAs);
|
|
296
|
-
gm.write();
|
|
297
|
-
// User ↔ group: `ak_groups` until 2026.2 renamed it `groups` (the old `groups` table pointed at Django's auth_group).
|
|
298
|
-
const memberRows = tables.find('authentik_core_user_ak_groups')?.rows ?? tables.rows('authentik_core_user_groups');
|
|
299
|
-
const memberOf = new Map();
|
|
300
|
-
for (const r of memberRows) {
|
|
301
|
-
const uid = (0, tables_1.text)((0, tables_1.col)(r, 'user_id'));
|
|
302
|
-
const gid = (0, tables_1.text)((0, tables_1.col)(r, 'group_id'));
|
|
303
|
-
if (uid && gid && gm.has(gid))
|
|
304
|
-
pushTo(memberOf, uid, gid);
|
|
305
|
-
}
|
|
306
|
-
// RBAC roles: assigned to users directly, to groups (many-to-many, or one group per role before 2025.10).
|
|
307
|
-
const roleKey = new Map();
|
|
308
|
-
const roleGroups = new Map();
|
|
309
|
-
for (const r of tables.rows('authentik_rbac_role')) {
|
|
310
|
-
const id = (0, tables_1.text)((0, tables_1.col)(r, 'uuid', 'id'));
|
|
311
|
-
const name = (0, tables_1.text)((0, tables_1.col)(r, 'name'));
|
|
312
|
-
if (!id || !name)
|
|
313
|
-
continue;
|
|
314
|
-
const key = `rbac:${(0, translate_kit_1.keyOf)(name)}`;
|
|
315
|
-
roleKey.set(id, key);
|
|
316
|
-
set.add('role', { key, name, description: 'authentik RBAC role (authentik admin permissions do not carry over)', scope: 'app' }, key);
|
|
317
|
-
const g = (0, tables_1.text)((0, tables_1.col)(r, 'group_id'));
|
|
318
|
-
if (g)
|
|
319
|
-
pushTo(roleGroups, g, id);
|
|
320
|
-
}
|
|
321
|
-
for (const r of tables.rows('authentik_core_group_roles')) {
|
|
322
|
-
const g = (0, tables_1.text)((0, tables_1.col)(r, 'group_id'));
|
|
323
|
-
const role = (0, tables_1.text)((0, tables_1.col)(r, 'role_id'));
|
|
324
|
-
if (g && role)
|
|
325
|
-
pushTo(roleGroups, g, role);
|
|
326
|
-
}
|
|
327
|
-
const userRoles = new Map();
|
|
328
|
-
for (const r of tables.rows('authentik_core_user_roles', 'authentik_rbac_role_users')) {
|
|
329
|
-
const u = (0, tables_1.text)((0, tables_1.col)(r, 'user_id'));
|
|
330
|
-
const role = (0, tables_1.text)((0, tables_1.col)(r, 'role_id'));
|
|
331
|
-
if (u && role)
|
|
332
|
-
pushTo(userRoles, u, role);
|
|
333
|
-
}
|
|
334
|
-
const c = { set, subMode, installId, trustEmails: opts.trustEmails === true, ids: new Map(), used: new Set() };
|
|
335
|
-
let unusable = 0;
|
|
336
|
-
for (const r of userRows) {
|
|
337
|
-
const pk = (0, tables_1.text)((0, tables_1.col)(r, 'id', 'pk'));
|
|
338
|
-
if (!pk)
|
|
339
|
-
continue;
|
|
340
|
-
const digest = (0, tables_1.text)((0, tables_1.col)(r, 'password'));
|
|
341
|
-
const groupsOfUser = memberOf.get(pk) ?? [];
|
|
342
|
-
const rbacIds = new Set([...(userRoles.get(pk) ?? []), ...groupsOfUser.flatMap((g) => gm.ancestry(g)).flatMap((g) => roleGroups.get(g) ?? [])]);
|
|
343
|
-
const rbac = [...roleKey.entries()].filter(([id]) => rbacIds.has(id)).map(([, k]) => k);
|
|
344
|
-
addUser(c, {
|
|
345
|
-
pk,
|
|
346
|
-
uuid: (0, tables_1.text)((0, tables_1.col)(r, 'uuid')),
|
|
347
|
-
username: (0, tables_1.text)((0, tables_1.col)(r, 'username')),
|
|
348
|
-
email: (0, tables_1.text)((0, tables_1.col)(r, 'email')),
|
|
349
|
-
name: (0, tables_1.text)((0, tables_1.col)(r, 'name')),
|
|
350
|
-
password: digest,
|
|
351
|
-
isActive: (0, tables_1.col)(r, 'is_active') === undefined ? true : (0, tables_1.bool)((0, tables_1.col)(r, 'is_active')),
|
|
352
|
-
type: (0, tables_1.text)((0, tables_1.col)(r, 'type')),
|
|
353
|
-
path: (0, tables_1.text)((0, tables_1.col)(r, 'path')),
|
|
354
|
-
attributes: (0, tables_1.json)((0, tables_1.col)(r, 'attributes')) ?? {},
|
|
355
|
-
lastLogin: (0, tables_1.time)((0, tables_1.col)(r, 'last_login')),
|
|
356
|
-
dateJoined: (0, tables_1.time)((0, tables_1.col)(r, 'date_joined')),
|
|
357
|
-
}, rolesFor(gm, groupsAs, groupsOfUser, rbac));
|
|
358
|
-
if (!c.ids.has(pk))
|
|
359
|
-
continue;
|
|
360
|
-
if (!digest || digest.startsWith('!'))
|
|
361
|
-
unusable++;
|
|
362
|
-
else if (!djangoPassword(digest)) {
|
|
363
|
-
set.warn('Some password hashes are in a Django format Atlas cannot verify (legacy MD5 / SHA1 / crypt hashers): those users sign in through lazy migration or reset their password.');
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
if (unusable)
|
|
367
|
-
set.warn(`${unusable} user(s) had no usable password (source-only accounts, or set_unusable_password): they sign in through their linked identities or reset their password.`);
|
|
368
|
-
if (groupsAs === 'organizations') {
|
|
369
|
-
for (const [pk, gids] of memberOf) {
|
|
370
|
-
const id = c.ids.get(pk);
|
|
371
|
-
if (id)
|
|
372
|
-
for (const g of gids)
|
|
373
|
-
set.add('membership', { organization_id: g, user_id: id, role: 'member' }, `${g}:${id}`);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
if (set.list('user').some((u) => u.roles?.includes('admin')))
|
|
377
|
-
set.add('role', { key: 'admin', name: 'Admin', description: 'Members of an authentik superuser group', scope: 'app' }, 'admin');
|
|
378
|
-
addDumpSources(set, tables, c, opts);
|
|
379
|
-
addDumpTokens(set, tables, c, now);
|
|
380
|
-
addDumpFactors(set, tables, c, opts);
|
|
381
|
-
set.manifest = {
|
|
382
|
-
...set.manifest,
|
|
383
|
-
origin: opts.baseUrl ? hostOf(opts.baseUrl) : 'authentik database dump',
|
|
384
|
-
providers: [...new Set(set.list('identity').map((i) => i.provider))].sort(),
|
|
385
|
-
settings: { sub_mode: subMode, groups_as: groupsAs, ...(providers.modes.length ? { provider_sub_modes: providers.modes } : {}) },
|
|
386
|
-
};
|
|
387
|
-
return set;
|
|
388
|
-
}
|
|
389
|
-
function addDumpSources(set, tables, c, opts) {
|
|
390
|
-
const sources = new Map();
|
|
391
|
-
for (const r of tables.rows('authentik_core_source')) {
|
|
392
|
-
const id = (0, tables_1.text)((0, tables_1.col)(r, 'pbm_uuid', 'id'));
|
|
393
|
-
if (id)
|
|
394
|
-
sources.set(id, r);
|
|
395
|
-
}
|
|
396
|
-
const oauth = new Map(tables.rows('authentik_sources_oauth_oauthsource').map((r) => [(0, tables_1.text)((0, tables_1.col)(r, 'source_ptr_id')) ?? '', r]));
|
|
397
|
-
const saml = new Map(tables.rows('authentik_sources_saml_samlsource').map((r) => [(0, tables_1.text)((0, tables_1.col)(r, 'source_ptr_id')) ?? '', r]));
|
|
398
|
-
const certs = new Map(tables.rows('authentik_crypto_certificatekeypair').map((r) => [(0, tables_1.text)((0, tables_1.col)(r, 'kp_uuid', 'id')) ?? '', r]));
|
|
399
|
-
for (const [id, s] of saml) {
|
|
400
|
-
const base = sources.get(id) ?? {};
|
|
401
|
-
const slug = (0, tables_1.text)((0, tables_1.col)(base, 'slug')) ?? id;
|
|
402
|
-
const cert = (0, tables_1.text)((0, tables_1.col)(certs.get((0, tables_1.text)((0, tables_1.col)(s, 'verification_kp_id')) ?? '') ?? {}, 'certificate_data'));
|
|
403
|
-
set.add('sso_connection', (0, record_set_1.compact)({
|
|
404
|
-
id,
|
|
405
|
-
name: (0, tables_1.text)((0, tables_1.col)(base, 'name')) ?? slug,
|
|
406
|
-
protocol: 'saml',
|
|
407
|
-
enabled: (0, tables_1.col)(base, 'enabled') === undefined ? true : (0, tables_1.bool)((0, tables_1.col)(base, 'enabled')),
|
|
408
|
-
saml: (0, record_set_1.compact)({
|
|
409
|
-
idp_sso_url: (0, tables_1.text)((0, tables_1.col)(s, 'sso_url')),
|
|
410
|
-
idp_certificate: cert,
|
|
411
|
-
// authentik's `issuer` is ITS entity id (the SP side); the IdP must be repointed at Atlas's.
|
|
412
|
-
sp_entity_id: (0, tables_1.text)((0, tables_1.col)(s, 'issuer')),
|
|
413
|
-
sp_acs_url: opts.baseUrl ? `${opts.baseUrl.replace(/\/+$/, '')}/source/saml/${slug}/acs/` : undefined,
|
|
414
|
-
}),
|
|
415
|
-
}));
|
|
416
|
-
}
|
|
417
|
-
const oauthConn = new Map(tables.rows('authentik_sources_oauth_useroauthsourceconnection').map((r) => [(0, tables_1.text)((0, tables_1.col)(r, 'usersourceconnection_ptr_id')) ?? '', r]));
|
|
418
|
-
const samlConn = new Map(tables.rows('authentik_sources_saml_usersamlsourceconnection').map((r) => [(0, tables_1.text)((0, tables_1.col)(r, 'usersourceconnection_ptr_id')) ?? '', r]));
|
|
419
|
-
let federated = 0;
|
|
420
|
-
for (const r of tables.rows('authentik_core_usersourceconnection')) {
|
|
421
|
-
const connId = (0, tables_1.text)((0, tables_1.col)(r, 'id'));
|
|
422
|
-
const userId = c.ids.get((0, tables_1.text)((0, tables_1.col)(r, 'user_id')) ?? '');
|
|
423
|
-
const sourceId = (0, tables_1.text)((0, tables_1.col)(r, 'source_id')) ?? '';
|
|
424
|
-
if (!connId || !userId) {
|
|
425
|
-
set.omit('identity', 'source link of a user not in the export');
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
const o = oauthConn.get(connId);
|
|
429
|
-
const sm = samlConn.get(connId);
|
|
430
|
-
// `identifier` moved from the subtables to the base table in 2025.2.
|
|
431
|
-
const identifier = (0, tables_1.text)((0, tables_1.col)(r, 'identifier')) ?? (0, tables_1.text)((0, tables_1.col)(o ?? sm ?? {}, 'identifier'));
|
|
432
|
-
const source = sources.get(sourceId) ?? {};
|
|
433
|
-
const slug = (0, tables_1.text)((0, tables_1.col)(source, 'slug')) ?? sourceId;
|
|
434
|
-
if (!identifier) {
|
|
435
|
-
set.omit('identity', 'source link without an identifier');
|
|
436
|
-
continue;
|
|
437
|
-
}
|
|
438
|
-
if (saml.has(sourceId) || sm) {
|
|
439
|
-
set.add('identity', (0, record_set_1.compact)({ user_id: userId, provider: slug, provider_user_id: identifier, kind: 'saml', sso_connection_id: saml.has(sourceId) ? sourceId : undefined }));
|
|
440
|
-
continue;
|
|
441
|
-
}
|
|
442
|
-
const os = oauth.get(sourceId);
|
|
443
|
-
if (!os && !o) {
|
|
444
|
-
// LDAP / Kerberos / Plex / SCIM links: the account lives in that directory.
|
|
445
|
-
federated++;
|
|
446
|
-
continue;
|
|
447
|
-
}
|
|
448
|
-
const { provider, kind } = sourceProvider(slug, (0, tables_1.text)((0, tables_1.col)(os ?? {}, 'provider_type')));
|
|
449
|
-
set.add('identity', (0, record_set_1.compact)({
|
|
450
|
-
user_id: userId,
|
|
451
|
-
provider,
|
|
452
|
-
provider_user_id: identifier,
|
|
453
|
-
kind,
|
|
454
|
-
access_token: opts.oauthTokens ? (0, tables_1.text)((0, tables_1.col)(o ?? {}, 'access_token')) : undefined,
|
|
455
|
-
refresh_token: opts.oauthTokens ? (0, tables_1.text)((0, tables_1.col)(o ?? {}, 'refresh_token')) : undefined,
|
|
456
|
-
expires_at: opts.oauthTokens ? (0, tables_1.time)((0, tables_1.col)(o ?? {}, 'expires')) : undefined,
|
|
457
|
-
profile: { authentik_source: slug },
|
|
458
|
-
}));
|
|
459
|
-
}
|
|
460
|
-
if (federated) {
|
|
461
|
-
set.omit('identity', 'LDAP / Kerberos / other directory source link: the password lives in that directory (lazy migration against authentik covers these users)', federated);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
function addDumpTokens(set, tables, c, now) {
|
|
465
|
-
for (const r of tables.rows('authentik_core_token')) {
|
|
466
|
-
const intent = (0, tables_1.text)((0, tables_1.col)(r, 'intent'));
|
|
467
|
-
if (intent !== 'api' && intent !== 'app_password') {
|
|
468
|
-
set.omit('api_key', 'recovery / verification token (single-use links, not API keys)');
|
|
469
|
-
continue;
|
|
470
|
-
}
|
|
471
|
-
if ((0, tables_1.text)((0, tables_1.col)(r, 'managed'))) {
|
|
472
|
-
set.omit('api_key', 'token managed by authentik (outposts, internal service accounts)');
|
|
473
|
-
continue;
|
|
474
|
-
}
|
|
475
|
-
const userId = c.ids.get((0, tables_1.text)((0, tables_1.col)(r, 'user_id')) ?? '');
|
|
476
|
-
if (!userId) {
|
|
477
|
-
set.omit('api_key', 'token of a user not in the export (service accounts: issue an Atlas machine credential)');
|
|
478
|
-
continue;
|
|
479
|
-
}
|
|
480
|
-
const expiring = (0, tables_1.col)(r, 'expiring') === undefined ? true : (0, tables_1.bool)((0, tables_1.col)(r, 'expiring'));
|
|
481
|
-
const expires = expiring ? (0, tables_1.timeMs)((0, tables_1.col)(r, 'expires')) : undefined;
|
|
482
|
-
if (expires !== undefined && expires <= now) {
|
|
483
|
-
set.omit('api_key', 'expired');
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
const key = (0, tables_1.text)((0, tables_1.col)(r, 'key'));
|
|
487
|
-
const identifier = (0, tables_1.text)((0, tables_1.col)(r, 'identifier'));
|
|
488
|
-
if (!key || !identifier) {
|
|
489
|
-
set.omit('api_key', 'token without its key');
|
|
490
|
-
continue;
|
|
491
|
-
}
|
|
492
|
-
set.add('api_key', (0, record_set_1.compact)({
|
|
493
|
-
id: (0, tables_1.text)((0, tables_1.col)(r, 'token_uuid')) ?? identifier,
|
|
494
|
-
user_id: userId,
|
|
495
|
-
name: (0, tables_1.text)((0, tables_1.col)(r, 'description')) ? `${identifier} (${(0, tables_1.text)((0, tables_1.col)(r, 'description'))})` : identifier,
|
|
496
|
-
hash: (0, node_crypto_1.createHash)('sha256').update(key, 'utf8').digest('hex'),
|
|
497
|
-
hash_algorithm: 'sha256',
|
|
498
|
-
start: key.slice(0, 4),
|
|
499
|
-
scopes: intent === 'app_password' ? ['authentik:app_password'] : undefined,
|
|
500
|
-
expires_at: expires !== undefined ? new Date(expires).toISOString() : undefined,
|
|
501
|
-
}));
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
function addDumpFactors(set, tables, c, opts) {
|
|
505
|
-
const owner = (r) => c.ids.get((0, tables_1.text)((0, tables_1.col)(r, 'user_id')) ?? '');
|
|
506
|
-
const confirmed = (r) => (0, tables_1.col)(r, 'confirmed') === undefined || (0, tables_1.bool)((0, tables_1.col)(r, 'confirmed'));
|
|
507
|
-
for (const r of tables.rows('authentik_stages_authenticator_totp_totpdevice')) {
|
|
508
|
-
const userId = owner(r);
|
|
509
|
-
if (!userId)
|
|
510
|
-
continue;
|
|
511
|
-
if (!confirmed(r)) {
|
|
512
|
-
set.omit('mfa_factor', 'TOTP device never confirmed');
|
|
513
|
-
continue;
|
|
514
|
-
}
|
|
515
|
-
const hex = (0, tables_1.text)((0, tables_1.col)(r, 'key'));
|
|
516
|
-
if (!hex || !/^([0-9a-f]{2})+$/i.test(hex)) {
|
|
517
|
-
set.omit('mfa_factor', 'TOTP device without a hex seed');
|
|
518
|
-
continue;
|
|
519
|
-
}
|
|
520
|
-
const digits = Number((0, tables_1.col)(r, 'digits') ?? 6);
|
|
521
|
-
const period = Number((0, tables_1.col)(r, 'step') ?? 30);
|
|
522
|
-
if (Number((0, tables_1.col)(r, 't0') ?? 0) !== 0)
|
|
523
|
-
set.warn('Some TOTP devices count steps from a non-zero t0: Atlas counts from the Unix epoch, so those users re-enrol if their codes are refused.');
|
|
524
|
-
const factor = (0, record_set_1.compact)({
|
|
525
|
-
id: `totp_${(0, tables_1.text)((0, tables_1.col)(r, 'id')) ?? userId}`,
|
|
526
|
-
user_id: userId,
|
|
527
|
-
type: 'totp',
|
|
528
|
-
secret_base32: base32(Buffer.from(hex, 'hex')),
|
|
529
|
-
digits: digits === 8 ? 8 : 6,
|
|
530
|
-
period: Number.isFinite(period) && period > 0 ? period : 30,
|
|
531
|
-
algorithm: 'SHA1',
|
|
532
|
-
verified: true,
|
|
533
|
-
created_at: (0, tables_1.time)((0, tables_1.col)(r, 'created')),
|
|
534
|
-
});
|
|
535
|
-
set.add('mfa_factor', factor);
|
|
536
|
-
}
|
|
537
|
-
// Static (recovery) tokens are stored in plaintext and deleted when used: what is left is unused.
|
|
538
|
-
const tokens = new Map();
|
|
539
|
-
for (const t of tables.rows('authentik_stages_authenticator_static_statictoken')) {
|
|
540
|
-
const device = (0, tables_1.text)((0, tables_1.col)(t, 'device_id'));
|
|
541
|
-
const token = (0, tables_1.text)((0, tables_1.col)(t, 'token'));
|
|
542
|
-
if (device && token)
|
|
543
|
-
pushTo(tokens, device, token);
|
|
544
|
-
}
|
|
545
|
-
for (const r of tables.rows('authentik_stages_authenticator_static_staticdevice')) {
|
|
546
|
-
const userId = owner(r);
|
|
547
|
-
const codes = tokens.get((0, tables_1.text)((0, tables_1.col)(r, 'id')) ?? '') ?? [];
|
|
548
|
-
if (!userId || !confirmed(r))
|
|
549
|
-
continue;
|
|
550
|
-
if (!codes.length) {
|
|
551
|
-
set.omit('mfa_factor', 'recovery-code device with no unused codes');
|
|
552
|
-
continue;
|
|
553
|
-
}
|
|
554
|
-
set.add('mfa_factor', { id: `static_${(0, tables_1.text)((0, tables_1.col)(r, 'id'))}`, user_id: userId, type: 'backup_codes', backup_codes: codes, verified: true });
|
|
555
|
-
}
|
|
556
|
-
for (const r of tables.rows('authentik_stages_authenticator_sms_smsdevice')) {
|
|
557
|
-
const userId = owner(r);
|
|
558
|
-
const phone = (0, record_set_1.e164)((0, tables_1.col)(r, 'phone_number'));
|
|
559
|
-
if (!userId || !confirmed(r))
|
|
560
|
-
continue;
|
|
561
|
-
if (!phone) {
|
|
562
|
-
set.omit('mfa_factor', 'SMS device without an E.164 number (hashed numbers cannot move)');
|
|
563
|
-
continue;
|
|
564
|
-
}
|
|
565
|
-
set.add('mfa_factor', { id: `sms_${(0, tables_1.text)((0, tables_1.col)(r, 'id'))}`, user_id: userId, type: 'phone', phone, verified: true });
|
|
566
|
-
}
|
|
567
|
-
for (const r of tables.rows('authentik_stages_authenticator_email_emaildevice')) {
|
|
568
|
-
const userId = owner(r);
|
|
569
|
-
if (!userId || !confirmed(r))
|
|
570
|
-
continue;
|
|
571
|
-
set.add('mfa_factor', { id: `email_${(0, tables_1.text)((0, tables_1.col)(r, 'id'))}`, user_id: userId, type: 'email', verified: true });
|
|
572
|
-
}
|
|
573
|
-
const duo = tables.rows('authentik_stages_authenticator_duo_duodevice').filter((r) => owner(r)).length;
|
|
574
|
-
if (duo)
|
|
575
|
-
set.omit('mfa_factor', 'Duo device (the enrolment lives at Duo): users enrol an Atlas factor', duo);
|
|
576
|
-
let noRp = 0;
|
|
577
|
-
const rps = new Set();
|
|
578
|
-
for (const r of tables.rows('authentik_stages_authenticator_webauthn_webauthndevice')) {
|
|
579
|
-
const userId = owner(r);
|
|
580
|
-
if (!userId)
|
|
581
|
-
continue;
|
|
582
|
-
const credentialId = b64url((0, tables_1.col)(r, 'credential_id'));
|
|
583
|
-
const publicKey = b64url((0, tables_1.col)(r, 'public_key'));
|
|
584
|
-
const rpId = (0, tables_1.text)((0, tables_1.col)(r, 'rp_id')) ?? opts.rpId;
|
|
585
|
-
if (!credentialId || !publicKey) {
|
|
586
|
-
set.omit('passkey', 'WebAuthn device without its credential id or public key');
|
|
587
|
-
continue;
|
|
588
|
-
}
|
|
589
|
-
if (!rpId) {
|
|
590
|
-
noRp++;
|
|
591
|
-
continue;
|
|
592
|
-
}
|
|
593
|
-
rps.add(rpId);
|
|
594
|
-
const aaguid = (0, tables_1.text)((0, tables_1.col)(r, 'aaguid'));
|
|
595
|
-
set.add('passkey', (0, record_set_1.compact)({
|
|
596
|
-
id: `webauthn_${(0, tables_1.text)((0, tables_1.col)(r, 'id'))}`,
|
|
597
|
-
user_id: userId,
|
|
598
|
-
credential_id: credentialId,
|
|
599
|
-
public_key: publicKey,
|
|
600
|
-
sign_count: Number((0, tables_1.col)(r, 'sign_count') ?? 0) || 0,
|
|
601
|
-
rp_id: rpId,
|
|
602
|
-
aaguid: aaguid && aaguid !== '00000000-0000-0000-0000-000000000000' ? aaguid : undefined,
|
|
603
|
-
name: (0, tables_1.text)((0, tables_1.col)(r, 'name')),
|
|
604
|
-
created_at: (0, tables_1.time)((0, tables_1.col)(r, 'created_on')),
|
|
605
|
-
}));
|
|
606
|
-
}
|
|
607
|
-
if (noRp)
|
|
608
|
-
set.omit('passkey', 'registered before authentik stored the RP id: pass --set rp-id=<authentik host>', noRp);
|
|
609
|
-
if (rps.size === 1)
|
|
610
|
-
set.manifest.rpId = [...rps][0];
|
|
611
|
-
if (rps.size)
|
|
612
|
-
set.warn(`Passkeys only work on the domain they were registered for (${[...rps].join(', ')}): serve Atlas sign-in there, or users register them again.`);
|
|
613
|
-
}
|
|
614
|
-
/** authentik stores WebAuthn ids/keys as base64url; accept padded / standard base64 too. */
|
|
615
|
-
function b64url(v) {
|
|
616
|
-
const s = (0, tables_1.text)(v);
|
|
617
|
-
if (!s || !/^[A-Za-z0-9+/_-]+={0,2}$/.test(s))
|
|
618
|
-
return undefined;
|
|
619
|
-
return Buffer.from(s.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('base64url');
|
|
620
|
-
}
|
|
621
|
-
function hostOf(url) {
|
|
622
|
-
return url.replace(/^https?:\/\//, '').replace(/\/+$/, '');
|
|
623
|
-
}
|
|
624
|
-
// ── API ─────────────────────────────────────────────────────────────────────
|
|
625
|
-
/** Every page of an authentik list endpoint (`{ pagination: { next }, results }`, next = 0 on the last page). */
|
|
626
|
-
async function authentikList(http, path) {
|
|
627
|
-
const out = [];
|
|
628
|
-
const sep = path.includes('?') ? '&' : '?';
|
|
629
|
-
for (let page = 1, guard = 0; page > 0 && guard < 10_000; guard++) {
|
|
630
|
-
const { body } = await http.get(`${path}${sep}page=${page}&page_size=100`);
|
|
631
|
-
out.push(...(0, record_set_1.objs)(body?.results));
|
|
632
|
-
const next = Number(body?.pagination?.next ?? 0);
|
|
633
|
-
page = Number.isFinite(next) && next > page ? next : 0;
|
|
634
|
-
}
|
|
635
|
-
return out;
|
|
636
|
-
}
|
|
637
|
-
/** A list endpoint the token may not reach (or an older authentik lacks): empty, with a warning. */
|
|
638
|
-
async function optionalList(set, http, path, what) {
|
|
639
|
-
try {
|
|
640
|
-
return await authentikList(http, path);
|
|
641
|
-
}
|
|
642
|
-
catch (err) {
|
|
643
|
-
if (err instanceof vendor_http_1.VendorApiError && [403, 404].includes(err.status)) {
|
|
644
|
-
set.warn(`${what} could not be read with this token (${err.status}): skipped.`);
|
|
645
|
-
return [];
|
|
646
|
-
}
|
|
647
|
-
throw err;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
async function exportAuthentikApi(opts) {
|
|
651
|
-
const base = opts.baseUrl.replace(/\/+$/, '');
|
|
652
|
-
if (!/^https?:\/\/[^/\s]+/.test(base))
|
|
653
|
-
throw new Error(`Not an authentik URL: ${opts.baseUrl}`);
|
|
654
|
-
const set = new record_set_1.RecordSet();
|
|
655
|
-
const now = (opts.now ?? new Date()).getTime();
|
|
656
|
-
const progress = opts.onProgress ?? (() => undefined);
|
|
657
|
-
const http = new vendor_http_1.VendorHttp({ vendor: 'authentik', baseUrl: `${base}/api/v3`, headers: { authorization: `Bearer ${opts.token}` }, fetchImpl: opts.fetchImpl, sleep: opts.sleep });
|
|
658
|
-
const groupsAs = opts.groupsAs ?? 'roles';
|
|
659
|
-
const subMode = opts.subMode ?? 'hashed_user_id';
|
|
660
|
-
progress('groups');
|
|
661
|
-
const rawGroups = groupsAs === 'skip' ? [] : await authentikList(http, '/core/groups/?include_users=false');
|
|
662
|
-
const groups = rawGroups
|
|
663
|
-
.map((g) => ({
|
|
664
|
-
id: (0, record_set_1.str)(g.pk) ?? '',
|
|
665
|
-
name: (0, record_set_1.str)(g.name) ?? '',
|
|
666
|
-
isSuperuser: g.is_superuser === true,
|
|
667
|
-
// `parents` (a list) since 2025.10, `parent` before.
|
|
668
|
-
parents: Array.isArray(g.parents) ? (0, record_set_1.strs)(g.parents) : (0, record_set_1.str)(g.parent) ? [(0, record_set_1.str)(g.parent)] : [],
|
|
669
|
-
attributes: (0, record_set_1.bag)(g.attributes),
|
|
670
|
-
}))
|
|
671
|
-
.filter((g) => g.id && g.name);
|
|
672
|
-
const gm = new GroupMapper(set, groups, groupsAs);
|
|
673
|
-
gm.write();
|
|
674
|
-
progress('roles');
|
|
675
|
-
const roleKey = new Map();
|
|
676
|
-
for (const r of await optionalList(set, http, '/rbac/roles/', 'RBAC roles')) {
|
|
677
|
-
const id = (0, record_set_1.str)(r.pk);
|
|
678
|
-
const name = (0, record_set_1.str)(r.name);
|
|
679
|
-
if (!id || !name)
|
|
680
|
-
continue;
|
|
681
|
-
const key = `rbac:${(0, translate_kit_1.keyOf)(name)}`;
|
|
682
|
-
roleKey.set(id, key);
|
|
683
|
-
set.add('role', { key, name, description: 'authentik RBAC role (authentik admin permissions do not carry over)', scope: 'app' }, key);
|
|
684
|
-
}
|
|
685
|
-
const groupRoles = new Map(rawGroups.map((g) => [(0, record_set_1.str)(g.pk) ?? '', (0, record_set_1.strs)(g.roles)]));
|
|
686
|
-
progress('users');
|
|
687
|
-
const c = { set, subMode, installId: opts.installId, trustEmails: opts.trustEmails === true, ids: new Map(), used: new Set() };
|
|
688
|
-
const memberOf = new Map();
|
|
689
|
-
for (const u of await authentikList(http, '/core/users/?include_groups=false')) {
|
|
690
|
-
const pk = (0, record_set_1.str)(u.pk);
|
|
691
|
-
if (!pk)
|
|
692
|
-
continue;
|
|
693
|
-
const gids = (0, record_set_1.strs)(u.groups).filter((g) => gm.has(g));
|
|
694
|
-
memberOf.set(pk, gids);
|
|
695
|
-
const rbacIds = new Set([...(0, record_set_1.strs)(u.roles), ...gids.flatMap((g) => gm.ancestry(g)).flatMap((g) => groupRoles.get(g) ?? [])]);
|
|
696
|
-
const rbac = [...roleKey.entries()].filter(([id]) => rbacIds.has(id)).map(([, k]) => k);
|
|
697
|
-
addUser(c, {
|
|
698
|
-
pk,
|
|
699
|
-
uuid: (0, record_set_1.str)(u.uuid),
|
|
700
|
-
uid: (0, record_set_1.str)(u.uid),
|
|
701
|
-
username: (0, record_set_1.str)(u.username),
|
|
702
|
-
email: (0, record_set_1.str)(u.email),
|
|
703
|
-
name: (0, record_set_1.str)(u.name),
|
|
704
|
-
isActive: u.is_active !== false,
|
|
705
|
-
type: (0, record_set_1.str)(u.type),
|
|
706
|
-
path: (0, record_set_1.str)(u.path),
|
|
707
|
-
attributes: (0, record_set_1.isObj)(u.attributes) ? u.attributes : {},
|
|
708
|
-
lastLogin: (0, record_set_1.str)(u.last_login),
|
|
709
|
-
dateJoined: (0, record_set_1.str)(u.date_joined),
|
|
710
|
-
}, rolesFor(gm, groupsAs, gids, rbac));
|
|
711
|
-
}
|
|
712
|
-
if (groupsAs === 'organizations') {
|
|
713
|
-
for (const [pk, gids] of memberOf) {
|
|
714
|
-
const id = c.ids.get(pk);
|
|
715
|
-
if (id)
|
|
716
|
-
for (const g of gids)
|
|
717
|
-
set.add('membership', { organization_id: g, user_id: id, role: 'member' }, `${g}:${id}`);
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
if (set.list('user').some((u) => u.roles?.includes('admin')))
|
|
721
|
-
set.add('role', { key: 'admin', name: 'Admin', description: 'Members of an authentik superuser group', scope: 'app' }, 'admin');
|
|
722
|
-
if (c.ids.size) {
|
|
723
|
-
set.warn("authentik's API never returns password hashes or authenticator secrets: turn on the authentik lazy-migration preset (passwords are checked against authentik's flow executor on first sign-in), or export from a database dump to move hashes, TOTP seeds, recovery codes and passkeys.");
|
|
724
|
-
}
|
|
725
|
-
progress('sources');
|
|
726
|
-
const oauthSources = new Map((await optionalList(set, http, '/sources/oauth/', 'OAuth sources')).map((s) => [(0, record_set_1.str)(s.slug) ?? '', s]));
|
|
727
|
-
for (const s of await optionalList(set, http, '/sources/saml/', 'SAML sources')) {
|
|
728
|
-
const id = (0, record_set_1.str)(s.pk);
|
|
729
|
-
const slug = (0, record_set_1.str)(s.slug);
|
|
730
|
-
if (!id || !slug)
|
|
731
|
-
continue;
|
|
732
|
-
let cert;
|
|
733
|
-
const kp = (0, record_set_1.str)(s.verification_kp);
|
|
734
|
-
if (kp) {
|
|
735
|
-
try {
|
|
736
|
-
const { body } = await http.get(`/crypto/certificatekeypairs/${encodeURIComponent(kp)}/view_certificate/`);
|
|
737
|
-
cert = (0, record_set_1.str)(body?.data);
|
|
738
|
-
}
|
|
739
|
-
catch (err) {
|
|
740
|
-
if (!(err instanceof vendor_http_1.VendorApiError))
|
|
741
|
-
throw err;
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
set.add('sso_connection', (0, record_set_1.compact)({
|
|
745
|
-
id,
|
|
746
|
-
name: (0, record_set_1.str)(s.name) ?? slug,
|
|
747
|
-
protocol: 'saml',
|
|
748
|
-
enabled: s.enabled !== false,
|
|
749
|
-
saml: (0, record_set_1.compact)({ idp_sso_url: (0, record_set_1.str)(s.sso_url), idp_certificate: cert, sp_entity_id: (0, record_set_1.str)(s.issuer), sp_acs_url: `${base}/source/saml/${slug}/acs/` }),
|
|
750
|
-
}));
|
|
751
|
-
}
|
|
752
|
-
const samlIds = new Set(set.list('sso_connection').map((s) => s.id));
|
|
753
|
-
for (const [path, kind] of [
|
|
754
|
-
['/sources/user_connections/oauth/', 'oauth'],
|
|
755
|
-
['/sources/user_connections/saml/', 'saml'],
|
|
756
|
-
]) {
|
|
757
|
-
for (const conn of await optionalList(set, http, path, `${kind.toUpperCase()} source links`)) {
|
|
758
|
-
const userId = c.ids.get((0, record_set_1.str)(conn.user) ?? '');
|
|
759
|
-
const source = (0, record_set_1.isObj)(conn.source_obj) ? conn.source_obj : (0, record_set_1.isObj)(conn.source) ? conn.source : {};
|
|
760
|
-
const slug = (0, record_set_1.str)(source.slug);
|
|
761
|
-
const identifier = (0, record_set_1.str)(conn.identifier);
|
|
762
|
-
if (!userId || !slug || !identifier) {
|
|
763
|
-
set.omit('identity', 'source link of a user not in the export');
|
|
764
|
-
continue;
|
|
765
|
-
}
|
|
766
|
-
if (kind === 'saml') {
|
|
767
|
-
const sid = (0, record_set_1.str)(source.pk);
|
|
768
|
-
set.add('identity', (0, record_set_1.compact)({ user_id: userId, provider: slug, provider_user_id: identifier, kind: 'saml', sso_connection_id: sid && samlIds.has(sid) ? sid : undefined }));
|
|
769
|
-
continue;
|
|
770
|
-
}
|
|
771
|
-
const { provider, kind: k } = sourceProvider(slug, (0, record_set_1.str)(oauthSources.get(slug)?.provider_type) ?? (0, record_set_1.str)(source.provider_type));
|
|
772
|
-
set.add('identity', { user_id: userId, provider, provider_user_id: identifier, kind: k, profile: { authentik_source: slug } });
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
progress('tokens');
|
|
776
|
-
for (const t of await optionalList(set, http, '/core/tokens/', 'Tokens')) {
|
|
777
|
-
const intent = (0, record_set_1.str)(t.intent);
|
|
778
|
-
const identifier = (0, record_set_1.str)(t.identifier);
|
|
779
|
-
if (intent !== 'api' && intent !== 'app_password') {
|
|
780
|
-
set.omit('api_key', 'recovery / verification token (single-use links, not API keys)');
|
|
781
|
-
continue;
|
|
782
|
-
}
|
|
783
|
-
if ((0, record_set_1.str)(t.managed)) {
|
|
784
|
-
set.omit('api_key', 'token managed by authentik (outposts, internal service accounts)');
|
|
785
|
-
continue;
|
|
786
|
-
}
|
|
787
|
-
const userId = c.ids.get((0, record_set_1.str)(t.user) ?? '');
|
|
788
|
-
if (!userId || !identifier) {
|
|
789
|
-
set.omit('api_key', 'token of a user not in the export (service accounts: issue an Atlas machine credential)');
|
|
790
|
-
continue;
|
|
791
|
-
}
|
|
792
|
-
const expires = t.expiring !== false && (0, record_set_1.str)(t.expires) ? Date.parse((0, record_set_1.str)(t.expires)) : undefined;
|
|
793
|
-
if (expires !== undefined && Number.isFinite(expires) && expires <= now) {
|
|
794
|
-
set.omit('api_key', 'expired');
|
|
795
|
-
continue;
|
|
796
|
-
}
|
|
797
|
-
let key;
|
|
798
|
-
try {
|
|
799
|
-
const { body } = await http.get(`/core/tokens/${encodeURIComponent(identifier)}/view_key/`);
|
|
800
|
-
key = (0, record_set_1.str)(body?.key);
|
|
801
|
-
}
|
|
802
|
-
catch (err) {
|
|
803
|
-
if (!(err instanceof vendor_http_1.VendorApiError))
|
|
804
|
-
throw err;
|
|
805
|
-
}
|
|
806
|
-
if (!key) {
|
|
807
|
-
set.omit('api_key', 'the token key was not readable (view_key needs the "View token key" permission)');
|
|
808
|
-
continue;
|
|
809
|
-
}
|
|
810
|
-
set.add('api_key', (0, record_set_1.compact)({
|
|
811
|
-
id: identifier,
|
|
812
|
-
user_id: userId,
|
|
813
|
-
name: (0, record_set_1.str)(t.description) ? `${identifier} (${(0, record_set_1.str)(t.description)})` : identifier,
|
|
814
|
-
hash: (0, node_crypto_1.createHash)('sha256').update(key, 'utf8').digest('hex'),
|
|
815
|
-
hash_algorithm: 'sha256',
|
|
816
|
-
start: key.slice(0, 4),
|
|
817
|
-
scopes: intent === 'app_password' ? ['authentik:app_password'] : undefined,
|
|
818
|
-
expires_at: expires !== undefined && Number.isFinite(expires) ? new Date(expires).toISOString() : undefined,
|
|
819
|
-
}));
|
|
820
|
-
}
|
|
821
|
-
progress('authenticators');
|
|
822
|
-
for (const [path, label] of [
|
|
823
|
-
['/authenticators/admin/totp/', 'TOTP device'],
|
|
824
|
-
['/authenticators/admin/static/', 'recovery-code device'],
|
|
825
|
-
['/authenticators/admin/webauthn/', 'WebAuthn device'],
|
|
826
|
-
]) {
|
|
827
|
-
const n = (await optionalList(set, http, path, `${label}s`)).length;
|
|
828
|
-
if (n)
|
|
829
|
-
set.omit(path.includes('webauthn') ? 'passkey' : 'mfa_factor', `${label}: the API never returns its secret (export from a database dump to move it; otherwise users re-enrol)`, n);
|
|
830
|
-
}
|
|
831
|
-
set.manifest = {
|
|
832
|
-
origin: hostOf(base),
|
|
833
|
-
providers: [...new Set(set.list('identity').map((i) => i.provider))].sort(),
|
|
834
|
-
settings: { sub_mode: subMode, groups_as: groupsAs },
|
|
835
|
-
};
|
|
836
|
-
return set;
|
|
837
|
-
}
|
|
838
|
-
//# sourceMappingURL=authentik.js.map
|