@atlasauth/cli 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/args.d.ts +155 -0
- package/dist/args.js +66 -1
- package/dist/args.js.map +1 -1
- package/dist/commands/auth.js +5 -1
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/config.d.ts +56 -1
- package/dist/commands/config.js +188 -29
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/csp.d.ts +32 -0
- package/dist/commands/csp.js +180 -0
- package/dist/commands/csp.js.map +1 -0
- package/dist/commands/import-better-auth.d.ts +3 -0
- package/dist/commands/import-better-auth.js +164 -0
- package/dist/commands/import-better-auth.js.map +1 -0
- package/dist/commands/import.js +7 -0
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/info.js +1 -1
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +26 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/integrations.d.ts +8 -0
- package/dist/commands/integrations.js +112 -0
- package/dist/commands/integrations.js.map +1 -0
- package/dist/commands/listen.d.ts +17 -0
- package/dist/commands/listen.js +223 -0
- package/dist/commands/listen.js.map +1 -0
- package/dist/commands/migrate.js +40 -1
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/move-origin.d.ts +11 -0
- package/dist/commands/move-origin.js +95 -0
- package/dist/commands/move-origin.js.map +1 -0
- package/dist/commands/operator.d.ts +26 -0
- package/dist/commands/operator.js +198 -0
- package/dist/commands/operator.js.map +1 -0
- package/dist/commands/project-commands.d.ts +12 -0
- package/dist/commands/project-commands.js +130 -30
- package/dist/commands/project-commands.js.map +1 -1
- package/dist/commands/referrals.d.ts +4 -4
- package/dist/commands/referrals.js +203 -33
- package/dist/commands/referrals.js.map +1 -1
- package/dist/commands/shared.d.ts +6 -0
- package/dist/commands/shared.js +10 -1
- package/dist/commands/shared.js.map +1 -1
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.js +77 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/webhooks.d.ts +29 -2
- package/dist/commands/webhooks.js +257 -24
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/config.d.ts +14 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +13 -0
- package/dist/context.js.map +1 -1
- package/dist/help.d.ts +1 -1
- package/dist/help.js +221 -17
- package/dist/help.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/migrate/better-auth/integration.d.ts +59 -0
- package/dist/migrate/better-auth/integration.js +81 -0
- package/dist/migrate/better-auth/integration.js.map +1 -0
- package/dist/migrate/better-auth/orchestrator.d.ts +43 -0
- package/dist/migrate/better-auth/orchestrator.js +525 -0
- package/dist/migrate/better-auth/orchestrator.js.map +1 -0
- package/dist/migrate/better-auth/output.d.ts +20 -0
- package/dist/migrate/better-auth/output.js +146 -0
- package/dist/migrate/better-auth/output.js.map +1 -0
- package/dist/migrate/better-auth/translate.d.ts +77 -0
- package/dist/migrate/better-auth/translate.js +1989 -0
- package/dist/migrate/better-auth/translate.js.map +1 -0
- package/dist/run.js +14 -0
- package/dist/run.js.map +1 -1
- package/package.json +5 -4
package/dist/help.js
CHANGED
|
@@ -12,27 +12,44 @@ Usage: atlas <command> [subcommand] [arguments] [options]
|
|
|
12
12
|
|
|
13
13
|
Commands:
|
|
14
14
|
login Authenticate and store a profile credential
|
|
15
|
+
(--device: operator sign-in in the browser, no key stored)
|
|
16
|
+
token --resource <id> A one-hour token for one instance/app from your operator sign-in
|
|
17
|
+
keys whoami|list|create|rotate|revoke|revoke-leaked
|
|
18
|
+
Scoped secret keys; new secrets go sealed into 0600 files
|
|
15
19
|
logout Remove a stored profile credential
|
|
16
20
|
whoami Show the active profile and instance
|
|
17
21
|
users list|get|create|delete
|
|
18
22
|
orgs list|get|members
|
|
19
23
|
api-keys list|create|revoke
|
|
20
|
-
webhooks list|create
|
|
24
|
+
webhooks list|create|upsert|update|test|deliveries|redeliver|replay|rotate|reveal
|
|
25
|
+
listen --forward-to <url> Forward live events to your local server, signed (no tunnel)
|
|
26
|
+
move-origin --from --to Move an app to a new domain in one step (--dry-run first)
|
|
27
|
+
csp --framework next|express|nginx
|
|
28
|
+
Print the Content Security Policy sources Atlas needs
|
|
29
|
+
integrations list|get|set|remove|deliveries Identity integrations (chat, docs, consent, referrals, custom)
|
|
21
30
|
sessions revoke
|
|
22
|
-
config export|import
|
|
31
|
+
config export|import|plan Config-as-code: round-trip the instance's config; plan = drift diff
|
|
23
32
|
actions list|deploy|test|logs|gallery|show|install|installs|update|publish
|
|
24
33
|
init Create or complete an app's setup (idempotent); secrets to 0600 files
|
|
25
34
|
preflight Check an instance's setup; non-zero exit on errors (for CI)
|
|
35
|
+
doctor Integration health: webhooks, logout, referrals, email, consent (exit 1 on a failure)
|
|
26
36
|
env Print deploy variables: public values + secret file paths
|
|
27
37
|
client rotate Rotate an OAuth client secret straight into its file
|
|
28
38
|
referrals connect|backfill|status
|
|
29
39
|
Connect a referral platform, backfill, check the connection
|
|
40
|
+
status Atlas status, incidents that concern the instance and its
|
|
41
|
+
upstream status pages; non-zero exit on an outage
|
|
30
42
|
import --from <vendor> <file>
|
|
31
43
|
Move users from Auth0, Clerk, Supabase, Firebase, Cognito,
|
|
32
44
|
Auth.js, WorkOS or Better Auth (resumable; --dry-run first)
|
|
33
45
|
migrate code --from <vendor> [path]
|
|
34
46
|
Rewrite an app's auth code onto Atlas (Clerk, Auth.js,
|
|
35
47
|
Supabase, Auth0, Better Auth); a dry run with a diff unless --yes
|
|
48
|
+
migrate better-auth [path] Move a Better Auth app to Atlas end to end: config, users,
|
|
49
|
+
sessions and code, resumable (--dry-run, --resume, --yes)
|
|
50
|
+
migrate better-auth config [path]
|
|
51
|
+
Translate the app's betterAuth({...}) options into Atlas
|
|
52
|
+
config files plus a report (offline)
|
|
36
53
|
info [path] Print the environment for a support ticket (versions, SDKs,
|
|
37
54
|
instance, API latency, preflight); secrets redacted
|
|
38
55
|
mcp install Add the Atlas MCP server (docs search) to Cursor, Claude Code,
|
|
@@ -48,10 +65,12 @@ Global options:
|
|
|
48
65
|
|
|
49
66
|
Environment overrides:
|
|
50
67
|
ATLAS_SECRET_KEY Secret key to use instead of the stored one
|
|
51
|
-
|
|
68
|
+
ATLAS_API_BASE API URL to use instead of the stored one
|
|
69
|
+
ATLAS_API_URL Same (the older name); ATLAS_API_BASE wins when both are set
|
|
52
70
|
ATLAS_PLATFORM_KEY Platform key (psk_) for atlas init
|
|
53
|
-
|
|
54
|
-
|
|
71
|
+
REFERALLI_BASE_URL Referalli base URL for atlas referrals connect
|
|
72
|
+
REFERALLI_API_KEY Referalli merchant key for atlas referrals connect (never stored)
|
|
73
|
+
(the old REFERALLY_BASE_URL / REFERALLY_API_KEY still work, with a notice)
|
|
55
74
|
|
|
56
75
|
Secrets: a command that receives a secret writes it to a 0600 file under
|
|
57
76
|
~/.config/<product>/ and prints only the path. --print-secret prints it instead.
|
|
@@ -59,10 +78,38 @@ Secrets: a command that receives a secret writes it to a 0600 file under
|
|
|
59
78
|
Run 'atlas <command> --help' for command-specific help.`;
|
|
60
79
|
/** Per-command help, keyed by the resource word. */
|
|
61
80
|
exports.COMMAND_HELP = {
|
|
62
|
-
migrate: `atlas migrate
|
|
81
|
+
migrate: `atlas migrate — move an app's auth onto Atlas
|
|
63
82
|
|
|
64
83
|
Usage:
|
|
65
84
|
atlas migrate code --from <vendor> [path] [--yes] [--json]
|
|
85
|
+
atlas migrate better-auth config [path] [--dir <dir>] [--format json|yaml] [--entry <file>] [--json]
|
|
86
|
+
atlas migrate better-auth [path] [--dry-run] [--yes] [--resume] [--force] [--json]
|
|
87
|
+
[--dir <dir>] [--state-file <file>] [--entry <file>] [--bundle <file>] [--run-export]
|
|
88
|
+
[--confirm-conflicts] [--bridge-days <n>] [--skip <step,...>]
|
|
89
|
+
|
|
90
|
+
migrate better-auth config reads your betterAuth({...}) setup statically (it
|
|
91
|
+
follows imports and resolves env vars by NAME, never their values) and writes
|
|
92
|
+
Atlas config-as-code files (the 'atlas config import' format) plus
|
|
93
|
+
better-auth-report.md: what maps 1:1, what maps with a difference, and what
|
|
94
|
+
needs a manual step, each with file:line. Default --dir: atlas-migrate/config.
|
|
95
|
+
|
|
96
|
+
migrate better-auth runs the whole program, checkpointing each step in
|
|
97
|
+
atlas-migrate/state.json (--state-file):
|
|
98
|
+
preflight instance and key, CLI version, the betterAuth() call
|
|
99
|
+
translate the config files and report (as above)
|
|
100
|
+
apply review the diff, confirm, push the config (env placeholders are
|
|
101
|
+
filled from the environment and the app's .env files)
|
|
102
|
+
export run the exporter in the app (prints the command; --run-export runs it)
|
|
103
|
+
import upload the bundle, dry-run report, confirm, import (conflicts with
|
|
104
|
+
existing Atlas users need --confirm-conflicts; a stopped import resumes)
|
|
105
|
+
bridge accept Better Auth sessions for --bridge-days (default 30): no forced logout
|
|
106
|
+
code atlas migrate code --from better-auth, after a confirmation
|
|
107
|
+
verify counts, preflight and a sign-in checklist
|
|
108
|
+
--dry-run walks every step without changing the instance or the code. --yes
|
|
109
|
+
answers every confirmation. --resume continues a stopped run. --json prints the
|
|
110
|
+
step summary (with --json and no --yes it stops at the first confirmation).
|
|
111
|
+
|
|
112
|
+
Code rewrite (migrate code):
|
|
66
113
|
|
|
67
114
|
Vendors:
|
|
68
115
|
clerk @clerk/* SDKs
|
|
@@ -71,6 +118,10 @@ Vendors:
|
|
|
71
118
|
Supabase client itself stays for your database
|
|
72
119
|
auth0 @auth0/auth0-react, @auth0/nextjs-auth0 (v3 and v4), @auth0/auth0-spa-js
|
|
73
120
|
better-auth better-auth (client, server, Next.js handler, cookies)
|
|
121
|
+
openid-client openid-client (Issuer.discover, authorizationUrl, callback, endSessionUrl)
|
|
122
|
+
jose jose used to verify OIDC ID tokens (jwtVerify + createRemoteJWKSet)
|
|
123
|
+
generic-oidc a hand-rolled relying party (discovery, PKCE, code exchange, JWKS) found
|
|
124
|
+
by its code; replaced by oidc.start / oidc.callback / oidc.logoutUrl
|
|
74
125
|
|
|
75
126
|
What it rewrites: imports, providers, hooks, server session helpers, middleware,
|
|
76
127
|
sign-in/out calls and env var names, onto native Atlas APIs and the drop-in
|
|
@@ -100,6 +151,9 @@ reported, not fatal. Anything shaped like a secret is redacted.`,
|
|
|
100
151
|
|
|
101
152
|
Usage:
|
|
102
153
|
atlas import --from <vendor> <export-file> [--dry-run]
|
|
154
|
+
atlas import --from better-auth --bundle <file> [--dry-run] [--yes]
|
|
155
|
+
atlas import --from better-auth --import <id> [--confirm-conflicts]
|
|
156
|
+
atlas import --from better-auth (prints the import key and export command)
|
|
103
157
|
|
|
104
158
|
Vendors and the file each one reads:
|
|
105
159
|
auth0 the user export job (NDJSON/JSON); --hashes <file> merges the password export
|
|
@@ -120,6 +174,13 @@ Options:
|
|
|
120
174
|
--create-orgs Create organizations that memberships name but that do not exist yet
|
|
121
175
|
--json Machine-readable summary
|
|
122
176
|
|
|
177
|
+
Better Auth bundle (npx atlas-better-auth-export --out <file> --public-key <key>):
|
|
178
|
+
--bundle <file> Upload the sealed bundle, show the dry run, then apply
|
|
179
|
+
--import <id> Continue an uploaded import (apply it, or resume a failed one)
|
|
180
|
+
--confirm-conflicts Apply although the dry run found conflicts with existing users
|
|
181
|
+
--options <json|@file> Import options, e.g. '{"import_sessions":false}'
|
|
182
|
+
--yes Apply without asking
|
|
183
|
+
|
|
123
184
|
Batches are sent with upsert, so a resumed or repeated run never duplicates a
|
|
124
185
|
user or a membership. Exit code 2 means some rows were reported as issues.`,
|
|
125
186
|
mcp: `atlas mcp — connect AI coding agents to Atlas
|
|
@@ -138,20 +199,47 @@ agent can search and read the Atlas docs. Servers already in the file are kept.
|
|
|
138
199
|
|
|
139
200
|
No key is written. To also manage your instance from the agent, add
|
|
140
201
|
ATLAS_SECRET_KEY to the server's env yourself.`,
|
|
202
|
+
status: `atlas status — is it Atlas, a service you depend on, or you?
|
|
203
|
+
|
|
204
|
+
Usage:
|
|
205
|
+
atlas status [--json]
|
|
206
|
+
|
|
207
|
+
Shows Atlas's components (with their regions), the open Atlas incidents that
|
|
208
|
+
concern this instance (its status subscription's regions, components and
|
|
209
|
+
minimum impact), the subscription itself, and the state of every upstream
|
|
210
|
+
status page the instance declared (POST /v1/instance/status_dependencies).
|
|
211
|
+
|
|
212
|
+
Exit code 1 when Atlas reports a major outage or an open major / critical
|
|
213
|
+
incident concerns the instance, or an enabled upstream status page reports a
|
|
214
|
+
partial or major outage; 0 otherwise.`,
|
|
141
215
|
referrals: `atlas referrals — referral attribution
|
|
142
216
|
|
|
143
217
|
Usage:
|
|
144
|
-
atlas referrals connect --provider
|
|
145
|
-
[--
|
|
218
|
+
atlas referrals connect --provider referalli --program <prg_…> --base-url <url>
|
|
219
|
+
[--referalli-key-file <path|-> | --referalli-key <rk_…>]
|
|
146
220
|
[--auto-enroll] [--destination <url>] [--tracking-token <token>] [--enable]
|
|
147
221
|
[--no-sync] [--allow-mode-mismatch]
|
|
222
|
+
atlas referrals connect --oauth [--preset <id>] [--enable] (default preset: referalli)
|
|
148
223
|
atlas referrals connect --provider webhook --endpoint <https-url>
|
|
149
224
|
[--secret-file <path|->] [--program <id>] [--auto-enroll] [--enable]
|
|
150
225
|
atlas referrals backfill --since <YYYY-MM-DD> [--map <file.csv>]
|
|
151
226
|
[--metadata-path public_metadata.referral_code] [--wait]
|
|
152
227
|
atlas referrals status
|
|
228
|
+
atlas referrals conformance [--protocol webhook|connection] [--base-url <url>] [--connection-id <id>] --secret-file <path|->
|
|
229
|
+
[--only <case ids or areas>] [--simulate]
|
|
153
230
|
|
|
154
|
-
connect --provider
|
|
231
|
+
connect --provider referalli --oauth is one-click: it prints a Referalli link, you choose the
|
|
232
|
+
organization and program there, and Referalli hands Atlas the connection secret directly (nothing to
|
|
233
|
+
copy). It needs no key, --program or --base-url, and waits until the connection appears. Where the
|
|
234
|
+
deployment does not offer it yet, use a key as below.
|
|
235
|
+
|
|
236
|
+
conformance runs the referral protocol conformance suite (@atlasauth/referral-conformance) against
|
|
237
|
+
any platform (--protocol webhook: the generic Atlas referral protocol; connection: the Referalli dialect): signed calls with the answers a conforming server must give (401 for a bad signature,
|
|
238
|
+
an empty export for an unknown customer, nulls accepted, …). It defaults to the connected Referalli;
|
|
239
|
+
the secret is read from --secret-file because Atlas never shows it. --simulate also sends Atlas's own
|
|
240
|
+
simulated sign-up. It exits 1 on any failed case.
|
|
241
|
+
|
|
242
|
+
connect --provider referalli creates the Atlas connection on Referalli with
|
|
155
243
|
your merchant key (bring your own key: used for this one call, never stored or
|
|
156
244
|
printed), saves the connection id and secret on the instance, and runs a ping.
|
|
157
245
|
It requires v2 signatures on the connection from the start and registers a
|
|
@@ -159,9 +247,10 @@ Referalli webhook that sends referral changes (voided, approved, reassigned…)
|
|
|
159
247
|
back to Atlas; --no-sync skips the webhook. A test key (rk_test_) belongs with a
|
|
160
248
|
development instance and a live key with production: a mismatch is refused
|
|
161
249
|
unless --allow-mode-mismatch. --auto-enroll and --destination are passed to
|
|
162
|
-
Referalli. --enable turns referrals on when the ping passes. Prefer --
|
|
163
|
-
|
|
164
|
-
your shell history.
|
|
250
|
+
Referalli. --enable turns referrals on when the ping passes. Prefer --referalli-key-file (or
|
|
251
|
+
REFERALLI_API_KEY) to --referalli-key: a key on the command line can end up in
|
|
252
|
+
your shell history. The old names (--provider referally, --referally-key-file,
|
|
253
|
+
--referally-key, REFERALLY_*) still work and print a notice.
|
|
165
254
|
|
|
166
255
|
connect --provider webhook points the instance at a platform that speaks the
|
|
167
256
|
Atlas referral protocol. Without --secret-file, a signing secret is generated
|
|
@@ -180,7 +269,34 @@ Usage: atlas login [--profile <name>] [--url <api-url>] [--secret-key <sk_...>]
|
|
|
180
269
|
|
|
181
270
|
Prompts for an API URL and a secret key, validates the key with one Backend
|
|
182
271
|
call, then stores it (0600) under the profile. --url / --secret-key skip the
|
|
183
|
-
prompts for non-interactive setup
|
|
272
|
+
prompts for non-interactive setup.
|
|
273
|
+
|
|
274
|
+
Operator sign-in (no key on disk):
|
|
275
|
+
atlas login --device [--resource <ins_…|app_…>] [--scope "<scopes>"]
|
|
276
|
+
Opens Atlas's sign-in (passkey, multi-factor) with a device code. Only
|
|
277
|
+
short-lived tokens are stored: the operator token, and with --resource a
|
|
278
|
+
one-hour token bound to that instance or app (scope "read" by default).
|
|
279
|
+
Creating apps or instances and minting keys need a multi-factor sign-in
|
|
280
|
+
within the last 5 minutes.`,
|
|
281
|
+
token: `atlas token — a one-hour token bound to one instance or app
|
|
282
|
+
|
|
283
|
+
Usage: atlas token --resource <ins_…|app_…|acct_…> [--scope "<scopes>"] [--json]
|
|
284
|
+
|
|
285
|
+
Swaps your operator sign-in (atlas login --device) for an Atlas token (RFC 8693
|
|
286
|
+
token exchange). "read" = every read scope.`,
|
|
287
|
+
keys: `atlas keys — the instance's secret keys
|
|
288
|
+
|
|
289
|
+
Usage:
|
|
290
|
+
atlas keys whoami What the current key is and can do
|
|
291
|
+
atlas keys list Every credential on the instance
|
|
292
|
+
atlas keys create --scopes "<scopes>" [--name n] [--owner o] [--expires-at <ISO>] [--allowed-ips <cidr,…>] [--out <file>]
|
|
293
|
+
atlas keys rotate <id> [--overlap <seconds>] [--out <file>]
|
|
294
|
+
atlas keys revoke <id>
|
|
295
|
+
atlas keys revoke-leaked [<secret>] Revoke a leaked Atlas credential (no login needed)
|
|
296
|
+
|
|
297
|
+
New secrets come back sealed to a key pair made on this machine and are
|
|
298
|
+
written to a 0600 file (default .atlas/secret-key-<id>.env); --print-secret
|
|
299
|
+
prints them instead.`,
|
|
184
300
|
logout: `atlas logout — remove a stored profile credential
|
|
185
301
|
|
|
186
302
|
Usage: atlas logout [--profile <name>]`,
|
|
@@ -212,8 +328,76 @@ Usage:
|
|
|
212
328
|
Usage:
|
|
213
329
|
atlas webhooks list [--json]
|
|
214
330
|
atlas webhooks create --url <https-url> [--events a,b] [--product <name>] [--print-secret] [--json]
|
|
331
|
+
atlas webhooks upsert --url <https-url> [--events a,b] one endpoint per URL; idempotent
|
|
332
|
+
atlas webhooks update <id> [--url <u>] [--events a,b] [--active | --inactive]
|
|
333
|
+
atlas webhooks test <id> [--timeout 10s] [--no-wait] [--json]
|
|
334
|
+
atlas webhooks deliveries <id> [--status failed] [--event-type user.created]
|
|
335
|
+
[--since <iso|2h|7d>] [--until <iso>] [--limit <n>] [--starting-after <id>] [--json]
|
|
336
|
+
atlas webhooks redeliver <id> --delivery <delivery-id>
|
|
337
|
+
atlas webhooks redeliver <id> --since <iso|2h|7d> [--until <iso>] [--status failed]
|
|
338
|
+
atlas webhooks replay <id> [--since failing_since] re-send what a disabled endpoint missed
|
|
339
|
+
atlas webhooks rotate <id> [--now | --overlap <seconds>]
|
|
340
|
+
atlas webhooks reveal <id>
|
|
341
|
+
|
|
342
|
+
create, upsert, rotate and reveal write the signing secret to a 0600 file and
|
|
343
|
+
print only its path (--print-secret prints it instead; --force replaces a file).
|
|
344
|
+
test sends a signed webhook.test event and waits for your endpoint's answer;
|
|
345
|
+
the exit code is 1 when it did not answer 2xx. rotate --overlap keeps the old
|
|
346
|
+
secret signing alongside the new one for that many seconds.`,
|
|
347
|
+
listen: `atlas listen — forward live events to your local server
|
|
348
|
+
|
|
349
|
+
Usage:
|
|
350
|
+
atlas listen --forward-to <url> [--events user.*,session.created] [--count <n>] [--timeout <dur>] [--json]
|
|
351
|
+
atlas listen --no-forward [--events ...] only print events
|
|
352
|
+
|
|
353
|
+
Opens a signed event stream from your instance and POSTs each event to
|
|
354
|
+
--forward-to with the same atlas-id, atlas-timestamp and atlas-signature headers a
|
|
355
|
+
real delivery carries, then prints the status your server returned. No tunnel
|
|
356
|
+
and no second endpoint. The signing secret belongs to this session only and is
|
|
357
|
+
written to a 0600 file (webhook-listen.env): point your verifier at it. --events
|
|
358
|
+
takes names or patterns (user.*, *.created). The session lasts up to an hour;
|
|
359
|
+
Ctrl-C stops it. --count n exits after n events (exit 1 if any forward failed).`,
|
|
360
|
+
'move-origin': `atlas move-origin — move an app to a new domain
|
|
361
|
+
|
|
362
|
+
Usage: atlas move-origin --from <origin> --to <origin> [--dry-run] [--yes] [--json]
|
|
363
|
+
|
|
364
|
+
Rewrites every field that points at the old origin: allowed origins, branding
|
|
365
|
+
links, OAuth client redirect and logout URIs, webhook URLs, the redirect-URL
|
|
366
|
+
allowlist and your Sign in with Atlas apps. Shows the before and after of every
|
|
367
|
+
field first and asks before writing (--yes skips the question). After a real
|
|
368
|
+
move it sends a signed test delivery to each webhook endpoint that moved.
|
|
369
|
+
--dry-run prints the diff and writes nothing; running it twice changes nothing.`,
|
|
370
|
+
csp: `atlas csp — the Content Security Policy sources Atlas needs
|
|
371
|
+
|
|
372
|
+
Usage: atlas csp [--framework next|express|nginx] [--shape redirect|panel|button]
|
|
373
|
+
[--instance <id> | --product <name> [--instance-env <env>]] [--origin <url>]
|
|
374
|
+
[--manifest <url|file>]... [--no-atlas] [--json]
|
|
375
|
+
|
|
376
|
+
Reads your instance's embed manifest (including a custom Frontend API host) and
|
|
377
|
+
prints the script-src, connect-src, img-src and frame-src sources for your
|
|
378
|
+
setup, as a next.config.ts headers() block, a helmet() config or an nginx
|
|
379
|
+
add_header line. Read-only. --shape redirect (hosted sign-in) needs none.
|
|
380
|
+
With --origin, warns when that origin is not one of the instance's allowed origins.
|
|
381
|
+
|
|
382
|
+
Any provider that publishes the open embed-manifest format ({surfaces:{name:{csp:{directive:[sources]}}}},
|
|
383
|
+
usually at /.well-known/atlas-embed.json) can be merged in with --manifest <url|file>
|
|
384
|
+
(repeatable): a consent platform, chat widget, captcha or analytics vendor. --no-atlas
|
|
385
|
+
skips the Atlas instance and uses only the manifests you list.`,
|
|
386
|
+
integrations: `atlas integrations — identity integrations (presets and custom)
|
|
215
387
|
|
|
216
|
-
|
|
388
|
+
Usage:
|
|
389
|
+
atlas integrations list [--json]
|
|
390
|
+
atlas integrations get <id>
|
|
391
|
+
atlas integrations set <id> --audience <aud> [--name <n>] [--events-url <url|none>]
|
|
392
|
+
[--backchannel-logout-url <url|none>] [--oauth-client-id <client_id|none>]
|
|
393
|
+
[--disable] [--dry-run] [--json]
|
|
394
|
+
atlas integrations remove <id> [--json]
|
|
395
|
+
atlas integrations deliveries <id> [--trace <id>] [--json]
|
|
396
|
+
|
|
397
|
+
<id> is a preset (chatly, forumulate, cookiemunch, referalli) or your own id.
|
|
398
|
+
--oauth-client-id names the first-party OAuth client the service signs users in
|
|
399
|
+
with: while no --backchannel-logout-url is set, its backchannel_logout_uri is the
|
|
400
|
+
integration's back-channel receiver.`,
|
|
217
401
|
init: `atlas init — create or complete an app's setup, idempotently
|
|
218
402
|
|
|
219
403
|
Usage:
|
|
@@ -223,13 +407,16 @@ Usage:
|
|
|
223
407
|
[--email managed|development|none] [--email-from <address>]
|
|
224
408
|
[--email-provider resend|brevo --email-key-file <path|->]
|
|
225
409
|
[--client-redirect <url>]... [--webhook-url <url>]
|
|
410
|
+
[--backchannel <url>]
|
|
226
411
|
[--yes] [--force] [--rotate-secret] [--json]
|
|
227
412
|
|
|
228
413
|
Needs a platform key (ATLAS_PLATFORM_KEY, or a psk_ profile from atlas login).
|
|
229
414
|
Finds the app by name and environment, or creates it, then sets strategies, the
|
|
230
415
|
email sender, the custom domain (auth.<domain> unless --auth-host; prints the
|
|
231
416
|
CNAME), a first-party OAuth client and a webhook. Re-running only fills what is
|
|
232
|
-
missing.
|
|
417
|
+
missing. --backchannel <url> sets the client's back-channel logout URI (your
|
|
418
|
+
route that ends the app session when Atlas ends one; @atlasauth/backend has
|
|
419
|
+
ready-made handlers).
|
|
233
420
|
|
|
234
421
|
Email always goes through YOUR provider account (Atlas lends none):
|
|
235
422
|
managed Atlas sets your domain up on your Resend or Brevo account and
|
|
@@ -250,14 +437,26 @@ Usage: atlas preflight [--instance <id> | --product <name> [--instance-env <env>
|
|
|
250
437
|
|
|
251
438
|
Prints every finding (severity, code, message, fix). Exits 1 when there is an
|
|
252
439
|
error, or with --fail-on warning also on a warning.`,
|
|
440
|
+
doctor: `atlas doctor — integration health (a CI / deploy gate)
|
|
441
|
+
|
|
442
|
+
Usage: atlas doctor [--instance <id> | --product <name> [--instance-env <env>]]
|
|
443
|
+
[--only <source,...>] [--no-probe] [--json]
|
|
444
|
+
|
|
445
|
+
Prints every check: setup findings, webhook receivers (with the failing hop:
|
|
446
|
+
dns, tls, http, challenge or auth), back-channel logout, the referral
|
|
447
|
+
platform, email, the consent manager and SDK versions. Exits 1 when a check
|
|
448
|
+
fails. --no-probe uses recorded deliveries only (no live calls).`,
|
|
253
449
|
env: `atlas env — print deploy variables without secrets
|
|
254
450
|
|
|
255
|
-
Usage: atlas env --product <name> [--instance-env <env>] [--format dotenv|coolify|vercel] [--json]
|
|
451
|
+
Usage: atlas env [--product <name> [--instance-env <env>]] [--format dotenv|coolify|vercel|k8s] [--json]
|
|
256
452
|
|
|
257
453
|
Public values (publishable key, Frontend API, issuer, discovery and JWKS URLs,
|
|
258
454
|
OAuth client id) are printed as-is. Secrets are printed as references to their
|
|
259
455
|
0600 files: *_FILE=<path> (dotenv), KEY=@<path> (coolify), or a vercel env add
|
|
260
|
-
command that pipes the value from the file (vercel)
|
|
456
|
+
command that pipes the value from the file (vercel). k8s prints a ConfigMap plus
|
|
457
|
+
kubectl create secret commands that read each file. Without --product it reads
|
|
458
|
+
the public values from the instance your key belongs to (no secret references).
|
|
459
|
+
Both ATLAS_API_BASE and ATLAS_API_URL are printed.`,
|
|
261
460
|
client: `atlas client — OAuth clients
|
|
262
461
|
|
|
263
462
|
Usage: atlas client rotate <client-id> [--now | --overlap <seconds>]
|
|
@@ -276,6 +475,7 @@ Usage:
|
|
|
276
475
|
Usage:
|
|
277
476
|
atlas config export [--dir <path>] [--format json|yaml]
|
|
278
477
|
atlas config import [--dir <path>] [--format json|yaml] [--dry-run] [--prune]
|
|
478
|
+
atlas config plan [--dir <path>] [--format json|yaml] [--prune] [--exit-code] [--json]
|
|
279
479
|
|
|
280
480
|
export Read the instance's current config (instance/auth config, OAuth clients
|
|
281
481
|
and providers, SSO connections, resource servers, JWT templates, roles,
|
|
@@ -290,6 +490,10 @@ import Diff the directory against live config and apply creates/updates
|
|
|
290
490
|
--dir config directory (default: ./atlas-config)
|
|
291
491
|
--format json (default) or yaml
|
|
292
492
|
|
|
493
|
+
plan A Terraform-style, read-only diff of the directory against the live
|
|
494
|
+
instance: field-by-field before -> after for updates. --exit-code exits 2
|
|
495
|
+
when there is drift (for CI); --json for tooling.
|
|
496
|
+
|
|
293
497
|
Secrets never live on disk. Inject a credential at import with a \${ENV_VAR}
|
|
294
498
|
placeholder in a file (e.g. a provider "client_secret": "\${GOOGLE_SECRET}").`,
|
|
295
499
|
actions: `atlas actions — manage Actions (tenant code run in the auth pipeline)
|
package/dist/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEU,QAAA,QAAQ,GAAG
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEU,QAAA,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAqEgC,CAAC;AAEzD,oDAAoD;AACvC,QAAA,YAAY,GAA2B;IAClD,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CAyDmC;IAC5C,IAAI,EAAE;;;;;;;;;;gEAUwD;IAC9D,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2EAmCiE;IACzE,GAAG,EAAE;;;;;;;;;;;;;;;+CAewC;IAC7C,MAAM,EAAE;;;;;;;;;;;;sCAY4B;IACpC,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEAkD4D;IAEvE,KAAK,EAAE;;;;;;;;;;;;;;2BAckB;IAEzB,KAAK,EAAE;;;;;4CAKmC;IAE1C,IAAI,EAAE;;;;;;;;;;;;qBAYa;IAEnB,MAAM,EAAE;;uCAE6B;IAErC,MAAM,EAAE;;gDAEsC;IAE9C,KAAK,EAAE;;;;;;wCAM+B;IAEtC,IAAI,EAAE;;;;;uCAK+B;IAErC,UAAU,EAAE;;;;;;8CAMgC;IAE5C,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;4DAoBgD;IAC1D,MAAM,EAAE;;;;;;;;;;;;gFAYsE;IAC9E,aAAa,EAAE;;;;;;;;;gFAS+D;IAC9E,GAAG,EAAE;;;;;;;;;;;;;;;+DAewD;IAE7D,YAAY,EAAE;;;;;;;;;;;;;;qCAcqB;IAEnC,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yEA+BiE;IAEvE,SAAS,EAAE;;;;;;oDAMuC;IAElD,MAAM,EAAE;;;;;;;;iEAQuD;IAE/D,GAAG,EAAE;;;;;;;;;;mDAU4C;IAEjD,MAAM,EAAE;;;;;;;;wDAQ8C;IAEtD,QAAQ,EAAE;;;8CAGkC;IAE5C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;8EAyBoE;IAC5E,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;qEA0B0D;CACpE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,3 +25,7 @@ export { preflight, envCommand, client } from './commands/project-commands';
|
|
|
25
25
|
export { referrals } from './commands/referrals';
|
|
26
26
|
export { writeSecretFile, readEnvFile, parseDotenv, renderDotenv, productDir, deliverSecret, } from './secrets';
|
|
27
27
|
export { readManifest, writeManifest, manifestPath, type ProjectManifest, type ProjectInstance, type InstanceEnv, } from './project';
|
|
28
|
+
export { migrate } from './commands/migrate';
|
|
29
|
+
export { planConfigImport, type ConfigPlan, type PlannedChange } from './commands/config';
|
|
30
|
+
export { translateBetterAuth, type Translation, type ReportEntry, type ConfigDocument } from './migrate/better-auth/translate';
|
|
31
|
+
export { migrateBetterAuth, STEPS as BETTER_AUTH_MIGRATION_STEPS } from './migrate/better-auth/orchestrator';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.manifestPath = exports.writeManifest = exports.readManifest = exports.deliverSecret = exports.productDir = exports.renderDotenv = exports.parseDotenv = exports.readEnvFile = exports.writeSecretFile = exports.referrals = exports.client = exports.envCommand = exports.preflight = exports.init = exports.actions = exports.config = exports.sessions = exports.webhooks = exports.apiKeys = exports.orgs = exports.users = exports.whoami = exports.logout = exports.login = exports.getVersion = exports.defaultPrompter = exports.defaultConfigPath = exports.MemoryConfigStore = exports.FileConfigStore = exports.captureIO = exports.defaultIO = exports.CliError = exports.isNotFound = exports.createConfigHttp = exports.defaultContext = exports.run = void 0;
|
|
3
|
+
exports.BETTER_AUTH_MIGRATION_STEPS = exports.migrateBetterAuth = exports.translateBetterAuth = exports.planConfigImport = exports.migrate = exports.manifestPath = exports.writeManifest = exports.readManifest = exports.deliverSecret = exports.productDir = exports.renderDotenv = exports.parseDotenv = exports.readEnvFile = exports.writeSecretFile = exports.referrals = exports.client = exports.envCommand = exports.preflight = exports.init = exports.actions = exports.config = exports.sessions = exports.webhooks = exports.apiKeys = exports.orgs = exports.users = exports.whoami = exports.logout = exports.login = exports.getVersion = exports.defaultPrompter = exports.defaultConfigPath = exports.MemoryConfigStore = exports.FileConfigStore = exports.captureIO = exports.defaultIO = exports.CliError = exports.isNotFound = exports.createConfigHttp = exports.defaultContext = exports.run = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Library surface of `@atlasauth/cli`. The package ships a bin (`atlas`), but
|
|
6
6
|
* exporting the pieces lets the handlers be unit-tested with injected deps and
|
|
@@ -65,4 +65,13 @@ var project_1 = require("./project");
|
|
|
65
65
|
Object.defineProperty(exports, "readManifest", { enumerable: true, get: function () { return project_1.readManifest; } });
|
|
66
66
|
Object.defineProperty(exports, "writeManifest", { enumerable: true, get: function () { return project_1.writeManifest; } });
|
|
67
67
|
Object.defineProperty(exports, "manifestPath", { enumerable: true, get: function () { return project_1.manifestPath; } });
|
|
68
|
+
var migrate_1 = require("./commands/migrate");
|
|
69
|
+
Object.defineProperty(exports, "migrate", { enumerable: true, get: function () { return migrate_1.migrate; } });
|
|
70
|
+
var config_3 = require("./commands/config");
|
|
71
|
+
Object.defineProperty(exports, "planConfigImport", { enumerable: true, get: function () { return config_3.planConfigImport; } });
|
|
72
|
+
var translate_1 = require("./migrate/better-auth/translate");
|
|
73
|
+
Object.defineProperty(exports, "translateBetterAuth", { enumerable: true, get: function () { return translate_1.translateBetterAuth; } });
|
|
74
|
+
var orchestrator_1 = require("./migrate/better-auth/orchestrator");
|
|
75
|
+
Object.defineProperty(exports, "migrateBetterAuth", { enumerable: true, get: function () { return orchestrator_1.migrateBetterAuth; } });
|
|
76
|
+
Object.defineProperty(exports, "BETTER_AUTH_MIGRATION_STEPS", { enumerable: true, get: function () { return orchestrator_1.STEPS; } });
|
|
68
77
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,6BAA0C;AAAjC,0FAAA,GAAG,OAAA;AACZ,qCAAmF;AAA1E,yGAAA,cAAc,OAAA;AACvB,6CAA8E;AAArE,+GAAA,gBAAgB,OAAA;AAAE,yGAAA,UAAU,OAAA;AACrC,mCAAoC;AAA3B,kGAAA,QAAQ,OAAA;AACjB,2BAAqE;AAA5D,+FAAA,SAAS,OAAA;AAAE,+FAAA,SAAS,OAAA;AAC7B,mCAOkB;AANhB,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,2GAAA,iBAAiB,OAAA;AAKnB,mCAA0D;AAAjD,yGAAA,eAAe,OAAA;AACxB,qCAAuC;AAA9B,qGAAA,UAAU,OAAA;AAEnB,0EAA0E;AAC1E,wCAAwD;AAA/C,6FAAA,KAAK,OAAA;AAAE,8FAAA,MAAM,OAAA;AAAE,8FAAA,MAAM,OAAA;AAC9B,0CAAyC;AAAhC,8FAAA,KAAK,OAAA;AACd,wCAAuC;AAA9B,4FAAA,IAAI,OAAA;AACb,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA;AACjB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA;AACjB,4CAA2C;AAAlC,gGAAA,MAAM,OAAA;AACf,8CAA6C;AAApC,kGAAA,OAAO,OAAA;AAChB,wCAAuC;AAA9B,4FAAA,IAAI,OAAA;AACb,gEAA4E;AAAnE,6GAAA,SAAS,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,0GAAA,MAAM,OAAA;AACtC,kDAAiD;AAAxC,sGAAA,SAAS,OAAA;AAClB,qCAOmB;AANjB,0GAAA,eAAe,OAAA;AACf,sGAAA,WAAW,OAAA;AACX,sGAAA,WAAW,OAAA;AACX,uGAAA,YAAY,OAAA;AACZ,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AAEf,qCAOmB;AANjB,uGAAA,YAAY,OAAA;AACZ,wGAAA,aAAa,OAAA;AACb,uGAAA,YAAY,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,6BAA0C;AAAjC,0FAAA,GAAG,OAAA;AACZ,qCAAmF;AAA1E,yGAAA,cAAc,OAAA;AACvB,6CAA8E;AAArE,+GAAA,gBAAgB,OAAA;AAAE,yGAAA,UAAU,OAAA;AACrC,mCAAoC;AAA3B,kGAAA,QAAQ,OAAA;AACjB,2BAAqE;AAA5D,+FAAA,SAAS,OAAA;AAAE,+FAAA,SAAS,OAAA;AAC7B,mCAOkB;AANhB,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,2GAAA,iBAAiB,OAAA;AAKnB,mCAA0D;AAAjD,yGAAA,eAAe,OAAA;AACxB,qCAAuC;AAA9B,qGAAA,UAAU,OAAA;AAEnB,0EAA0E;AAC1E,wCAAwD;AAA/C,6FAAA,KAAK,OAAA;AAAE,8FAAA,MAAM,OAAA;AAAE,8FAAA,MAAM,OAAA;AAC9B,0CAAyC;AAAhC,8FAAA,KAAK,OAAA;AACd,wCAAuC;AAA9B,4FAAA,IAAI,OAAA;AACb,gDAA8C;AAArC,mGAAA,OAAO,OAAA;AAChB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA;AACjB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA;AACjB,4CAA2C;AAAlC,gGAAA,MAAM,OAAA;AACf,8CAA6C;AAApC,kGAAA,OAAO,OAAA;AAChB,wCAAuC;AAA9B,4FAAA,IAAI,OAAA;AACb,gEAA4E;AAAnE,6GAAA,SAAS,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,0GAAA,MAAM,OAAA;AACtC,kDAAiD;AAAxC,sGAAA,SAAS,OAAA;AAClB,qCAOmB;AANjB,0GAAA,eAAe,OAAA;AACf,sGAAA,WAAW,OAAA;AACX,sGAAA,WAAW,OAAA;AACX,uGAAA,YAAY,OAAA;AACZ,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AAEf,qCAOmB;AANjB,uGAAA,YAAY,OAAA;AACZ,wGAAA,aAAa,OAAA;AACb,uGAAA,YAAY,OAAA;AAKd,8CAA6C;AAApC,kGAAA,OAAO,OAAA;AAChB,4CAA0F;AAAjF,0GAAA,gBAAgB,OAAA;AACzB,6DAA+H;AAAtH,gHAAA,mBAAmB,OAAA;AAC5B,mEAA6G;AAApG,iHAAA,iBAAiB,OAAA;AAAE,2HAAA,KAAK,OAA+B"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type BetterAuthImport, type BetterAuthImportOptions } from '@atlasauth/backend';
|
|
2
|
+
import type { ConfigHttp } from '../../config-http';
|
|
3
|
+
/**
|
|
4
|
+
* Every call the Better Auth migration makes into the import and session-bridge
|
|
5
|
+
* APIs lives in this one module:
|
|
6
|
+
*
|
|
7
|
+
* - the export/import pair: the `@atlasauth/better-auth-migrate` exporter seals
|
|
8
|
+
* a bundle to the instance's import key (`GET /v1/better_auth_imports/public_key`),
|
|
9
|
+
* which is uploaded in line-split parts, finalized (which runs the dry run)
|
|
10
|
+
* and applied under `/v1/better_auth_imports`, and
|
|
11
|
+
* - the session bridge (`/v1/migrations/better_auth/bridge`), which lets a live
|
|
12
|
+
* Better Auth session become an Atlas session during the cutover window.
|
|
13
|
+
*/
|
|
14
|
+
/** The exporter's documented command line. */
|
|
15
|
+
export declare const EXPORTER_BIN = "atlas-better-auth-export";
|
|
16
|
+
export declare const EXPORTER_PACKAGE = "@atlasauth/better-auth-migrate";
|
|
17
|
+
/** `publicKey` is the key's compact `kid:public_key` form. */
|
|
18
|
+
export declare function exporterCommand(opts: {
|
|
19
|
+
out: string;
|
|
20
|
+
publicKey: string;
|
|
21
|
+
}): {
|
|
22
|
+
cmd: string;
|
|
23
|
+
args: string[];
|
|
24
|
+
display: string;
|
|
25
|
+
};
|
|
26
|
+
/** The import key the exporter seals the bundle to (the private half stays with Atlas), as `kid:public_key`. */
|
|
27
|
+
export declare function getImportPublicKey(http: ConfigHttp): Promise<string>;
|
|
28
|
+
export type ImportJob = BetterAuthImport;
|
|
29
|
+
/** Statuses an import rests in; anything else is still being worked on. */
|
|
30
|
+
export declare const RESTING_STATUSES: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Upload a sealed bundle: create the import, send it in line-split parts of at
|
|
33
|
+
* most 8 MiB, then finalize (which checks the parts and the key and runs the
|
|
34
|
+
* dry run; a large bundle comes back `analyzing` and finishes in the background).
|
|
35
|
+
*/
|
|
36
|
+
export declare function uploadBundle(http: ConfigHttp, opts: {
|
|
37
|
+
bundle: string;
|
|
38
|
+
options?: BetterAuthImportOptions;
|
|
39
|
+
onPart?: (n: number, of: number) => void;
|
|
40
|
+
}): Promise<ImportJob>;
|
|
41
|
+
export declare function getImport(http: ConfigHttp, id: string): Promise<ImportJob>;
|
|
42
|
+
/** Finalize an import whose upload finished but was never finalized. */
|
|
43
|
+
export declare function finalizeImport(http: ConfigHttp, id: string): Promise<ImportJob>;
|
|
44
|
+
/** Apply a dry-run-ready import, or resume a failed one from where it stopped. */
|
|
45
|
+
export declare function applyImport(http: ConfigHttp, id: string, opts: {
|
|
46
|
+
confirmConflicts: boolean;
|
|
47
|
+
}): Promise<ImportJob>;
|
|
48
|
+
export interface BridgeSettings {
|
|
49
|
+
/** Better Auth's `advanced.cookiePrefix` (default `better-auth`). */
|
|
50
|
+
cookiePrefix: string;
|
|
51
|
+
/** When the bridge stops accepting Better Auth sessions (epoch ms). */
|
|
52
|
+
endsAt: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Turn the Better Auth session bridge on for a window. The old app's Better
|
|
56
|
+
* Auth secret is stored write-only so Atlas can check the cookie signature
|
|
57
|
+
* (the live fallback to the old app stays off unless set up separately).
|
|
58
|
+
*/
|
|
59
|
+
export declare function enableSessionBridge(http: ConfigHttp, settings: BridgeSettings, secret: string): Promise<void>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RESTING_STATUSES = exports.EXPORTER_PACKAGE = exports.EXPORTER_BIN = void 0;
|
|
4
|
+
exports.exporterCommand = exporterCommand;
|
|
5
|
+
exports.getImportPublicKey = getImportPublicKey;
|
|
6
|
+
exports.uploadBundle = uploadBundle;
|
|
7
|
+
exports.getImport = getImport;
|
|
8
|
+
exports.finalizeImport = finalizeImport;
|
|
9
|
+
exports.applyImport = applyImport;
|
|
10
|
+
exports.enableSessionBridge = enableSessionBridge;
|
|
11
|
+
const backend_1 = require("@atlasauth/backend");
|
|
12
|
+
/**
|
|
13
|
+
* Every call the Better Auth migration makes into the import and session-bridge
|
|
14
|
+
* APIs lives in this one module:
|
|
15
|
+
*
|
|
16
|
+
* - the export/import pair: the `@atlasauth/better-auth-migrate` exporter seals
|
|
17
|
+
* a bundle to the instance's import key (`GET /v1/better_auth_imports/public_key`),
|
|
18
|
+
* which is uploaded in line-split parts, finalized (which runs the dry run)
|
|
19
|
+
* and applied under `/v1/better_auth_imports`, and
|
|
20
|
+
* - the session bridge (`/v1/migrations/better_auth/bridge`), which lets a live
|
|
21
|
+
* Better Auth session become an Atlas session during the cutover window.
|
|
22
|
+
*/
|
|
23
|
+
/** The exporter's documented command line. */
|
|
24
|
+
exports.EXPORTER_BIN = 'atlas-better-auth-export';
|
|
25
|
+
exports.EXPORTER_PACKAGE = '@atlasauth/better-auth-migrate';
|
|
26
|
+
/** `publicKey` is the key's compact `kid:public_key` form. */
|
|
27
|
+
function exporterCommand(opts) {
|
|
28
|
+
const args = ['--yes', exports.EXPORTER_BIN, '--out', opts.out, '--public-key', opts.publicKey];
|
|
29
|
+
return { cmd: 'npx', args, display: `npx ${exports.EXPORTER_BIN} --out ${opts.out} --public-key ${opts.publicKey}` };
|
|
30
|
+
}
|
|
31
|
+
/** The import key the exporter seals the bundle to (the private half stays with Atlas), as `kid:public_key`. */
|
|
32
|
+
async function getImportPublicKey(http) {
|
|
33
|
+
const key = await http.get('/v1/better_auth_imports/public_key');
|
|
34
|
+
if (!key?.compact)
|
|
35
|
+
throw new Error('The instance did not return an import key.');
|
|
36
|
+
return key.compact;
|
|
37
|
+
}
|
|
38
|
+
/** Statuses an import rests in; anything else is still being worked on. */
|
|
39
|
+
exports.RESTING_STATUSES = ['uploading', 'ready', 'invalid', 'completed', 'failed'];
|
|
40
|
+
const importPath = (id, sub = '') => `/v1/better_auth_imports/${encodeURIComponent(id)}${sub}`;
|
|
41
|
+
/**
|
|
42
|
+
* Upload a sealed bundle: create the import, send it in line-split parts of at
|
|
43
|
+
* most 8 MiB, then finalize (which checks the parts and the key and runs the
|
|
44
|
+
* dry run; a large bundle comes back `analyzing` and finishes in the background).
|
|
45
|
+
*/
|
|
46
|
+
async function uploadBundle(http, opts) {
|
|
47
|
+
const parts = (0, backend_1.splitBundleParts)(opts.bundle);
|
|
48
|
+
if (parts.length === 0)
|
|
49
|
+
throw new Error('The bundle is empty.');
|
|
50
|
+
const created = await http.post('/v1/better_auth_imports', opts.options ? { options: opts.options } : {});
|
|
51
|
+
for (let i = 0; i < parts.length; i++) {
|
|
52
|
+
await http.put(importPath(created.id, `/parts/${i + 1}`), { data: parts[i] });
|
|
53
|
+
opts.onPart?.(i + 1, parts.length);
|
|
54
|
+
}
|
|
55
|
+
return http.post(importPath(created.id, '/finalize'), {});
|
|
56
|
+
}
|
|
57
|
+
async function getImport(http, id) {
|
|
58
|
+
return http.get(importPath(id));
|
|
59
|
+
}
|
|
60
|
+
/** Finalize an import whose upload finished but was never finalized. */
|
|
61
|
+
async function finalizeImport(http, id) {
|
|
62
|
+
return http.post(importPath(id, '/finalize'), {});
|
|
63
|
+
}
|
|
64
|
+
/** Apply a dry-run-ready import, or resume a failed one from where it stopped. */
|
|
65
|
+
async function applyImport(http, id, opts) {
|
|
66
|
+
return http.post(importPath(id, '/apply'), opts.confirmConflicts ? { confirm_conflicts: true } : {});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Turn the Better Auth session bridge on for a window. The old app's Better
|
|
70
|
+
* Auth secret is stored write-only so Atlas can check the cookie signature
|
|
71
|
+
* (the live fallback to the old app stays off unless set up separately).
|
|
72
|
+
*/
|
|
73
|
+
async function enableSessionBridge(http, settings, secret) {
|
|
74
|
+
await http.put('/v1/migrations/better_auth/bridge', {
|
|
75
|
+
enabled: true,
|
|
76
|
+
ends_at: settings.endsAt,
|
|
77
|
+
cookie_prefix: settings.cookiePrefix,
|
|
78
|
+
live_fallback: { secret },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/migrate/better-auth/integration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ParsedArgs } from '../../args';
|
|
2
|
+
import type { RunContext } from '../../context';
|
|
3
|
+
import { type Json } from '../../serialize';
|
|
4
|
+
/**
|
|
5
|
+
* `atlas migrate better-auth [path]` — the whole Better Auth → Atlas program as
|
|
6
|
+
* one resumable run:
|
|
7
|
+
*
|
|
8
|
+
* preflight → translate → apply (review the diff, confirm, config push) →
|
|
9
|
+
* export (the exporter runs in the app) → import (dry run, confirm, apply) →
|
|
10
|
+
* bridge (no forced logout) → code (the codemod) → verify (checklist).
|
|
11
|
+
*
|
|
12
|
+
* Each finished step is checkpointed in the state file, so `--resume` carries
|
|
13
|
+
* on where a run stopped (a confirmation declined, an env var missing, the
|
|
14
|
+
* export not run yet). `--dry-run` walks every step without changing the
|
|
15
|
+
* instance or the code; `--yes` answers every confirmation.
|
|
16
|
+
*/
|
|
17
|
+
export declare const STEPS: readonly ["preflight", "translate", "apply", "export", "import", "bridge", "code", "verify"];
|
|
18
|
+
export type StepId = (typeof STEPS)[number];
|
|
19
|
+
type StepStatus = 'done' | 'skipped' | 'planned' | 'action_needed' | 'awaiting_confirmation' | 'blocked';
|
|
20
|
+
interface StepRecord {
|
|
21
|
+
status: StepStatus;
|
|
22
|
+
at?: number;
|
|
23
|
+
detail?: Record<string, unknown>;
|
|
24
|
+
message?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface MigrationState {
|
|
27
|
+
version: 1;
|
|
28
|
+
project: string;
|
|
29
|
+
instance_id: string | null;
|
|
30
|
+
environment: string | null;
|
|
31
|
+
started_at: number;
|
|
32
|
+
steps: Partial<Record<StepId, StepRecord>>;
|
|
33
|
+
}
|
|
34
|
+
/** `${NAME}` placeholders in the config files that the environment does not set. */
|
|
35
|
+
export declare function missingPlaceholders(dir: string, env: NodeJS.ProcessEnv): Set<string>;
|
|
36
|
+
/** Leaves of `desired` that differ from `live` (arrays compare as a whole). */
|
|
37
|
+
export declare function leafDiff(desired: Json, live: Json, prefix?: string): Array<{
|
|
38
|
+
path: string;
|
|
39
|
+
from: Json | undefined;
|
|
40
|
+
to: Json;
|
|
41
|
+
}>;
|
|
42
|
+
export declare function migrateBetterAuth(ctx: RunContext, args: ParsedArgs, projectArg: string | undefined): Promise<number>;
|
|
43
|
+
export {};
|