@atlasauth/cli 0.2.0 → 0.4.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.
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.instanceCredential = instanceCredential;
4
+ exports.preflight = preflight;
5
+ exports.envCommand = envCommand;
6
+ exports.client = client;
7
+ const backend_1 = require("@atlasauth/backend");
8
+ const args_1 = require("../args");
9
+ const errors_1 = require("../errors");
10
+ const output_1 = require("../output");
11
+ const project_1 = require("../project");
12
+ const secrets_1 = require("../secrets");
13
+ const shared_1 = require("./shared");
14
+ /**
15
+ * The project commands that sit beside `atlas init`: `preflight` (a CI gate),
16
+ * `env` (deploy variables without secrets) and `client rotate` (a new OAuth
17
+ * client secret, written straight to its file).
18
+ */
19
+ /**
20
+ * The instance credential a project command runs with:
21
+ * - `--instance <id>`: the instance's secret file from a project manifest;
22
+ * - `--product <name>` [`--instance-env`]: that project's instance;
23
+ * - otherwise the profile / ATLAS_SECRET_KEY, as every other command.
24
+ */
25
+ function instanceCredential(ctx, args) {
26
+ const v = args.values;
27
+ const instanceId = (0, args_1.str)(v, 'instance');
28
+ const product = (0, args_1.str)(v, 'product');
29
+ if (instanceId) {
30
+ const found = (0, project_1.findInstance)(ctx.env, instanceId, product);
31
+ if (!found) {
32
+ throw new errors_1.CliError(`No project manifest knows instance ${instanceId}${product ? ` (product '${product}')` : ''}. Run 'atlas init' for it, or use ATLAS_SECRET_KEY.`);
33
+ }
34
+ return {
35
+ secretKey: (0, project_1.instanceSecretFromFile)(found.instance),
36
+ apiUrl: ctx.env.ATLAS_API_URL?.trim() || found.manifest.api_url,
37
+ manifest: found.manifest,
38
+ instance: found.instance,
39
+ };
40
+ }
41
+ if (product) {
42
+ const { manifest, instance } = projectInstance(ctx, args, product);
43
+ return {
44
+ secretKey: (0, project_1.instanceSecretFromFile)(instance),
45
+ apiUrl: ctx.env.ATLAS_API_URL?.trim() || manifest.api_url,
46
+ manifest,
47
+ instance,
48
+ };
49
+ }
50
+ const auth = (0, shared_1.resolveAuth)(ctx, v);
51
+ return { secretKey: auth.secretKey, apiUrl: auth.apiUrl };
52
+ }
53
+ /** The manifest instance for `--product` + `--instance-env` (default: production, else the only one). */
54
+ function projectInstance(ctx, args, product) {
55
+ const manifest = (0, project_1.readManifest)(ctx.env, product);
56
+ if (!manifest) {
57
+ throw new errors_1.CliError(`No project '${product}' at ${(0, secrets_1.productDir)(ctx.env, product)}. Run 'atlas init --product ${product}' first.`);
58
+ }
59
+ const requested = (0, args_1.str)(args.values, 'instance-env');
60
+ const envs = Object.keys(manifest.instances);
61
+ const env = requested
62
+ ? (0, project_1.parseInstanceEnv)(requested, 'production')
63
+ : manifest.instances.production
64
+ ? 'production'
65
+ : envs.length === 1
66
+ ? envs[0]
67
+ : 'production';
68
+ const instance = manifest.instances[env];
69
+ if (!instance)
70
+ throw new errors_1.CliError(`Project '${product}' has no ${env} instance. Run 'atlas init --product ${product} --instance-env ${env}'.`);
71
+ return { manifest, instance };
72
+ }
73
+ const FINDING_COLUMNS = [
74
+ { header: 'SEVERITY', get: (f) => f.severity },
75
+ { header: 'CODE', get: (f) => f.code },
76
+ { header: 'MESSAGE', get: (f) => f.message },
77
+ ];
78
+ /** `atlas preflight` — run the instance's setup checks; exit 1 on errors (or warnings with --fail-on warning). */
79
+ async function preflight(ctx, args) {
80
+ const failOn = (0, args_1.str)(args.values, 'fail-on') ?? 'error';
81
+ if (failOn !== 'error' && failOn !== 'warning') {
82
+ throw new errors_1.CliError(`--fail-on must be error or warning, got '${failOn}'.`);
83
+ }
84
+ const cred = instanceCredential(ctx, args);
85
+ const report = await (0, project_1.httpFor)(ctx, cred).get('/v1/instance/preflight');
86
+ const findings = report.findings ?? [];
87
+ const errors = findings.filter((f) => f.severity === 'error').length;
88
+ const warnings = findings.filter((f) => f.severity === 'warning').length;
89
+ const failed = errors > 0 || (failOn === 'warning' && warnings > 0);
90
+ if ((0, shared_1.wantsJson)(args.values)) {
91
+ (0, output_1.printJson)(ctx.io, report);
92
+ }
93
+ else if (findings.length === 0) {
94
+ ctx.io.out('Preflight passed: no findings.');
95
+ }
96
+ else {
97
+ ctx.io.out((0, output_1.renderTable)(FINDING_COLUMNS, findings));
98
+ ctx.io.out('');
99
+ for (const f of findings.filter((x) => x.severity !== 'info')) {
100
+ ctx.io.out(`${f.code}: ${f.fix}`);
101
+ }
102
+ ctx.io.out('');
103
+ ctx.io.out(`${errors} error(s), ${warnings} warning(s), ${findings.length - errors - warnings} info.`);
104
+ }
105
+ if (failed) {
106
+ ctx.io.err(`atlas: preflight failed (${errors} error(s)${failOn === 'warning' ? `, ${warnings} warning(s)` : ''}).`);
107
+ return 1;
108
+ }
109
+ return 0;
110
+ }
111
+ // ---- atlas env ----------------------------------------------------------------
112
+ const FORMATS = ['dotenv', 'coolify', 'vercel'];
113
+ /** Public values, then each secret as a reference to its file — never the value. */
114
+ async function envCommand(ctx, args) {
115
+ const format = ((0, args_1.str)(args.values, 'format') ?? 'dotenv');
116
+ if (!FORMATS.includes(format))
117
+ throw new errors_1.CliError(`--format must be one of: ${FORMATS.join(', ')} (got '${format}').`);
118
+ const product = (0, args_1.str)(args.values, 'product');
119
+ if (!product)
120
+ throw new errors_1.CliError('atlas env needs --product <name> (the name you passed to atlas init).');
121
+ const { manifest, instance } = projectInstance(ctx, args, product);
122
+ const pub = {
123
+ ATLAS_PUBLISHABLE_KEY: instance.publishable_key,
124
+ ATLAS_API_URL: manifest.api_url,
125
+ };
126
+ if (instance.frontend_api_host)
127
+ pub.ATLAS_FRONTEND_API = `https://${instance.frontend_api_host}`;
128
+ if (instance.issuer)
129
+ pub.ATLAS_ISSUER = instance.issuer;
130
+ if (instance.discovery_url)
131
+ pub.ATLAS_DISCOVERY_URL = instance.discovery_url;
132
+ if (instance.jwks_uri)
133
+ pub.ATLAS_JWKS_URI = instance.jwks_uri;
134
+ if (instance.oauth_client)
135
+ pub.ATLAS_CLIENT_ID = instance.oauth_client.client_id;
136
+ const secrets = [{ key: 'ATLAS_SECRET_KEY', file: instance.secret_file }];
137
+ if (instance.oauth_client?.secret_file)
138
+ secrets.push({ key: 'ATLAS_CLIENT_SECRET', file: instance.oauth_client.secret_file });
139
+ if (instance.webhook?.secret_file)
140
+ secrets.push({ key: 'ATLAS_WEBHOOK_SECRET', file: instance.webhook.secret_file });
141
+ if ((0, shared_1.wantsJson)(args.values)) {
142
+ (0, output_1.printJson)(ctx.io, { product, environment: instance.environment, public: pub, secret_files: Object.fromEntries(secrets.map((s) => [s.key, s.file])) });
143
+ return 0;
144
+ }
145
+ const out = (l) => ctx.io.out(l);
146
+ if (format === 'dotenv') {
147
+ out(`# ${product} (${instance.environment}): public values`);
148
+ for (const [k, v] of Object.entries(pub))
149
+ out(`${k}=${v}`);
150
+ out('# Secrets are not printed. Each *_FILE variable names the 0600 file that holds it.');
151
+ for (const s of secrets)
152
+ out(`${s.key}_FILE=${s.file}`);
153
+ }
154
+ else if (format === 'coolify') {
155
+ out(`# ${product} (${instance.environment}): paste into Coolify → Environment Variables (Developer view).`);
156
+ for (const [k, v] of Object.entries(pub))
157
+ out(`${k}=${v}`);
158
+ out('# Secrets: copy each value from its file (mark them as secret in Coolify):');
159
+ for (const s of secrets)
160
+ out(`${s.key}=@${s.file}`);
161
+ }
162
+ else {
163
+ out(`# ${product} (${instance.environment}): Vercel CLI commands. Secrets are piped from their files, never echoed.`);
164
+ const target = instance.environment === 'production' ? 'production' : 'preview';
165
+ for (const [k, v] of Object.entries(pub))
166
+ out(`printf '%s' '${v.replace(/'/g, "'\\''")}' | vercel env add ${k} ${target}`);
167
+ for (const s of secrets)
168
+ out(`sed -n 's/^${s.key}=//p' '${s.file}' | tr -d '\\n' | vercel env add ${s.key} ${target}`);
169
+ }
170
+ return 0;
171
+ }
172
+ // ---- atlas client rotate ----------------------------------------------------------
173
+ /** `atlas client rotate <id> [--now | --overlap <seconds>]` — the new secret goes straight to its file. */
174
+ async function client(ctx, args) {
175
+ const sub = args.positionals[1];
176
+ if (sub !== 'rotate') {
177
+ throw new errors_1.CliError(sub ? `Unknown subcommand 'client ${sub}'. Try: rotate.` : 'client needs a subcommand: rotate.');
178
+ }
179
+ const ref = (0, shared_1.requireArg)(args.positionals, 2, 'client-id');
180
+ const v = args.values;
181
+ const overlapRaw = (0, args_1.str)(v, 'overlap');
182
+ if (v.now === true && overlapRaw !== undefined)
183
+ throw new errors_1.CliError('Pass --now or --overlap, not both.');
184
+ let overlapSeconds;
185
+ if (v.now === true)
186
+ overlapSeconds = 0;
187
+ else if (overlapRaw !== undefined) {
188
+ const n = Number(overlapRaw);
189
+ if (!Number.isInteger(n) || n < 0)
190
+ throw new errors_1.CliError(`--overlap must be a whole number of seconds, got '${overlapRaw}'.`);
191
+ overlapSeconds = n;
192
+ }
193
+ const cred = instanceCredential(ctx, args);
194
+ const api = (0, project_1.httpFor)(ctx, cred);
195
+ // Accept the internal id or the public client_id.
196
+ let id = ref;
197
+ if (ref.startsWith('client_')) {
198
+ const rows = (await api.get('/v1/oauth_clients')).data ?? [];
199
+ const match = rows.find((c) => c.client_id === ref);
200
+ if (!match)
201
+ throw new errors_1.CliError(`No OAuth client with client_id ${ref} on this instance.`);
202
+ id = match.id;
203
+ }
204
+ let res;
205
+ try {
206
+ res = await api.post(`/v1/oauth_clients/${id}/rotate_secret`, overlapSeconds === undefined ? {} : { overlap_seconds: overlapSeconds });
207
+ }
208
+ catch (err) {
209
+ if (err instanceof backend_1.AtlasApiError && err.status === 404)
210
+ throw new errors_1.CliError(`No OAuth client ${ref} on this instance.`);
211
+ throw err;
212
+ }
213
+ const product = (0, args_1.str)(v, 'product') ?? cred.manifest?.product;
214
+ const env = cred.instance?.environment;
215
+ const fileName = product && env && cred.instance?.oauth_client?.id === res.id ? `${env}-oauth-client.env` : `oauth-client-${res.id}.env`;
216
+ const entries = { ATLAS_CLIENT_ID: res.client_id, ATLAS_CLIENT_SECRET: res.client_secret };
217
+ if (v['print-secret'] === true) {
218
+ (0, secrets_1.deliverSecret)({ io: ctx.io, env: ctx.env, product: product ?? 'atlasauth', fileName, entries, label: 'The new client secret', printSecret: true });
219
+ }
220
+ else {
221
+ // A rotation replaces the file by design: the old secret is the one being retired.
222
+ const { path } = (0, secrets_1.writeSecretFile)((0, secrets_1.productDir)(ctx.env, product ?? 'atlasauth'), fileName, entries, {
223
+ force: true,
224
+ comment: `OAuth client ${res.id}. Server-side only.`,
225
+ });
226
+ ctx.io.out(`New client secret for ${res.client_id} written to ${path} (mode 0600).`);
227
+ }
228
+ const expires = res.previous_secret_expires_at;
229
+ if (overlapSeconds === 0 || expires === null)
230
+ ctx.io.out('The previous secret stopped working immediately.');
231
+ else if (typeof expires === 'number')
232
+ ctx.io.out(`The previous secret keeps working until ${new Date(expires).toISOString()}.`);
233
+ else
234
+ ctx.io.out('The API did not say when the previous secret stops working; assume immediately and deploy the new one now.');
235
+ return 0;
236
+ }
237
+ //# sourceMappingURL=project-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-commands.js","sourceRoot":"","sources":["../../src/commands/project-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { type ParsedArgs } from '../args';
2
+ import type { RunContext } from '../context';
3
+ /**
4
+ * `atlas referrals connect | backfill | status`: referral attribution from the
5
+ * terminal.
6
+ *
7
+ * `connect --provider referally` is bring-your-own-key: the Referally merchant
8
+ * key is used for one call (it creates the Atlas connection on Referally) and
9
+ * is never stored or printed. The connection id and secret Referally returns
10
+ * go straight onto the instance; the secret is never printed either.
11
+ */
12
+ /** The Referally API version pinned on every call. */
13
+ export declare const REFERALLY_VERSION = "2026-10-21";
14
+ interface PingRead {
15
+ ok?: boolean;
16
+ org_name?: string | null;
17
+ program_name?: string | null;
18
+ program_id?: string | null;
19
+ auto_enroll_users?: boolean | null;
20
+ server_time?: string | number | null;
21
+ clock_skew_ms?: number | null;
22
+ }
23
+ interface TestRead {
24
+ ok: boolean;
25
+ http_status?: number | null;
26
+ latency_ms?: number | null;
27
+ error?: {
28
+ code: string;
29
+ message: string;
30
+ } | null;
31
+ ping?: PingRead | null;
32
+ }
33
+ /** Platform clock minus ours, in ms, from a ping. */
34
+ export declare function pingSkewMs(ping: PingRead, receivedAt: number, latencyMs?: number | null): number | null;
35
+ /** Lines describing a connection test (a ping where the provider supports it). */
36
+ export declare function describeTestLines(test: TestRead, receivedAt: number): string[];
37
+ /** A `customerRef,code` CSV → map; throws on a bad line. A header row is skipped. */
38
+ export declare function parseCodeCsv(text: string): Record<string, string>;
39
+ export declare function referrals(ctx: RunContext, args: ParsedArgs): Promise<number>;
40
+ export {};