@formigio/fazemos-cli 0.10.78 → 0.10.79
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/dist/auth.d.ts +31 -3
- package/dist/auth.js +109 -19
- package/dist/auth.js.map +1 -1
- package/dist/authConfig.d.ts +43 -0
- package/dist/authConfig.js +54 -0
- package/dist/authConfig.js.map +1 -0
- package/dist/config.d.ts +53 -13
- package/dist/config.js +22 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +71 -36
- package/dist/index.js.map +1 -1
- package/dist/oidc.d.ts +111 -0
- package/dist/oidc.js +283 -0
- package/dist/oidc.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,8 @@ getActiveProjectId, setActiveProjectId, clearActiveProjectId, findProjectBySlug,
|
|
|
7
7
|
// Directory-scoped context override (.fazemos.json)
|
|
8
8
|
setOrgOverride, setProjectOverride, setDirContextSource, getDirContextSource, } from './config.js';
|
|
9
9
|
import { findDirContextFile, readDirContextFile, writeDirContextFile, removeDirContextFile, DIR_CONFIG_FILENAME, } from './dircontext.js';
|
|
10
|
-
import {
|
|
10
|
+
import { loginWithBrowser, hostedLogoutUrl, signup, confirmSignup, adminLogin } from './auth.js';
|
|
11
|
+
import { fetchAuthConfig } from './authConfig.js';
|
|
11
12
|
import { api, ApiError, refreshAuthMeCache, invalidateAuthMeCache, resolveOrgIdMaybeSlug, resolveProjectIdBySlug, patchProjectDocsRepo, patchOrgWorkspace } from './api.js';
|
|
12
13
|
import { isProjectConnectionUnavailable, renderProjectConnectionUnavailableCopy, } from './connectionErrorCopy.js';
|
|
13
14
|
import { loadYaml, summarize } from './yaml/load.js';
|
|
@@ -328,55 +329,70 @@ program.hook('preAction', async (_thisCommand, actionCommand) => {
|
|
|
328
329
|
// ── Init ────────────────────────────────────────────────────
|
|
329
330
|
program
|
|
330
331
|
.command('init')
|
|
331
|
-
.description('Configure an environment (
|
|
332
|
+
.description('Configure an environment (discovers Cognito settings from the API)')
|
|
332
333
|
.argument('<name>', 'Environment name (e.g., dev, prod, local)')
|
|
333
334
|
.requiredOption('--api-url <url>', 'API base URL')
|
|
334
|
-
.option('--cognito-pool <id>', 'Cognito User Pool ID (
|
|
335
|
-
.option('--cognito-client <id>', 'Cognito
|
|
336
|
-
.option('--cognito-
|
|
335
|
+
.option('--cognito-pool <id>', 'Cognito User Pool ID (discovered if omitted)')
|
|
336
|
+
.option('--cognito-client <id>', 'Cognito app client ID for the web console (discovered if omitted)')
|
|
337
|
+
.option('--cognito-cli-client <id>', 'Cognito app client ID for the CLI (discovered if omitted)')
|
|
338
|
+
.option('--hosted-ui <domain>', 'Cognito hosted-UI origin, e.g. https://jj-auth-dev.auth.us-west-2.amazoncognito.com (discovered if omitted)')
|
|
339
|
+
.option('--cognito-region <region>', 'Cognito region (discovered if omitted)')
|
|
337
340
|
.action(async (name, opts) => {
|
|
341
|
+
const apiUrl = opts.apiUrl.replace(/\/$/, '');
|
|
338
342
|
let poolId = opts.cognitoPool;
|
|
339
343
|
let clientId = opts.cognitoClient;
|
|
344
|
+
let cliClientId = opts.cognitoCliClient;
|
|
345
|
+
let hostedUiDomain = opts.hostedUi;
|
|
340
346
|
let region = opts.cognitoRegion;
|
|
341
|
-
//
|
|
342
|
-
|
|
347
|
+
// Discovery is the normal path; the flags exist for an API that predates
|
|
348
|
+
// GET /auth/config, or for pointing at a stack whose config endpoint is
|
|
349
|
+
// temporarily degraded. Anything supplied by flag wins — the operator has
|
|
350
|
+
// more context than the endpoint does about why they typed it.
|
|
351
|
+
const needsDiscovery = !poolId || !cliClientId || !hostedUiDomain || !region;
|
|
352
|
+
if (needsDiscovery) {
|
|
343
353
|
try {
|
|
344
|
-
console.log(chalk.cyan(
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
console.log(chalk.yellow('Auto-discovery not available — provide --cognito-pool and --cognito-client'));
|
|
355
|
-
process.exit(1);
|
|
356
|
-
}
|
|
354
|
+
console.log(chalk.cyan(`Discovering auth config from ${apiUrl}/auth/config ...`));
|
|
355
|
+
const cfg = await fetchAuthConfig(apiUrl);
|
|
356
|
+
poolId = poolId || cfg.cognito.userPoolId;
|
|
357
|
+
clientId = clientId || cfg.cognito.clients.web.clientId;
|
|
358
|
+
cliClientId = cliClientId || cfg.cognito.clients.cli.clientId;
|
|
359
|
+
hostedUiDomain = hostedUiDomain || cfg.cognito.hostedUiDomain;
|
|
360
|
+
region = region || cfg.cognito.region;
|
|
361
|
+
console.log(chalk.green('Discovered Cognito settings'));
|
|
357
362
|
}
|
|
358
|
-
catch {
|
|
359
|
-
console.error(chalk.red(
|
|
363
|
+
catch (err) {
|
|
364
|
+
console.error(chalk.red(err.message));
|
|
360
365
|
process.exit(1);
|
|
361
366
|
}
|
|
362
367
|
}
|
|
363
|
-
if (!poolId
|
|
364
|
-
console.error(chalk.red('Missing Cognito Pool ID
|
|
368
|
+
if (!poolId) {
|
|
369
|
+
console.error(chalk.red('Missing Cognito Pool ID — pass --cognito-pool.'));
|
|
365
370
|
process.exit(1);
|
|
366
371
|
}
|
|
367
372
|
addEnvironment(name, {
|
|
368
|
-
apiUrl
|
|
373
|
+
apiUrl,
|
|
369
374
|
cognitoPoolId: poolId,
|
|
370
|
-
cognitoClientId: clientId,
|
|
375
|
+
cognitoClientId: clientId || '',
|
|
371
376
|
cognitoRegion: region || 'us-west-2',
|
|
377
|
+
cognitoCliClientId: cliClientId || undefined,
|
|
378
|
+
hostedUiDomain: hostedUiDomain || undefined,
|
|
372
379
|
});
|
|
373
380
|
console.log(chalk.green(`Environment "${name}" configured`));
|
|
374
|
-
console.log(` API:
|
|
375
|
-
console.log(` Pool:
|
|
376
|
-
console.log(`
|
|
377
|
-
console.log(`
|
|
381
|
+
console.log(` API: ${apiUrl}`);
|
|
382
|
+
console.log(` Pool: ${poolId}`);
|
|
383
|
+
console.log(` Region: ${region || 'us-west-2'}`);
|
|
384
|
+
console.log(` Web client: ${clientId || chalk.yellow('(none)')}`);
|
|
385
|
+
console.log(` CLI client: ${cliClientId || chalk.yellow('(none)')}`);
|
|
386
|
+
console.log(` Hosted UI: ${hostedUiDomain || chalk.yellow('(none)')}`);
|
|
387
|
+
// `auth login` needs both of these and refetches /auth/config anyway, so
|
|
388
|
+
// this is a warning rather than a failure — the environment is still
|
|
389
|
+
// usable for anything that runs on an existing token.
|
|
390
|
+
if (!cliClientId || !hostedUiDomain) {
|
|
391
|
+
console.log(chalk.yellow(`\nNo CLI app client or hosted-UI domain: \`fazemos auth login\` will not work ` +
|
|
392
|
+
`against this environment until the API's /auth/config advertises them.`));
|
|
393
|
+
}
|
|
378
394
|
if (config.get('activeEnv') === name) {
|
|
379
|
-
console.log(chalk.cyan(` Active:
|
|
395
|
+
console.log(chalk.cyan(` Active: yes`));
|
|
380
396
|
}
|
|
381
397
|
});
|
|
382
398
|
// ── Environment ─────────────────────────────────────────────
|
|
@@ -418,6 +434,10 @@ program
|
|
|
418
434
|
console.log(` Environment: ${chalk.cyan(env.name)}${srcLabel}`);
|
|
419
435
|
console.log(` API: ${env.apiUrl}`);
|
|
420
436
|
console.log(` Cognito: ${env.cognitoPoolId}`);
|
|
437
|
+
// `auth login` needs both of these; showing them here is how you tell a
|
|
438
|
+
// stale environment (configured before OIDC login) from a broken one.
|
|
439
|
+
console.log(` CLI client: ${env.cognitoCliClientId || chalk.yellow('(not discovered — run: fazemos auth login)')}`);
|
|
440
|
+
console.log(` Hosted UI: ${env.hostedUiDomain || chalk.yellow('(not discovered — run: fazemos auth login)')}`);
|
|
421
441
|
const token = getToken();
|
|
422
442
|
console.log(` Auth: ${token ? chalk.green('authenticated') : chalk.yellow('not logged in')}`);
|
|
423
443
|
});
|
|
@@ -425,12 +445,12 @@ program
|
|
|
425
445
|
const auth = program.command('auth').description('Authentication commands');
|
|
426
446
|
auth
|
|
427
447
|
.command('login')
|
|
428
|
-
.description('
|
|
429
|
-
.
|
|
430
|
-
.requiredOption('-p, --password <password>', 'Password')
|
|
448
|
+
.description('Sign in through your browser (Cognito hosted UI, auth-code + PKCE)')
|
|
449
|
+
.option('--no-browser', 'Print the sign-in URL instead of launching a browser')
|
|
431
450
|
.action(async (opts) => {
|
|
432
451
|
try {
|
|
433
|
-
|
|
452
|
+
// Commander turns `--no-browser` into `opts.browser === false`.
|
|
453
|
+
const result = await loginWithBrowser({ noBrowser: opts.browser === false });
|
|
434
454
|
console.log(chalk.green(`Logged in as ${result.email}`));
|
|
435
455
|
}
|
|
436
456
|
catch (err) {
|
|
@@ -496,13 +516,28 @@ auth
|
|
|
496
516
|
});
|
|
497
517
|
auth
|
|
498
518
|
.command('logout')
|
|
499
|
-
.description('Clear stored credentials')
|
|
519
|
+
.description('Clear stored credentials (prints the URL to end the browser session too)')
|
|
500
520
|
.action(() => {
|
|
501
521
|
const env = getActiveEnvName();
|
|
502
522
|
const auths = config.get('auth');
|
|
503
523
|
delete auths[env];
|
|
504
524
|
config.set('auth', auths);
|
|
505
525
|
console.log(chalk.green(`Logged out of ${env}`));
|
|
526
|
+
// Clearing local tokens does NOT end the Cognito hosted-UI session — the
|
|
527
|
+
// browser still holds it, so the next `auth login` signs straight back in
|
|
528
|
+
// with no prompt. That is usually what you want; when it is not (shared
|
|
529
|
+
// machine, switching accounts) this URL is how you actually sign out.
|
|
530
|
+
let url = null;
|
|
531
|
+
try {
|
|
532
|
+
url = hostedLogoutUrl();
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
// No environment configured — nothing further to offer.
|
|
536
|
+
}
|
|
537
|
+
if (url) {
|
|
538
|
+
console.log(chalk.gray(`\nStill signed in to the browser session. To end it too, open:`));
|
|
539
|
+
console.log(chalk.gray(` ${url}`));
|
|
540
|
+
}
|
|
506
541
|
});
|
|
507
542
|
// ── Whoami ──────────────────────────────────────────────────
|
|
508
543
|
program
|