@capuchoo/cli 0.8.0 → 0.9.1
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 +211 -23
- package/dist/cli/members.d.ts +23 -0
- package/dist/cli/members.d.ts.map +1 -0
- package/dist/cli/members.js +38 -0
- package/dist/cli/members.js.map +1 -0
- package/dist/cli/onboarding.d.ts +41 -0
- package/dist/cli/onboarding.d.ts.map +1 -0
- package/dist/cli/onboarding.js +94 -0
- package/dist/cli/onboarding.js.map +1 -0
- package/dist/cli/team.d.ts +16 -0
- package/dist/cli/team.d.ts.map +1 -0
- package/dist/cli/team.js +32 -0
- package/dist/cli/team.js.map +1 -0
- package/dist/commands/app/grant.d.ts +11 -0
- package/dist/commands/app/grant.d.ts.map +1 -0
- package/dist/commands/app/grant.js +31 -0
- package/dist/commands/app/grant.js.map +1 -0
- package/dist/commands/app/revoke.d.ts +13 -0
- package/dist/commands/app/revoke.d.ts.map +1 -0
- package/dist/commands/app/revoke.js +40 -0
- package/dist/commands/app/revoke.js.map +1 -0
- package/dist/commands/app/roles.d.ts +7 -0
- package/dist/commands/app/roles.d.ts.map +1 -0
- package/dist/commands/app/roles.js +30 -0
- package/dist/commands/app/roles.js.map +1 -0
- package/dist/commands/auth/issue.d.ts +12 -0
- package/dist/commands/auth/issue.d.ts.map +1 -0
- package/dist/commands/auth/issue.js +52 -0
- package/dist/commands/auth/issue.js.map +1 -0
- package/dist/commands/auth/keys.d.ts +7 -0
- package/dist/commands/auth/keys.d.ts.map +1 -0
- package/dist/commands/auth/keys.js +39 -0
- package/dist/commands/auth/keys.js.map +1 -0
- package/dist/commands/auth/login.d.ts +20 -0
- package/dist/commands/auth/login.d.ts.map +1 -1
- package/dist/commands/auth/login.js +90 -11
- package/dist/commands/auth/login.js.map +1 -1
- package/dist/commands/auth/revoke.d.ts +13 -0
- package/dist/commands/auth/revoke.d.ts.map +1 -0
- package/dist/commands/auth/revoke.js +48 -0
- package/dist/commands/auth/revoke.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +87 -12
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/menu.d.ts +3 -0
- package/dist/commands/menu.d.ts.map +1 -1
- package/dist/commands/menu.js +70 -15
- package/dist/commands/menu.js.map +1 -1
- package/dist/commands/org/invite.d.ts +14 -0
- package/dist/commands/org/invite.d.ts.map +1 -0
- package/dist/commands/org/invite.js +52 -0
- package/dist/commands/org/invite.js.map +1 -0
- package/dist/commands/org/members.d.ts +10 -0
- package/dist/commands/org/members.d.ts.map +1 -0
- package/dist/commands/org/members.js +49 -0
- package/dist/commands/org/members.js.map +1 -0
- package/dist/pipeline/app-identity.d.ts +35 -0
- package/dist/pipeline/app-identity.d.ts.map +1 -0
- package/dist/pipeline/app-identity.js +109 -0
- package/dist/pipeline/app-identity.js.map +1 -0
- package/dist/pipeline/capacitor-support.d.ts +1 -1
- package/dist/pipeline/capacitor-support.js +1 -1
- package/dist/services/cloud.d.ts +69 -1
- package/dist/services/cloud.d.ts.map +1 -1
- package/dist/services/cloud.js +67 -1
- package/dist/services/cloud.js.map +1 -1
- package/dist/utils/http.d.ts +5 -0
- package/dist/utils/http.d.ts.map +1 -1
- package/dist/utils/http.js +13 -2
- package/dist/utils/http.js.map +1 -1
- package/oclif.manifest.json +292 -2
- package/package.json +5 -5
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class AppGrant extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
email: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
role: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=grant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../../src/commands/app/grant.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,OAAgB,WAAW,SAAqC;IAEhE,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,IAAI;;;MAOlB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB3B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Args } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { whileWaiting } from "../../cli/prompts.js";
|
|
5
|
+
import { APP_ROLES, requireLinkedApp } from "../../cli/team.js";
|
|
6
|
+
export default class AppGrant extends BaseCommand {
|
|
7
|
+
static description = "Give someone a role on this app";
|
|
8
|
+
static examples = [
|
|
9
|
+
"<%= config.bin %> app grant dev@company.com developer",
|
|
10
|
+
"<%= config.bin %> app grant qa@company.com tester",
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
email: Args.string({ description: "Account to grant", required: true }),
|
|
14
|
+
role: Args.string({
|
|
15
|
+
description: `One of ${APP_ROLES.join(", ")}`,
|
|
16
|
+
required: true,
|
|
17
|
+
options: [...APP_ROLES],
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
const { args } = await this.parse(AppGrant);
|
|
22
|
+
const { cloud, project } = requireLinkedApp(this);
|
|
23
|
+
await whileWaiting("Granting...", cloud.grantAppRole(project.cloudAppId, args.email.trim(), args.role));
|
|
24
|
+
const publishes = args.role === "admin" || args.role === "developer";
|
|
25
|
+
this.log("");
|
|
26
|
+
this.log(` ${chalk.green("Granted")} ${args.email} is now ${chalk.bold(args.role)}`);
|
|
27
|
+
this.log(chalk.dim(publishes ? " They can publish releases." : " They cannot publish releases."));
|
|
28
|
+
this.log("");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=grant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant.js","sourceRoot":"","sources":["../../../src/commands/app/grant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGhE,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,MAAM,CAAU,WAAW,GAAG,iCAAiC,CAAC;IAEhE,MAAM,CAAU,QAAQ,GAAG;QACzB,uDAAuD;QACvD,mDAAmD;KACpD,CAAC;IAEF,MAAM,CAAU,IAAI,GAAG;QACrB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,UAAU,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC7C,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC;SACxB,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,YAAY,CAChB,aAAa,EACb,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,IAAe,CAAC,CAChF,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;QAErE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtF,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAC1F,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class AppRevoke extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
email: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=revoke.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../../src/commands/app/revoke.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,WAAW,SAAuC;IAElE,OAAgB,QAAQ,WAAoD;IAE5E,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { resolveByEmail } from "../../cli/members.js";
|
|
5
|
+
import { confirm, isInteractive, whileWaiting } from "../../cli/prompts.js";
|
|
6
|
+
import { requireLinkedApp } from "../../cli/team.js";
|
|
7
|
+
export default class AppRevoke extends BaseCommand {
|
|
8
|
+
static description = "Remove someone's role on this app";
|
|
9
|
+
static examples = ["<%= config.bin %> app revoke dev@company.com"];
|
|
10
|
+
static args = {
|
|
11
|
+
email: Args.string({ description: "Account to revoke", required: true }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
yes: Flags.boolean({ char: "y", default: false, description: "Skip the confirmation" }),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { args, flags } = await this.parse(AppRevoke);
|
|
18
|
+
const { cloud, project } = requireLinkedApp(this);
|
|
19
|
+
const members = await whileWaiting("Reading permissions...", cloud.appPermissions(project.cloudAppId));
|
|
20
|
+
const found = resolveByEmail(members, args.email);
|
|
21
|
+
if (!found.ok)
|
|
22
|
+
this.error(found.problem);
|
|
23
|
+
if (!flags.yes) {
|
|
24
|
+
if (!isInteractive()) {
|
|
25
|
+
this.error(`Refusing to revoke ${args.email} unattended. Pass --yes.`);
|
|
26
|
+
}
|
|
27
|
+
const proceed = await confirm(`Revoke ${args.email} on ${project.appName}?`, {
|
|
28
|
+
default: false,
|
|
29
|
+
});
|
|
30
|
+
if (!proceed)
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
await whileWaiting("Revoking...", cloud.revokeAppRole(project.cloudAppId, found.userId));
|
|
34
|
+
this.log("");
|
|
35
|
+
this.log(` ${chalk.green("Revoked")} ${args.email}`);
|
|
36
|
+
this.log(chalk.dim(" Organisation owners and admins keep access - remove them from the org instead."));
|
|
37
|
+
this.log("");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=revoke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke.js","sourceRoot":"","sources":["../../../src/commands/app/revoke.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,MAAM,CAAU,WAAW,GAAG,mCAAmC,CAAC;IAElE,MAAM,CAAU,QAAQ,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAE5E,MAAM,CAAU,IAAI,GAAG;QACrB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KACzE,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;KACxF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,wBAAwB,EACxB,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACzC,CAAC;QAEF,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,KAAK,0BAA0B,CAAC,CAAC;YACzE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,IAAI,CAAC,KAAK,OAAO,OAAO,CAAC,OAAO,GAAG,EAAE;gBAC3E,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YACH,IAAI,CAAC,OAAO;gBAAE,OAAO;QACvB,CAAC;QAED,MAAM,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,MAAO,CAAC,CAAC,CAAC;QAE1F,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAC9F,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../../src/commands/app/roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,OAAgB,WAAW,SAAsC;IAEjE,OAAgB,QAAQ,WAAmC;IAErD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA8B3B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { membershipRows } from "../../cli/members.js";
|
|
4
|
+
import { whileWaiting } from "../../cli/prompts.js";
|
|
5
|
+
import { requireLinkedApp } from "../../cli/team.js";
|
|
6
|
+
export default class AppRoles extends BaseCommand {
|
|
7
|
+
static description = "Show who can do what on this app";
|
|
8
|
+
static examples = ["<%= config.bin %> app roles"];
|
|
9
|
+
async run() {
|
|
10
|
+
const { cloud, project } = requireLinkedApp(this);
|
|
11
|
+
const members = await whileWaiting("Reading permissions...", cloud.appPermissions(project.cloudAppId));
|
|
12
|
+
this.log("");
|
|
13
|
+
this.log(` ${chalk.bold(project.appName)} ${chalk.dim(`(${project.appId})`)}`);
|
|
14
|
+
this.log("");
|
|
15
|
+
if (members.length === 0) {
|
|
16
|
+
this.log(chalk.dim(" No direct grants. Organisation owners and admins still have access."));
|
|
17
|
+
this.log("");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const width = Math.max(...membershipRows(members).map((row) => row.email.length));
|
|
21
|
+
for (const row of membershipRows(members)) {
|
|
22
|
+
const canPublish = row.role === "admin" || row.role === "developer";
|
|
23
|
+
this.log(` ${row.email.padEnd(width)} ${canPublish ? chalk.green(row.role) : chalk.dim(row.role)}`);
|
|
24
|
+
}
|
|
25
|
+
this.log("");
|
|
26
|
+
this.log(chalk.dim(" Green roles may publish. Grant with: capuchoo app grant <email> <role>"));
|
|
27
|
+
this.log("");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=roles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../../../src/commands/app/roles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,MAAM,CAAU,WAAW,GAAG,kCAAkC,CAAC;IAEjE,MAAM,CAAU,QAAQ,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3D,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,wBAAwB,EACxB,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACzC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;QAChF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEb,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC,CAAC;YAC7F,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAClF,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC;YACpE,IAAI,CAAC,GAAG,CACN,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC5F,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC,CAAC;QAChG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class AuthIssue extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
role: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
"this-app": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=issue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/issue.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,WAAW,SAAmE;IAE9F,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;;MAUnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { APP_ROLE_ORDER, describeCap } from "@capuchoo/core";
|
|
2
|
+
import { Flags } from "@oclif/core";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { hostname } from "node:os";
|
|
5
|
+
import { BaseCommand } from "../../base-command.js";
|
|
6
|
+
import { whileWaiting } from "../../cli/prompts.js";
|
|
7
|
+
import { requireCloud } from "../../cli/team.js";
|
|
8
|
+
import { readProjectConfig } from "../../utils/config.js";
|
|
9
|
+
export default class AuthIssue extends BaseCommand {
|
|
10
|
+
static description = "Create an API key, optionally limited to one app and one role";
|
|
11
|
+
static examples = [
|
|
12
|
+
"<%= config.bin %> auth issue --name ci --role developer --this-app",
|
|
13
|
+
"<%= config.bin %> auth issue --name readonly --role viewer",
|
|
14
|
+
];
|
|
15
|
+
static flags = {
|
|
16
|
+
name: Flags.string({ description: "Label shown in capuchoo auth keys" }),
|
|
17
|
+
role: Flags.string({
|
|
18
|
+
description: `Ceiling on what the key may do: ${APP_ROLE_ORDER.join(", ")}`,
|
|
19
|
+
options: [...APP_ROLE_ORDER],
|
|
20
|
+
}),
|
|
21
|
+
"this-app": Flags.boolean({
|
|
22
|
+
default: false,
|
|
23
|
+
description: "Restrict the key to the app this directory is linked to",
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { flags } = await this.parse(AuthIssue);
|
|
28
|
+
const cloud = requireCloud(this);
|
|
29
|
+
let appId;
|
|
30
|
+
if (flags["this-app"]) {
|
|
31
|
+
const project = readProjectConfig(process.cwd());
|
|
32
|
+
if (!project) {
|
|
33
|
+
this.error("--this-app needs a linked directory. Run capuchoo init, or drop the flag.");
|
|
34
|
+
}
|
|
35
|
+
appId = project.cloudAppId;
|
|
36
|
+
}
|
|
37
|
+
const name = flags.name?.trim() || `capuchoo-cli ${hostname()}`;
|
|
38
|
+
const role = flags.role;
|
|
39
|
+
const { key } = await whileWaiting("Creating...", cloud.createApiKey({ name, appId, role }));
|
|
40
|
+
this.log("");
|
|
41
|
+
this.log(` ${chalk.bold(name)}`);
|
|
42
|
+
this.log(` scope ${appId ? chalk.yellow("this app only") : chalk.dim("all apps")}`);
|
|
43
|
+
this.log(` role ${role ? chalk.yellow(describeCap(role)) : chalk.dim(describeCap(null))}`);
|
|
44
|
+
this.log("");
|
|
45
|
+
// Shown once, because only its hash is stored.
|
|
46
|
+
this.log(` ${key}`);
|
|
47
|
+
this.log("");
|
|
48
|
+
this.log(chalk.yellow(" Copy it now - it is not stored and cannot be shown again."));
|
|
49
|
+
this.log("");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.js","sourceRoot":"","sources":["../../../src/commands/auth/issue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,MAAM,CAAU,WAAW,GAAG,+DAA+D,CAAC;IAE9F,MAAM,CAAU,QAAQ,GAAG;QACzB,oEAAoE;QACpE,4DAA4D;KAC7D,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;QACxE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,mCAAmC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC3E,OAAO,EAAE,CAAC,GAAG,cAAc,CAAC;SAC7B,CAAC;QACF,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;YACxB,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,yDAAyD;SACvE,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,KAAyB,CAAC;QAC9B,IAAI,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;YAC1F,CAAC;YACD,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;QAC7B,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,gBAAgB,QAAQ,EAAE,EAAE,CAAC;QAChE,MAAM,IAAI,GAAG,KAAK,CAAC,IAA2B,CAAC;QAE/C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE7F,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,GAAG,CACN,eAAe,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CACvF,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,+CAA+C;QAC/C,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,6DAA6D,CAAC,CAAC,CAAC;QACtF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/keys.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,OAAgB,WAAW,SAAuC;IAElE,OAAgB,QAAQ,WAAmC;IAErD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAsC3B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describeCap, isAppRole } from "@capuchoo/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { whileWaiting } from "../../cli/prompts.js";
|
|
5
|
+
import { requireCloud } from "../../cli/team.js";
|
|
6
|
+
import { resolveCredentials } from "../../utils/config.js";
|
|
7
|
+
export default class AuthKeys extends BaseCommand {
|
|
8
|
+
static description = "List the API keys on this account";
|
|
9
|
+
static examples = ["<%= config.bin %> auth keys"];
|
|
10
|
+
async run() {
|
|
11
|
+
const cloud = requireCloud(this);
|
|
12
|
+
const current = resolveCredentials();
|
|
13
|
+
const keys = await whileWaiting("Reading keys...", cloud.apiKeys());
|
|
14
|
+
this.log("");
|
|
15
|
+
if (keys.length === 0) {
|
|
16
|
+
this.log(chalk.dim(" No keys."));
|
|
17
|
+
this.log("");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (const key of keys) {
|
|
21
|
+
// A key is shown once, at creation, so the prefix is the only way to tell
|
|
22
|
+
// which stored credential a row corresponds to.
|
|
23
|
+
const mine = key.key_prefix ? current?.apiKey.startsWith(key.key_prefix) : false;
|
|
24
|
+
const scope = key.app_id ? chalk.yellow("one app") : chalk.dim("all apps");
|
|
25
|
+
this.log(` ${chalk.bold(key.name)} ${chalk.dim(key.key_prefix ?? "")}` +
|
|
26
|
+
`${mine ? chalk.green(" (this machine)") : ""}`);
|
|
27
|
+
const cap = isAppRole(key.role)
|
|
28
|
+
? chalk.yellow(describeCap(key.role))
|
|
29
|
+
: chalk.dim(describeCap(null));
|
|
30
|
+
this.log(` ${scope} ${cap}`);
|
|
31
|
+
this.log(` ${chalk.dim(`id ${key.id}`)}`);
|
|
32
|
+
}
|
|
33
|
+
this.log("");
|
|
34
|
+
this.log(chalk.dim(" Revoke one with: capuchoo auth revoke <id>"));
|
|
35
|
+
this.log(chalk.dim(" Issue a limited one with: capuchoo auth issue --role developer --this-app"));
|
|
36
|
+
this.log("");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/commands/auth/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,MAAM,CAAU,WAAW,GAAG,mCAAmC,CAAC;IAElE,MAAM,CAAU,QAAQ,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3D,KAAK,CAAC,GAAG;QACP,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;QAErC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,iBAAiB,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAEpE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEb,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,0EAA0E;YAC1E,gDAAgD;YAChD,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACjF,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAE3E,IAAI,CAAC,GAAG,CACN,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE;gBAC5D,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,CAAC;YACF,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC7B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,GAAG,CAAC,6EAA6E,CAAC,CACzF,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -15,5 +15,25 @@ export default class AuthLogin extends BaseCommand {
|
|
|
15
15
|
* whether a failed login ends the process or just ends the login step.
|
|
16
16
|
*/
|
|
17
17
|
static performLogin(flagEndpoint?: string, flagApiKey?: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Turns a sign-in failure into something actionable.
|
|
20
|
+
*
|
|
21
|
+
* There is deliberately no `capuchoo auth register`: confirming an email is a
|
|
22
|
+
* browser round-trip, so a CLI signup could only ever end with "now go and
|
|
23
|
+
* check your email". Accounts are created in the dashboard, and an unconfirmed
|
|
24
|
+
* one is the state most likely to bring someone here confused.
|
|
25
|
+
*/
|
|
26
|
+
static explainSignInFailure(error: unknown): string;
|
|
27
|
+
/**
|
|
28
|
+
* Gets an API key, by signing in or by being handed one.
|
|
29
|
+
*
|
|
30
|
+
* Signing in is the default because pasting a key could not be the first step:
|
|
31
|
+
* keys are made in the dashboard, and an app-scoped one cannot create apps -
|
|
32
|
+
* so a new user had no way to reach a working state from the terminal at all.
|
|
33
|
+
*
|
|
34
|
+
* The token from `/auth/login` is used once, to mint a key, and then dropped.
|
|
35
|
+
* A JWT expires; a key does not, so you sign in once per machine.
|
|
36
|
+
*/
|
|
37
|
+
private static obtainKey;
|
|
18
38
|
}
|
|
19
39
|
//# sourceMappingURL=login.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,WAAW,SAAmC;IAE9D,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;MAMnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAK1B;;;;;;OAMG;WACU,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCpF;;;;;;;OAOG;IACH,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAqBnD;;;;;;;;;OASG;mBACkB,SAAS;CAmE/B"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hostname } from "node:os";
|
|
2
|
+
import { askSecret, askText, isInteractive, selectOne } from "../../cli/prompts.js";
|
|
2
3
|
import { Flags } from "@oclif/core";
|
|
3
4
|
import chalk from "chalk";
|
|
4
5
|
import ora from "ora";
|
|
5
6
|
import { CloudClient } from "../../services/cloud.js";
|
|
7
|
+
import { TimeoutError } from "../../utils/http.js";
|
|
6
8
|
import { readGlobalConfig, updateGlobalConfig } from "../../utils/config.js";
|
|
7
9
|
import { BaseCommand } from "../../base-command.js";
|
|
8
10
|
const DEFAULT_ENDPOINT = "https://capuchoo-back.onrender.com";
|
|
9
11
|
export default class AuthLogin extends BaseCommand {
|
|
10
|
-
static description = "
|
|
12
|
+
static description = "Sign in to a Capuchoo backend";
|
|
11
13
|
static examples = [
|
|
12
14
|
"<%= config.bin %> auth login",
|
|
13
15
|
"<%= config.bin %> auth login --endpoint https://capucho.internal --api-key cap_...",
|
|
@@ -40,15 +42,7 @@ export default class AuthLogin extends BaseCommand {
|
|
|
40
42
|
})))
|
|
41
43
|
.trim()
|
|
42
44
|
.replace(/\/+$/, "");
|
|
43
|
-
|
|
44
|
-
if (!apiKey) {
|
|
45
|
-
process.stderr.write(chalk.dim(`\n Create a key under Settings > API Keys at ${endpoint}\n\n`));
|
|
46
|
-
// Only a length check. The previous version required the key to start with
|
|
47
|
-
// "cap_", which is a server-side format decision the CLI has no business
|
|
48
|
-
// enforcing - a rotated prefix would have locked users out.
|
|
49
|
-
apiKey = await askSecret("API key");
|
|
50
|
-
}
|
|
51
|
-
apiKey = apiKey.trim();
|
|
45
|
+
const apiKey = (flagApiKey ?? (await AuthLogin.obtainKey(endpoint))).trim();
|
|
52
46
|
const spinner = ora({ text: "Verifying", stream: process.stderr }).start();
|
|
53
47
|
const profile = await new CloudClient(endpoint, apiKey).whoami();
|
|
54
48
|
if (!profile) {
|
|
@@ -67,5 +61,90 @@ export default class AuthLogin extends BaseCommand {
|
|
|
67
61
|
authenticatedAt: new Date().toISOString(),
|
|
68
62
|
});
|
|
69
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Turns a sign-in failure into something actionable.
|
|
66
|
+
*
|
|
67
|
+
* There is deliberately no `capuchoo auth register`: confirming an email is a
|
|
68
|
+
* browser round-trip, so a CLI signup could only ever end with "now go and
|
|
69
|
+
* check your email". Accounts are created in the dashboard, and an unconfirmed
|
|
70
|
+
* one is the state most likely to bring someone here confused.
|
|
71
|
+
*/
|
|
72
|
+
static explainSignInFailure(error) {
|
|
73
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
74
|
+
if (/not confirmed/i.test(message)) {
|
|
75
|
+
return ("That account exists but its email has not been confirmed yet. Open the " +
|
|
76
|
+
"link in the sign-up email, then run this again.");
|
|
77
|
+
}
|
|
78
|
+
if (/invalid login credentials/i.test(message)) {
|
|
79
|
+
return ("That email and password were not accepted. If you have not signed up yet, " +
|
|
80
|
+
"create the account in the dashboard first - there is no signup here, " +
|
|
81
|
+
"because confirming an email needs a browser.");
|
|
82
|
+
}
|
|
83
|
+
return message;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Gets an API key, by signing in or by being handed one.
|
|
87
|
+
*
|
|
88
|
+
* Signing in is the default because pasting a key could not be the first step:
|
|
89
|
+
* keys are made in the dashboard, and an app-scoped one cannot create apps -
|
|
90
|
+
* so a new user had no way to reach a working state from the terminal at all.
|
|
91
|
+
*
|
|
92
|
+
* The token from `/auth/login` is used once, to mint a key, and then dropped.
|
|
93
|
+
* A JWT expires; a key does not, so you sign in once per machine.
|
|
94
|
+
*/
|
|
95
|
+
static async obtainKey(endpoint) {
|
|
96
|
+
if (!isInteractive()) {
|
|
97
|
+
throw new Error("Not a terminal, so there is nobody to ask. Pass --api-key, or set " +
|
|
98
|
+
"CAPUCHOO_ENDPOINT and CAPUCHOO_API_KEY.");
|
|
99
|
+
}
|
|
100
|
+
const method = await selectOne("How would you like to sign in?", [
|
|
101
|
+
{ value: "password", label: "Email and password", hint: "creates a key for this machine" },
|
|
102
|
+
{ value: "key", label: "Paste an API key", hint: "from the dashboard" },
|
|
103
|
+
], "--api-key");
|
|
104
|
+
if (method === "key") {
|
|
105
|
+
process.stderr.write(chalk.dim(`\n Create a key under Settings > API Keys at ${endpoint}\n\n`));
|
|
106
|
+
// Length only. Requiring a "cap_" prefix is a server-side format decision
|
|
107
|
+
// the CLI has no business enforcing.
|
|
108
|
+
return askSecret("API key");
|
|
109
|
+
}
|
|
110
|
+
const email = await askText("Email", { flag: "--api-key" });
|
|
111
|
+
// Never a flag: a password in argv is a password in shell history and CI logs.
|
|
112
|
+
const password = await askSecret("Password");
|
|
113
|
+
const spinner = ora({ text: "Signing in", stream: process.stderr }).start();
|
|
114
|
+
let session;
|
|
115
|
+
try {
|
|
116
|
+
session = await CloudClient.login(endpoint, email.trim(), password);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
// A sign-in is usually the first request of a session, so it meets the
|
|
120
|
+
// backend at its coldest - and a host that sleeps when idle can take
|
|
121
|
+
// longer than the default timeout to answer. The second attempt lands on
|
|
122
|
+
// a service that is now awake.
|
|
123
|
+
if (!(error instanceof TimeoutError)) {
|
|
124
|
+
spinner.fail("Sign-in failed");
|
|
125
|
+
throw new Error(AuthLogin.explainSignInFailure(error));
|
|
126
|
+
}
|
|
127
|
+
spinner.text = "The backend was asleep - waking it and retrying";
|
|
128
|
+
try {
|
|
129
|
+
session = await CloudClient.login(endpoint, email.trim(), password, 120_000);
|
|
130
|
+
}
|
|
131
|
+
catch (retried) {
|
|
132
|
+
spinner.fail("Sign-in failed");
|
|
133
|
+
throw new Error(AuthLogin.explainSignInFailure(retried));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
spinner.text = "Creating a key for this machine";
|
|
137
|
+
try {
|
|
138
|
+
const { key } = await new CloudClient(endpoint, session.token).createApiKey({
|
|
139
|
+
name: `capuchoo-cli ${hostname()}`,
|
|
140
|
+
});
|
|
141
|
+
spinner.succeed("Created a key for this machine");
|
|
142
|
+
return key;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
spinner.fail("Signed in, but could not create an API key");
|
|
146
|
+
throw new Error(error instanceof Error ? error.message : String(error));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
70
149
|
}
|
|
71
150
|
//# sourceMappingURL=login.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class AuthRevoke extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=revoke.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/revoke.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,WAAW,SAAuB;IAElD,OAAgB,QAAQ,WAA0C;IAElE,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuC3B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { confirm, isInteractive, whileWaiting } from "../../cli/prompts.js";
|
|
5
|
+
import { requireCloud } from "../../cli/team.js";
|
|
6
|
+
import { resolveCredentials } from "../../utils/config.js";
|
|
7
|
+
export default class AuthRevoke extends BaseCommand {
|
|
8
|
+
static description = "Revoke an API key";
|
|
9
|
+
static examples = ["<%= config.bin %> auth revoke <id>"];
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.string({ description: "Key id, from capuchoo auth keys", required: true }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
yes: Flags.boolean({ char: "y", default: false, description: "Skip the confirmation" }),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { args, flags } = await this.parse(AuthRevoke);
|
|
18
|
+
const cloud = requireCloud(this);
|
|
19
|
+
const current = resolveCredentials();
|
|
20
|
+
const keys = await whileWaiting("Reading keys...", cloud.apiKeys());
|
|
21
|
+
const key = keys.find((candidate) => candidate.id === args.id);
|
|
22
|
+
if (!key) {
|
|
23
|
+
this.error(`No key with id "${args.id}". Run ${chalk.cyan("capuchoo auth keys")} to see them.`);
|
|
24
|
+
}
|
|
25
|
+
// Revoking the key in use signs this machine out, which is worth saying
|
|
26
|
+
// before it happens rather than after.
|
|
27
|
+
const isCurrent = key.key_prefix ? current?.apiKey.startsWith(key.key_prefix) : false;
|
|
28
|
+
if (!flags.yes) {
|
|
29
|
+
if (!isInteractive()) {
|
|
30
|
+
this.error(`Refusing to revoke "${key.name}" unattended. Pass --yes.`);
|
|
31
|
+
}
|
|
32
|
+
if (isCurrent) {
|
|
33
|
+
this.log("");
|
|
34
|
+
this.log(chalk.yellow(" This is the key this machine uses. Revoking it signs you out here."));
|
|
35
|
+
}
|
|
36
|
+
const proceed = await confirm(`Revoke "${key.name}"?`, { default: false });
|
|
37
|
+
if (!proceed)
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
await whileWaiting("Revoking...", cloud.revokeApiKey(key.id));
|
|
41
|
+
this.log("");
|
|
42
|
+
this.log(` ${chalk.green("Revoked")} ${key.name}`);
|
|
43
|
+
if (isCurrent)
|
|
44
|
+
this.log(chalk.dim(" Sign in again with: capuchoo auth login"));
|
|
45
|
+
this.log("");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=revoke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke.js","sourceRoot":"","sources":["../../../src/commands/auth/revoke.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAgBjD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAAsE;IAEjG,OAAgB,QAAQ,WAAgC;IAElD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAgBjD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAAsE;IAEjG,OAAgB,QAAQ,WAAgC;IAElD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAiO1B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IA6D1B,qGAAqG;IACrG,OAAO,CAAC,mBAAmB;IA2C3B,8EAA8E;IAC9E,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,MAAM;CA0Bf"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -207,6 +207,7 @@ export default class Doctor extends BaseCommand {
|
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
209
|
findings.push(...this.checkRuntimeWiring(appDir));
|
|
210
|
+
findings.push(...this.checkReleaseSigning(appDir));
|
|
210
211
|
this.report(findings);
|
|
211
212
|
}
|
|
212
213
|
/**
|
|
@@ -264,7 +265,6 @@ export default class Doctor extends BaseCommand {
|
|
|
264
265
|
findings.push({ level: "ok", what: "Capacitor plugin config" });
|
|
265
266
|
}
|
|
266
267
|
}
|
|
267
|
-
findings.push(...this.checkReleaseSigning(appDir));
|
|
268
268
|
return findings;
|
|
269
269
|
}
|
|
270
270
|
/** Whether a release build could be signed. Never blocking: debug and unsigned are valid choices. */
|