seamless-cli 0.10.2 → 0.11.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/README.md +197 -29
- package/dist/commands/apps.js +147 -0
- package/dist/commands/apps.js.map +1 -0
- package/dist/commands/config.js +16 -15
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/help.js +65 -187
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/helpTopics.js +376 -0
- package/dist/commands/helpTopics.js.map +1 -0
- package/dist/commands/init.js +295 -76
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/instanceLogin.js +55 -0
- package/dist/commands/instanceLogin.js.map +1 -0
- package/dist/commands/login.js +42 -80
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +18 -8
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/org.js +5 -4
- package/dist/commands/org.js.map +1 -1
- package/dist/commands/profile.js +29 -2
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/sessions.js +9 -7
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/templates.js +58 -0
- package/dist/commands/templates.js.map +1 -0
- package/dist/commands/users.js +9 -7
- package/dist/commands/users.js.map +1 -1
- package/dist/commands/verify.js +5 -2
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/whoami.js +13 -5
- package/dist/commands/whoami.js.map +1 -1
- package/dist/core/args.js +11 -0
- package/dist/core/args.js.map +1 -1
- package/dist/core/authClient.js +29 -6
- package/dist/core/authClient.js.map +1 -1
- package/dist/core/cancel.js +32 -0
- package/dist/core/cancel.js.map +1 -0
- package/dist/core/config.js +45 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/confirmAction.js +26 -0
- package/dist/core/confirmAction.js.map +1 -0
- package/dist/core/images.js +3 -3
- package/dist/core/interactiveLogin.js +72 -0
- package/dist/core/interactiveLogin.js.map +1 -0
- package/dist/core/output.js +23 -9
- package/dist/core/output.js.map +1 -1
- package/dist/core/portal.js +112 -8
- package/dist/core/portal.js.map +1 -1
- package/dist/core/templates.js +10 -0
- package/dist/core/templates.js.map +1 -1
- package/dist/core/tty.js +25 -0
- package/dist/core/tty.js.map +1 -0
- package/dist/generators/auth/auth.js +8 -7
- package/dist/generators/auth/auth.js.map +1 -1
- package/dist/generators/docker/docker.js +27 -21
- package/dist/generators/docker/docker.js.map +1 -1
- package/dist/index.js +89 -21
- package/dist/index.js.map +1 -1
- package/dist/prompts/appSelect.js +16 -10
- package/dist/prompts/appSelect.js.map +1 -1
- package/dist/prompts/initMode.js +77 -0
- package/dist/prompts/initMode.js.map +1 -0
- package/dist/prompts/oauthSetup.js +4 -3
- package/dist/prompts/oauthSetup.js.map +1 -1
- package/dist/prompts/projectSetup.js +77 -50
- package/dist/prompts/projectSetup.js.map +1 -1
- package/dist/testSetup.js +9 -0
- package/dist/testSetup.js.map +1 -0
- package/package.json +1 -1
- package/verify/adapter-app/package.json +1 -1
- package/verify/docker-compose.verify.yml +4 -3
- package/verify/harness/api/ownerAdmin.spec.ts +24 -0
- package/verify/harness/lib/env.ts +3 -4
- package/verify/harness/lib/flows.ts +1 -36
- package/verify/harness/playwright.config.ts +8 -3
- package/dist/commands/bootstrapAdmin.js +0 -96
- package/dist/commands/bootstrapAdmin.js.map +0 -1
- package/dist/core/bootstrapSecret.js +0 -39
- package/dist/core/bootstrapSecret.js.map +0 -1
- package/verify/harness/api/adminBootstrap.spec.ts +0 -34
package/dist/core/output.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import kleur from "kleur";
|
|
2
2
|
export function printSuccessOutput(config) {
|
|
3
|
-
const { projectName, webFramework, apiFramework, authMode, useDocker, adminMode } = config;
|
|
3
|
+
const { projectName, webFramework, apiFramework, authMode, useDocker, adminMode, ownerEmail, } = config;
|
|
4
4
|
// Where the admin console lives: proxied by the app API at /console, or a
|
|
5
5
|
// standalone container on 5174. "none" scaffolds no console at all.
|
|
6
6
|
const consoleUrl = adminMode === "api"
|
|
@@ -43,10 +43,8 @@ export function printSuccessOutput(config) {
|
|
|
43
43
|
if (useDocker) {
|
|
44
44
|
console.log(" 1. Start services");
|
|
45
45
|
console.log(kleur.cyan(" docker compose up\n"));
|
|
46
|
-
console.log(" 2.
|
|
47
|
-
console.log(kleur.
|
|
48
|
-
console.log(" 3. Complete registration in the browser");
|
|
49
|
-
console.log(kleur.dim(" This grants admin access to the system\n"));
|
|
46
|
+
console.log(" 2. Register in the browser with " + kleur.bold(ownerEmail));
|
|
47
|
+
console.log(kleur.dim(" That address is the owner, so it becomes an admin\n"));
|
|
50
48
|
}
|
|
51
49
|
else {
|
|
52
50
|
if (authMode === "local") {
|
|
@@ -68,8 +66,7 @@ export function printSuccessOutput(config) {
|
|
|
68
66
|
console.log(kleur.dim(" # Web app"));
|
|
69
67
|
console.log(" cd web && npm install && npm run dev\n");
|
|
70
68
|
}
|
|
71
|
-
console.log("
|
|
72
|
-
console.log(kleur.cyan(" seamless bootstrap-admin\n"));
|
|
69
|
+
console.log(" Register with " + kleur.bold(ownerEmail) + " to become an admin.\n");
|
|
73
70
|
}
|
|
74
71
|
console.log(kleur.bold("Available services:\n"));
|
|
75
72
|
console.log(" Auth: " + kleur.cyan("http://localhost:5312"));
|
|
@@ -91,13 +88,14 @@ export function printSuccessOutput(config) {
|
|
|
91
88
|
? " • Admin console is served by the API at /console"
|
|
92
89
|
: " • Admin console uses the same auth system"));
|
|
93
90
|
}
|
|
94
|
-
console.log(kleur.dim(
|
|
91
|
+
console.log(kleur.dim(` • ${ownerEmail} is the owner: registering with it grants the admin role`));
|
|
92
|
+
console.log(kleur.dim(" • The grant happens at signup, so change OWNER_EMAIL in auth before registering"));
|
|
95
93
|
console.log(kleur.dim(" • All secrets and keys are pre-configured\n"));
|
|
96
94
|
console.log(kleur.dim("Docs: ") + kleur.cyan("https://docs.seamlessauth.com\n"));
|
|
97
95
|
console.log(kleur.bold().green("Setup complete.\n"));
|
|
98
96
|
}
|
|
99
97
|
export function printManagedSuccessOutput(config) {
|
|
100
|
-
const { projectName, webFramework, apiFramework, authServerUrl, appName } = config;
|
|
98
|
+
const { projectName, webFramework, apiFramework, authServerUrl, appName, databaseUrl, } = config;
|
|
101
99
|
const title = kleur.bold().cyan("SEAMLESS");
|
|
102
100
|
console.log(`
|
|
103
101
|
╔════════════════════════════════════════╗
|
|
@@ -126,6 +124,16 @@ export function printManagedSuccessOutput(config) {
|
|
|
126
124
|
console.log(" • " + kleur.white("Auth server") + kleur.dim(" (managed instance)"));
|
|
127
125
|
console.log("");
|
|
128
126
|
console.log(kleur.bold("Next steps:\n"));
|
|
127
|
+
// The placeholders are the only thing standing between the scaffold and a
|
|
128
|
+
// working database, so they lead rather than sitting in a footnote.
|
|
129
|
+
if (databaseUrl) {
|
|
130
|
+
console.log(kleur.dim(" # Database"));
|
|
131
|
+
console.log(" Fill in the credentials in " +
|
|
132
|
+
kleur.cyan("api/.env") +
|
|
133
|
+
kleur.dim(" (DATABASE_URL):"));
|
|
134
|
+
console.log(" " + kleur.dim(maskDatabaseUrl(databaseUrl)));
|
|
135
|
+
console.log(kleur.dim(" Copy the user and password from the dashboard.\n"));
|
|
136
|
+
}
|
|
129
137
|
if (apiFramework) {
|
|
130
138
|
console.log(kleur.dim(" # API server"));
|
|
131
139
|
console.log(" cd api && npm install && npm run dev\n");
|
|
@@ -142,6 +150,12 @@ export function printManagedSuccessOutput(config) {
|
|
|
142
150
|
console.log(kleur.dim("Docs: ") + kleur.cyan("https://docs.seamlessauth.com\n"));
|
|
143
151
|
console.log(kleur.bold().green("Setup complete.\n"));
|
|
144
152
|
}
|
|
153
|
+
// Belt and braces: the CLI only ever holds a placeholder connection string, but
|
|
154
|
+
// anything printed as a connection string gets its userinfo masked so a real one
|
|
155
|
+
// pasted through here could never be echoed back in full.
|
|
156
|
+
export function maskDatabaseUrl(url) {
|
|
157
|
+
return url.replace(/\/\/[^@/]*@/, "//****:****@");
|
|
158
|
+
}
|
|
145
159
|
function formatFramework(name) {
|
|
146
160
|
const map = {
|
|
147
161
|
react: "React",
|
package/dist/core/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/core/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/core/output.ts"],"names":[],"mappings":"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"}
|
package/dist/core/portal.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { joinUrl } from "./http.js";
|
|
2
|
-
// The managed control plane (seamless-portal-api). It
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
2
|
+
// The managed control plane (seamless-portal-api). It only recognizes sessions
|
|
3
|
+
// from the portal's own auth instance (getPortalAuthUrl), so these calls take a
|
|
4
|
+
// createPortalClient and never the active profile's client: an instance session
|
|
5
|
+
// belongs to a different user pool on a different host. Override the host for
|
|
6
|
+
// staging or local portal development with SEAMLESS_PORTAL_API_URL.
|
|
6
7
|
export const DEFAULT_PORTAL_API_URL = "https://api.seamlessauth.com";
|
|
7
8
|
export function getPortalApiUrl() {
|
|
8
9
|
const override = process.env.SEAMLESS_PORTAL_API_URL?.trim();
|
|
@@ -15,24 +16,68 @@ export class PortalError extends Error {
|
|
|
15
16
|
this.name = "PortalError";
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
// Split out so a caller can retry a lookup by another reference (a name or infra
|
|
20
|
+
// id) without matching on message text.
|
|
21
|
+
export class PortalNotFoundError extends PortalError {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = "PortalNotFoundError";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Where this application's auth answers, or undefined while it is still
|
|
28
|
+
// provisioning.
|
|
29
|
+
export function resolveAppInstanceUrl(app) {
|
|
30
|
+
return app.instanceUrl ?? app.domain;
|
|
31
|
+
}
|
|
32
|
+
// The shortest reference that still identifies the application, for display and
|
|
33
|
+
// for pasting into `apps get` or `init --app`. Both accept an infra id, and it
|
|
34
|
+
// is far easier to read than the UUID primary key. Applications that have not
|
|
35
|
+
// been provisioned have no infra id yet, so they fall back to the id.
|
|
36
|
+
export function resolveAppRef(app) {
|
|
37
|
+
return app.infraId ?? app.id;
|
|
38
|
+
}
|
|
18
39
|
function str(raw, key) {
|
|
19
40
|
const value = raw[key];
|
|
20
41
|
return typeof value === "string" && value ? value : undefined;
|
|
21
42
|
}
|
|
43
|
+
function strList(raw, key) {
|
|
44
|
+
const value = raw[key];
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
return value.filter((item) => typeof item === "string");
|
|
47
|
+
}
|
|
48
|
+
return typeof value === "string" && value ? [value] : [];
|
|
49
|
+
}
|
|
50
|
+
function toServiceToken(raw) {
|
|
51
|
+
const meta = raw.serviceTokenMetadata;
|
|
52
|
+
if (!meta || typeof meta !== "object")
|
|
53
|
+
return undefined;
|
|
54
|
+
const record = meta;
|
|
55
|
+
return {
|
|
56
|
+
maskedToken: str(record, "maskedToken"),
|
|
57
|
+
createdAt: str(record, "createdAt"),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
22
60
|
function toApp(raw) {
|
|
23
61
|
const id = str(raw, "id");
|
|
24
|
-
|
|
25
|
-
if (!id || !domain)
|
|
62
|
+
if (!id)
|
|
26
63
|
return null;
|
|
27
64
|
return {
|
|
28
65
|
id,
|
|
29
66
|
name: str(raw, "name") ?? id,
|
|
30
|
-
|
|
67
|
+
instanceUrl: str(raw, "instanceUrl"),
|
|
68
|
+
domain: str(raw, "domain"),
|
|
69
|
+
consoleUrl: str(raw, "consoleUrl"),
|
|
31
70
|
infraId: str(raw, "infraId"),
|
|
32
71
|
frontendUrl: str(raw, "frontendUrl"),
|
|
33
72
|
servicePlan: str(raw, "servicePlan"),
|
|
34
73
|
status: str(raw, "status"),
|
|
74
|
+
hostedRegion: str(raw, "hostedRegion"),
|
|
75
|
+
devMode: typeof raw.devMode === "boolean" ? raw.devMode : undefined,
|
|
76
|
+
ownerEmails: strList(raw, "ownerEmail"),
|
|
77
|
+
trialExpiresAt: str(raw, "trialExpiresAt"),
|
|
78
|
+
createdAt: str(raw, "createdAt"),
|
|
35
79
|
hasServiceToken: raw.serviceTokenMetadata != null,
|
|
80
|
+
serviceToken: toServiceToken(raw),
|
|
36
81
|
};
|
|
37
82
|
}
|
|
38
83
|
function unauthorized(action) {
|
|
@@ -53,6 +98,65 @@ export async function listApplications(client) {
|
|
|
53
98
|
.map(toApp)
|
|
54
99
|
.filter((a) => a !== null);
|
|
55
100
|
}
|
|
101
|
+
export async function getApplication(client, appId) {
|
|
102
|
+
const url = joinUrl(getPortalApiUrl(), `/applications/${encodeURIComponent(appId)}`);
|
|
103
|
+
const res = await client.get(url);
|
|
104
|
+
if (res.status === 401 || res.status === 403) {
|
|
105
|
+
throw unauthorized("read this application");
|
|
106
|
+
}
|
|
107
|
+
if (res.status === 404) {
|
|
108
|
+
throw new PortalNotFoundError(`Managed application "${appId}" was not found.`);
|
|
109
|
+
}
|
|
110
|
+
if (!res.ok) {
|
|
111
|
+
throw new PortalError(`Could not load application "${appId}" (${res.status}).`);
|
|
112
|
+
}
|
|
113
|
+
const raw = res.data?.application;
|
|
114
|
+
const app = raw && typeof raw === "object"
|
|
115
|
+
? toApp(raw)
|
|
116
|
+
: null;
|
|
117
|
+
if (!app) {
|
|
118
|
+
throw new PortalError(`The control plane returned an unexpected response for "${appId}".`);
|
|
119
|
+
}
|
|
120
|
+
return app;
|
|
121
|
+
}
|
|
122
|
+
// Reads the bundled database. Returns null when the control plane has not
|
|
123
|
+
// provisioned one yet, which is a normal state for an application mid-deploy
|
|
124
|
+
// and must not fail a scaffold.
|
|
125
|
+
export async function getApplicationDatabase(client, appId) {
|
|
126
|
+
const url = joinUrl(getPortalApiUrl(), `/applications/${encodeURIComponent(appId)}/database`);
|
|
127
|
+
const res = await client.get(url);
|
|
128
|
+
if (res.status === 401 || res.status === 403) {
|
|
129
|
+
throw unauthorized("read this application's database");
|
|
130
|
+
}
|
|
131
|
+
if (res.status === 404) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
if (!res.ok) {
|
|
135
|
+
throw new PortalError(`Could not read the database for "${appId}" (${res.status}).`);
|
|
136
|
+
}
|
|
137
|
+
const raw = res.data?.database;
|
|
138
|
+
if (!raw || typeof raw !== "object")
|
|
139
|
+
return null;
|
|
140
|
+
const record = raw;
|
|
141
|
+
const host = str(record, "host");
|
|
142
|
+
const database = str(record, "database");
|
|
143
|
+
if (!host || !database)
|
|
144
|
+
return null;
|
|
145
|
+
const port = Number(record.port);
|
|
146
|
+
return {
|
|
147
|
+
host,
|
|
148
|
+
database,
|
|
149
|
+
port: Number.isFinite(port) && port > 0 ? port : 5432,
|
|
150
|
+
engine: str(record, "engine"),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
// The connection string written into a scaffolded api/.env. USER and PASSWORD
|
|
154
|
+
// stay as literal placeholders: obvious to spot, obvious to replace, and
|
|
155
|
+
// impossible to mistake for working credentials. sslmode=require matches what
|
|
156
|
+
// the control plane hands out, and is what makes the starter negotiate TLS.
|
|
157
|
+
export function buildScaffoldDatabaseUrl(db) {
|
|
158
|
+
return `postgres://USER:PASSWORD@${db.host}:${db.port}/${db.database}?sslmode=require`;
|
|
159
|
+
}
|
|
56
160
|
// Issues (rotates) the application's service token. The control plane only ever
|
|
57
161
|
// returns a raw token at rotation time (it is stored write-once), so this is the
|
|
58
162
|
// real credential flow: the token the auth instance already recognizes for this
|
|
@@ -64,7 +168,7 @@ export async function rotateServiceToken(client, appId) {
|
|
|
64
168
|
throw unauthorized("issue a service token");
|
|
65
169
|
}
|
|
66
170
|
if (res.status === 404) {
|
|
67
|
-
throw new
|
|
171
|
+
throw new PortalNotFoundError(`Managed application "${appId}" was not found.`);
|
|
68
172
|
}
|
|
69
173
|
if (!res.ok || !res.data?.serviceToken) {
|
|
70
174
|
throw new PortalError(`Could not issue a service token (${res.status}).`);
|
package/dist/core/portal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../src/core/portal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC
|
|
1
|
+
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../src/core/portal.ts"],"names":[],"mappings":"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"}
|
package/dist/core/templates.js
CHANGED
|
@@ -5,6 +5,15 @@ import { VERSION } from "../index.js";
|
|
|
5
5
|
import { parseEnvString, writeEnv } from "./env.js";
|
|
6
6
|
import { generateSecret } from "./secrets.js";
|
|
7
7
|
import { SEAMLESS_TEMPLATES_REF, SEAMLESS_TEMPLATES_REPO } from "./images.js";
|
|
8
|
+
// The command-line spellings for a template, longest-lived first. The id always
|
|
9
|
+
// works because it is what `seamless templates list` and the registry show; the
|
|
10
|
+
// alias is a shorter synonym some templates also declare.
|
|
11
|
+
export function templateFlags(entry) {
|
|
12
|
+
return entry.alias ? [`--${entry.alias}`, `--${entry.id}`] : [`--${entry.id}`];
|
|
13
|
+
}
|
|
14
|
+
export function matchesTemplateFlag(entry, flag) {
|
|
15
|
+
return entry.alias === flag || entry.id === flag;
|
|
16
|
+
}
|
|
8
17
|
// Build artifacts and local-only files that must never be copied into a scaffold,
|
|
9
18
|
// even if a local template checkout has them lying around.
|
|
10
19
|
const IGNORED_NAMES = new Set([
|
|
@@ -162,6 +171,7 @@ function resolveToken(token, ctx) {
|
|
|
162
171
|
apiToken: ctx.apiToken,
|
|
163
172
|
jwksKid: ctx.jwksKid,
|
|
164
173
|
serveAdminConsole: ctx.serveAdminConsole,
|
|
174
|
+
databaseUrl: ctx.databaseUrl,
|
|
165
175
|
};
|
|
166
176
|
if (token in known) {
|
|
167
177
|
const resolved = known[token];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"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"}
|
package/dist/core/tty.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// A terminal narrower than this cannot render a @clack/prompts list legibly. It
|
|
2
|
+
// shows up when a pty is allocated without a size (an expect script, some CI
|
|
3
|
+
// runners), which used to produce one character per line with no explanation.
|
|
4
|
+
const MIN_USABLE_COLUMNS = 20;
|
|
5
|
+
export function isInteractive() {
|
|
6
|
+
return process.stdin.isTTY === true;
|
|
7
|
+
}
|
|
8
|
+
// Refuses to ask a question nobody can answer. Without a TTY a prompt renders
|
|
9
|
+
// and then waits forever, so a run on a pipe used to hang until its job timed
|
|
10
|
+
// out rather than failing.
|
|
11
|
+
export function requireInteractive(question, remedy) {
|
|
12
|
+
if (isInteractive())
|
|
13
|
+
return;
|
|
14
|
+
throw new Error(`"${question}" needs an interactive terminal, and this run does not have one. ${remedy}`);
|
|
15
|
+
}
|
|
16
|
+
// Warns rather than failing: a narrow terminal still accepts input, so the
|
|
17
|
+
// prompts work even when they look wrong.
|
|
18
|
+
export function warnOnUnusableWidth(warn) {
|
|
19
|
+
const columns = process.stdout.columns;
|
|
20
|
+
if (!isInteractive() || columns === undefined || columns >= MIN_USABLE_COLUMNS) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
warn(`This terminal reports ${columns} columns, so the prompts below will render badly. Resize it, or re-run with --yes to skip them.`);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=tty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tty.js","sourceRoot":"","sources":["../../src/core/tty.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;AACtC,CAAC;AAED,8EAA8E;AAC9E,8EAA8E;AAC9E,2BAA2B;AAC3B,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,MAAc;IACjE,IAAI,aAAa,EAAE;QAAE,OAAO;IAE5B,MAAM,IAAI,KAAK,CACb,IAAI,QAAQ,oEAAoE,MAAM,EAAE,CACzF,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,0CAA0C;AAC1C,MAAM,UAAU,mBAAmB,CAAC,IAA+B;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;IACvC,IAAI,CAAC,aAAa,EAAE,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,IAAI,kBAAkB,EAAE,CAAC;QAC/E,OAAO;IACT,CAAC;IAED,IAAI,CACF,yBAAyB,OAAO,iGAAiG,CAClI,CAAC;AACJ,CAAC"}
|
|
@@ -6,19 +6,19 @@ import { fetchEnvExample } from "../../core/fetch.js";
|
|
|
6
6
|
import { POSTGRES_IMAGE, SEAMLESS_AUTH_API_IMAGE } from "../../core/images.js";
|
|
7
7
|
import { buildAuthEnv, configureAuthLocalEnv, envToDockerBlock, } from "../docker/docker.js";
|
|
8
8
|
const AUTH_REPO = "https://github.com/fells-code/seamless-auth-api";
|
|
9
|
-
export async function generateAuthServer(context, mode, oauth = [], adminMode = "api") {
|
|
9
|
+
export async function generateAuthServer(context, mode, oauth = [], adminMode = "api", ownerEmail) {
|
|
10
10
|
const { root } = context;
|
|
11
11
|
if (mode === "local") {
|
|
12
|
-
return await setupLocalAuth(root, oauth, adminMode);
|
|
12
|
+
return await setupLocalAuth(root, oauth, adminMode, ownerEmail);
|
|
13
13
|
}
|
|
14
14
|
return await setupDockerAuth(root);
|
|
15
15
|
}
|
|
16
|
-
async function setupLocalAuth(root, oauth = [], adminMode = "api") {
|
|
16
|
+
async function setupLocalAuth(root, oauth = [], adminMode = "api", ownerEmail) {
|
|
17
17
|
const authDir = path.join(root, "auth");
|
|
18
18
|
console.log("Cloning SeamlessAuth server...");
|
|
19
19
|
await runCommand("git", ["clone", AUTH_REPO, "auth"], root);
|
|
20
20
|
console.log("Writing auth environment...");
|
|
21
|
-
const shared = await configureAuthLocalEnv(root, oauth, adminMode);
|
|
21
|
+
const shared = await configureAuthLocalEnv(root, oauth, adminMode, ownerEmail);
|
|
22
22
|
console.log("Auth server ready in /auth");
|
|
23
23
|
return shared;
|
|
24
24
|
}
|
|
@@ -28,13 +28,14 @@ async function setupDockerAuth(root) {
|
|
|
28
28
|
const parsed = parseEnvString(raw);
|
|
29
29
|
const { env, shared } = buildAuthEnv(parsed, "docker");
|
|
30
30
|
const envBlock = envToDockerBlock(env);
|
|
31
|
-
const dockerCompose =
|
|
31
|
+
const dockerCompose = `# Ports are published on 127.0.0.1 so this stack is reachable from this machine
|
|
32
|
+
# only. See the note in the full-stack compose for why that matters here.
|
|
32
33
|
services:
|
|
33
34
|
db:
|
|
34
35
|
image: ${POSTGRES_IMAGE}
|
|
35
36
|
container_name: seamless-db
|
|
36
37
|
ports:
|
|
37
|
-
- "5432:5432"
|
|
38
|
+
- "127.0.0.1:5432:5432"
|
|
38
39
|
environment:
|
|
39
40
|
POSTGRES_USER: myuser
|
|
40
41
|
POSTGRES_PASSWORD: mypassword
|
|
@@ -51,7 +52,7 @@ services:
|
|
|
51
52
|
image: ${SEAMLESS_AUTH_API_IMAGE}
|
|
52
53
|
container_name: seamless-auth
|
|
53
54
|
ports:
|
|
54
|
-
- "5312:5312"
|
|
55
|
+
- "127.0.0.1:5312:5312"
|
|
55
56
|
environment:
|
|
56
57
|
${envBlock}
|
|
57
58
|
depends_on:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/generators/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAI7B,MAAM,SAAS,GAAG,iDAAiD,CAAC;AAEpE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAY,EACZ,IAAiC,EACjC,QAAkC,EAAE,EACpC,YAAuB,KAAK;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/generators/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAI7B,MAAM,SAAS,GAAG,iDAAiD,CAAC;AAEpE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAY,EACZ,IAAiC,EACjC,QAAkC,EAAE,EACpC,YAAuB,KAAK,EAC5B,UAAmB;IAEnB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEzB,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,MAAM,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,IAAY,EACZ,QAAkC,EAAE,EACpC,YAAuB,KAAK,EAC5B,UAAmB;IAEnB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAE5D,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAE/E,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY;IACzC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAE3D,MAAM,GAAG,GAAG,MAAM,eAAe,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEvC,MAAM,aAAa,GAAG;;;;aAIX,cAAc;;;;;;;;;;;;;;;;;aAiBd,uBAAuB;;;;;EAKlC,QAAQ;;;;;;;CAOT,CAAC;IAEA,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,EACrC,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAC5B,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -13,17 +13,20 @@ export async function generateDockerCompose(root, options) {
|
|
|
13
13
|
return shared;
|
|
14
14
|
}
|
|
15
15
|
async function buildCompose(options, root) {
|
|
16
|
-
const { authMode, adminMode, oauth } = options;
|
|
17
|
-
const { service: authBlock, shared } = await authService(authMode, root, oauth, adminMode);
|
|
16
|
+
const { authMode, adminMode, oauth, ownerEmail } = options;
|
|
17
|
+
const { service: authBlock, shared } = await authService(authMode, root, oauth, adminMode, ownerEmail);
|
|
18
18
|
const includeAdminContainer = adminMode === "image" || adminMode === "source";
|
|
19
19
|
return {
|
|
20
|
-
compose:
|
|
20
|
+
compose: `# Ports are published on 127.0.0.1 so this stack is reachable from this machine
|
|
21
|
+
# only. The auth server is configured to return OTP codes in the response for
|
|
22
|
+
# local login, which would otherwise be an authentication bypass for anyone on
|
|
23
|
+
# the same network. Drop the 127.0.0.1 prefix only if you know you want that.
|
|
21
24
|
services:
|
|
22
25
|
db:
|
|
23
26
|
image: ${POSTGRES_IMAGE}
|
|
24
27
|
container_name: seamless-db
|
|
25
28
|
ports:
|
|
26
|
-
- "5432:5432"
|
|
29
|
+
- "127.0.0.1:5432:5432"
|
|
27
30
|
environment:
|
|
28
31
|
POSTGRES_USER: myuser
|
|
29
32
|
POSTGRES_PASSWORD: mypassword
|
|
@@ -50,7 +53,7 @@ volumes:
|
|
|
50
53
|
shared,
|
|
51
54
|
};
|
|
52
55
|
}
|
|
53
|
-
async function authService(mode, root, oauth = [], adminMode = "api") {
|
|
56
|
+
async function authService(mode, root, oauth = [], adminMode = "api", ownerEmail) {
|
|
54
57
|
if (mode === "local") {
|
|
55
58
|
// auth/.env was already written by generateAuthServer (with its secrets and any
|
|
56
59
|
// OAuth config). Read those values back rather than regenerating, which would mint
|
|
@@ -64,7 +67,7 @@ async function authService(mode, root, oauth = [], adminMode = "api") {
|
|
|
64
67
|
context: ./auth
|
|
65
68
|
dockerfile: Dockerfile.dev
|
|
66
69
|
ports:
|
|
67
|
-
- "5312:5312"
|
|
70
|
+
- "127.0.0.1:5312:5312"
|
|
68
71
|
env_file:
|
|
69
72
|
- ./auth/.env
|
|
70
73
|
environment:
|
|
@@ -80,7 +83,7 @@ async function authService(mode, root, oauth = [], adminMode = "api") {
|
|
|
80
83
|
shared,
|
|
81
84
|
};
|
|
82
85
|
}
|
|
83
|
-
return await authServiceDocker(oauth, adminMode);
|
|
86
|
+
return await authServiceDocker(oauth, adminMode, ownerEmail);
|
|
84
87
|
}
|
|
85
88
|
// The app API's CORS allowlist. The console is same-origin here in API-served
|
|
86
89
|
// mode, so 5174 only belongs when a standalone dashboard container runs there.
|
|
@@ -97,7 +100,7 @@ function apiService(shared, adminMode) {
|
|
|
97
100
|
container_name: api
|
|
98
101
|
build: ./api
|
|
99
102
|
ports:
|
|
100
|
-
- "3000:3000"
|
|
103
|
+
- "127.0.0.1:3000:3000"
|
|
101
104
|
env_file:
|
|
102
105
|
- ./api/.env
|
|
103
106
|
environment:
|
|
@@ -122,7 +125,7 @@ function webService() {
|
|
|
122
125
|
container_name: web
|
|
123
126
|
build: ./web
|
|
124
127
|
ports:
|
|
125
|
-
- "5173:80"
|
|
128
|
+
- "127.0.0.1:5173:80"
|
|
126
129
|
environment:
|
|
127
130
|
API_URL: http://localhost:3000/
|
|
128
131
|
volumes:
|
|
@@ -137,10 +140,10 @@ function webService() {
|
|
|
137
140
|
retries: 10
|
|
138
141
|
`;
|
|
139
142
|
}
|
|
140
|
-
async function authServiceDocker(oauth = [], adminMode = "api") {
|
|
143
|
+
async function authServiceDocker(oauth = [], adminMode = "api", ownerEmail) {
|
|
141
144
|
const raw = await fetchEnvExample();
|
|
142
145
|
const parsed = parseEnvString(raw);
|
|
143
|
-
const { env, shared } = buildAuthEnv(parsed, "docker", oauth, adminMode);
|
|
146
|
+
const { env, shared } = buildAuthEnv(parsed, "docker", oauth, adminMode, ownerEmail);
|
|
144
147
|
const envBlock = envToDockerBlock(env);
|
|
145
148
|
return {
|
|
146
149
|
service: `
|
|
@@ -148,7 +151,7 @@ async function authServiceDocker(oauth = [], adminMode = "api") {
|
|
|
148
151
|
image: ${SEAMLESS_AUTH_API_IMAGE}
|
|
149
152
|
container_name: seamless-auth
|
|
150
153
|
ports:
|
|
151
|
-
- "5312:5312"
|
|
154
|
+
- "127.0.0.1:5312:5312"
|
|
152
155
|
environment:
|
|
153
156
|
${envBlock}
|
|
154
157
|
depends_on:
|
|
@@ -165,7 +168,7 @@ function adminService(mode) {
|
|
|
165
168
|
container_name: admin
|
|
166
169
|
build: ./admin
|
|
167
170
|
ports:
|
|
168
|
-
- "5174:80"
|
|
171
|
+
- "127.0.0.1:5174:80"
|
|
169
172
|
environment:
|
|
170
173
|
API_URL: http://localhost:3000/
|
|
171
174
|
AUTH_MODE: server
|
|
@@ -181,7 +184,7 @@ function adminService(mode) {
|
|
|
181
184
|
image: ${SEAMLESS_AUTH_ADMIN_DASHBOARD_IMAGE}
|
|
182
185
|
container_name: admin
|
|
183
186
|
ports:
|
|
184
|
-
- "5174:80"
|
|
187
|
+
- "127.0.0.1:5174:80"
|
|
185
188
|
environment:
|
|
186
189
|
API_URL: http://localhost:3000/
|
|
187
190
|
depends_on:
|
|
@@ -200,12 +203,16 @@ function adminOrigins(adminMode) {
|
|
|
200
203
|
}
|
|
201
204
|
return web;
|
|
202
205
|
}
|
|
203
|
-
export function buildAuthEnv(env, mode, oauth = [], adminMode = "api") {
|
|
206
|
+
export function buildAuthEnv(env, mode, oauth = [], adminMode = "api", ownerEmail) {
|
|
204
207
|
const apiToken = generateSecret(32);
|
|
205
|
-
const bootstrapSecret = generateSecret(32);
|
|
206
208
|
const kid = "dev-main";
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
// The auth server grants the admin role at signup to an address listed here,
|
|
210
|
+
// so registering in the scaffolded app produces a working /console admin with
|
|
211
|
+
// no separate promotion step. Signup-time only: setting this after an account
|
|
212
|
+
// already exists promotes nobody.
|
|
213
|
+
if (ownerEmail) {
|
|
214
|
+
env.OWNER_EMAIL = ownerEmail;
|
|
215
|
+
}
|
|
209
216
|
env.PORT = "5312";
|
|
210
217
|
env.NODE_ENV = "development";
|
|
211
218
|
env.AUTH_MODE = "server";
|
|
@@ -244,7 +251,6 @@ export function buildAuthEnv(env, mode, oauth = [], adminMode = "api") {
|
|
|
244
251
|
shared: {
|
|
245
252
|
apiToken,
|
|
246
253
|
kid,
|
|
247
|
-
bootstrapSecret,
|
|
248
254
|
},
|
|
249
255
|
};
|
|
250
256
|
}
|
|
@@ -282,7 +288,7 @@ export function buildJWKSConfig() {
|
|
|
282
288
|
}, null, 2),
|
|
283
289
|
};
|
|
284
290
|
}
|
|
285
|
-
export async function configureAuthLocalEnv(root, oauth = [], adminMode = "api") {
|
|
291
|
+
export async function configureAuthLocalEnv(root, oauth = [], adminMode = "api", ownerEmail) {
|
|
286
292
|
const authDir = path.join(root, "auth");
|
|
287
293
|
const envExamplePath = path.join(authDir, ".env.example");
|
|
288
294
|
const envPath = path.join(authDir, ".env");
|
|
@@ -291,7 +297,7 @@ export async function configureAuthLocalEnv(root, oauth = [], adminMode = "api")
|
|
|
291
297
|
}
|
|
292
298
|
const raw = fs.readFileSync(envExamplePath, "utf-8");
|
|
293
299
|
const parsed = parseEnvString(raw);
|
|
294
|
-
const { env, shared } = buildAuthEnv(parsed, "local", oauth, adminMode);
|
|
300
|
+
const { env, shared } = buildAuthEnv(parsed, "local", oauth, adminMode, ownerEmail);
|
|
295
301
|
writeEnvFile(envPath, env);
|
|
296
302
|
return shared;
|
|
297
303
|
}
|