apipay 0.1.0 → 0.2.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 +1 -1
- package/dist/commands/banks/add.d.ts +1 -1
- package/dist/commands/banks/add.d.ts.map +1 -1
- package/dist/commands/banks/add.js +43 -43
- package/dist/commands/banks/add.js.map +1 -1
- package/dist/commands/banks/list.d.ts +1 -1
- package/dist/commands/banks/list.d.ts.map +1 -1
- package/dist/commands/banks/list.js +19 -17
- package/dist/commands/banks/list.js.map +1 -1
- package/dist/commands/banks/remove.d.ts +1 -1
- package/dist/commands/banks/remove.d.ts.map +1 -1
- package/dist/commands/banks/remove.js +19 -19
- package/dist/commands/banks/remove.js.map +1 -1
- package/dist/commands/banks/toggle.d.ts +1 -1
- package/dist/commands/banks/toggle.d.ts.map +1 -1
- package/dist/commands/banks/toggle.js +12 -12
- package/dist/commands/banks/toggle.js.map +1 -1
- package/dist/commands/config/get.d.ts +1 -1
- package/dist/commands/config/get.d.ts.map +1 -1
- package/dist/commands/config/get.js +15 -12
- package/dist/commands/config/get.js.map +1 -1
- package/dist/commands/config/reset.d.ts +1 -1
- package/dist/commands/config/reset.d.ts.map +1 -1
- package/dist/commands/config/reset.js +12 -12
- package/dist/commands/config/reset.js.map +1 -1
- package/dist/commands/config/set.d.ts +1 -1
- package/dist/commands/config/set.d.ts.map +1 -1
- package/dist/commands/config/set.js +14 -11
- package/dist/commands/config/set.js.map +1 -1
- package/dist/commands/keys/create.d.ts +1 -1
- package/dist/commands/keys/create.d.ts.map +1 -1
- package/dist/commands/keys/create.js +38 -32
- package/dist/commands/keys/create.js.map +1 -1
- package/dist/commands/keys/list.d.ts +1 -1
- package/dist/commands/keys/list.d.ts.map +1 -1
- package/dist/commands/keys/list.js +15 -15
- package/dist/commands/keys/list.js.map +1 -1
- package/dist/commands/keys/revoke.d.ts +1 -1
- package/dist/commands/keys/revoke.d.ts.map +1 -1
- package/dist/commands/keys/revoke.js +25 -22
- package/dist/commands/keys/revoke.js.map +1 -1
- package/dist/commands/login.d.ts +2 -2
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +66 -55
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts +1 -1
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +12 -12
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/metrics/summary.d.ts +1 -1
- package/dist/commands/metrics/summary.d.ts.map +1 -1
- package/dist/commands/metrics/summary.js +17 -17
- package/dist/commands/metrics/summary.js.map +1 -1
- package/dist/commands/metrics/transactions.d.ts +1 -1
- package/dist/commands/metrics/transactions.d.ts.map +1 -1
- package/dist/commands/metrics/transactions.js +23 -20
- package/dist/commands/metrics/transactions.js.map +1 -1
- package/dist/commands/{init.d.ts → setup.d.ts} +4 -4
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +192 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +42 -38
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/webhooks/add.d.ts +1 -1
- package/dist/commands/webhooks/add.d.ts.map +1 -1
- package/dist/commands/webhooks/add.js +34 -32
- package/dist/commands/webhooks/add.js.map +1 -1
- package/dist/commands/webhooks/history.d.ts +1 -1
- package/dist/commands/webhooks/history.d.ts.map +1 -1
- package/dist/commands/webhooks/history.js +19 -17
- package/dist/commands/webhooks/history.js.map +1 -1
- package/dist/commands/webhooks/list.d.ts +1 -1
- package/dist/commands/webhooks/list.d.ts.map +1 -1
- package/dist/commands/webhooks/list.js +20 -16
- package/dist/commands/webhooks/list.js.map +1 -1
- package/dist/commands/webhooks/remove.d.ts +1 -1
- package/dist/commands/webhooks/remove.d.ts.map +1 -1
- package/dist/commands/webhooks/remove.js +14 -14
- package/dist/commands/webhooks/remove.js.map +1 -1
- package/dist/commands/webhooks/resend.d.ts +1 -1
- package/dist/commands/webhooks/resend.d.ts.map +1 -1
- package/dist/commands/webhooks/resend.js +20 -11
- package/dist/commands/webhooks/resend.js.map +1 -1
- package/dist/commands/webhooks/toggle.d.ts +1 -1
- package/dist/commands/webhooks/toggle.d.ts.map +1 -1
- package/dist/commands/webhooks/toggle.js +12 -12
- package/dist/commands/webhooks/toggle.js.map +1 -1
- package/dist/commands/webhooks/update.d.ts +1 -1
- package/dist/commands/webhooks/update.d.ts.map +1 -1
- package/dist/commands/webhooks/update.js +17 -17
- package/dist/commands/webhooks/update.js.map +1 -1
- package/dist/commands/whoami.d.ts +1 -1
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +18 -18
- package/dist/commands/whoami.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/api-client.d.ts +1 -1
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +39 -34
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/base-command.d.ts +3 -3
- package/dist/lib/base-command.d.ts.map +1 -1
- package/dist/lib/base-command.js +10 -10
- package/dist/lib/base-command.js.map +1 -1
- package/dist/lib/config.d.ts +2 -2
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +33 -34
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.js +11 -11
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/formatters.d.ts +2 -0
- package/dist/lib/formatters.d.ts.map +1 -1
- package/dist/lib/formatters.js +43 -37
- package/dist/lib/formatters.js.map +1 -1
- package/dist/lib/prompts.d.ts +1 -0
- package/dist/lib/prompts.d.ts.map +1 -1
- package/dist/lib/prompts.js +33 -18
- package/dist/lib/prompts.js.map +1 -1
- package/dist/lib/validators.d.ts +1 -0
- package/dist/lib/validators.d.ts.map +1 -1
- package/dist/lib/validators.js +49 -28
- package/dist/lib/validators.js.map +1 -1
- package/oclif.manifest.json +38 -38
- package/package.json +93 -82
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -109
- package/dist/commands/init.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set.js","sourceRoot":"","sources":["../../../src/commands/config/set.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"set.js","sourceRoot":"","sources":["../../../src/commands/config/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,WAAW,EAAC,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAC,OAAO,EAAC,MAAM,yBAAyB,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IACjD,MAAM,CAAU,WAAW,GAAG,+BAA+B,CAAC;IAE9D,MAAM,CAAU,IAAI,GAAG;QACtB,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,+BAA+B;YAC5C,QAAQ,EAAE,IAAI;SACd,CAAC;QACF,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAC,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;KACjE,CAAC;IAEF,MAAM,CAAU,QAAQ,GAAG;QAC1B,sEAAsE;KACtE,CAAC;IAEF,KAAK,CAAC,GAAG;QACR,MAAM,EAAC,IAAI,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE3C,MAAM,WAAW,GAAG,CAAC,YAAY,CAAC,CAAC;QACnC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,KAAK,CACT,uBAAuB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACtF,EAAC,IAAI,EAAE,CAAC,EAAC,CACT,CAAC;QACH,CAAC;QAED,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/create.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/create.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAK/D,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,oBAAoB;IAC3D,OAAgB,WAAW,SACuB;IAElD,OAAgB,QAAQ,WAAqC;IAEvD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuE1B"}
|
|
@@ -1,52 +1,58 @@
|
|
|
1
|
-
import chalk from
|
|
2
|
-
import { AuthenticatedCommand } from
|
|
3
|
-
import { setApiKey } from
|
|
4
|
-
import { success, warn
|
|
5
|
-
import { promptApiKeyName,
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { AuthenticatedCommand } from "../../lib/base-command.js";
|
|
3
|
+
import { setApiKey } from "../../lib/config.js";
|
|
4
|
+
import { info, kvLine, maskSecret, success, warn } from "../../lib/formatters.js";
|
|
5
|
+
import { promptApiKeyName, promptExistingKeyAction } from "../../lib/prompts.js";
|
|
6
6
|
export default class KeysCreate extends AuthenticatedCommand {
|
|
7
|
-
static description =
|
|
8
|
-
static examples = [
|
|
7
|
+
static description = "Generate a new API key for client integrations";
|
|
8
|
+
static examples = ["<%= config.bin %> keys:create"];
|
|
9
9
|
async run() {
|
|
10
10
|
// Check if user already has keys
|
|
11
|
-
this.spinner.start(
|
|
11
|
+
this.spinner.start("Checking existing keys...");
|
|
12
12
|
try {
|
|
13
|
-
const existing = await this.api.get(
|
|
13
|
+
const existing = await this.api.get("/client-auth/keys", "jwt");
|
|
14
14
|
const keys = existing?.data ?? existing;
|
|
15
15
|
if (Array.isArray(keys) && keys.length > 0) {
|
|
16
16
|
this.spinner.stop();
|
|
17
|
-
warn(
|
|
18
|
-
console.log(` Current key: ${chalk.cyan(keys[0].accessKey)}`);
|
|
19
|
-
console.log(
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
17
|
+
warn("You already have an API key. Only 1 key is allowed per account.");
|
|
18
|
+
console.log(` Current key: ${chalk.cyan(maskSecret(keys[0].accessKey))}`);
|
|
19
|
+
console.log("");
|
|
20
|
+
const action = await promptExistingKeyAction();
|
|
21
|
+
if (action === "keep") {
|
|
22
|
+
setApiKey({
|
|
23
|
+
id: keys[0].id,
|
|
24
|
+
accessKey: keys[0].accessKey,
|
|
25
|
+
secretKey: keys[0].secretKey ?? "",
|
|
26
|
+
name: keys[0].name ?? "",
|
|
27
|
+
});
|
|
28
|
+
info("Continuing with existing API key.");
|
|
22
29
|
return;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.
|
|
30
|
+
}
|
|
31
|
+
this.spinner.start("Revoking existing key...");
|
|
32
|
+
await this.api.delete(`/client-auth/keys/${keys[0].id}`, "jwt");
|
|
33
|
+
this.spinner.succeed("Existing key revoked");
|
|
26
34
|
}
|
|
27
35
|
else {
|
|
28
36
|
this.spinner.stop();
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
39
|
catch (error) {
|
|
32
|
-
this.spinner.fail(
|
|
40
|
+
this.spinner.fail("Failed to check existing keys");
|
|
33
41
|
this.handleError(error);
|
|
34
42
|
}
|
|
35
43
|
const name = await promptApiKeyName();
|
|
36
|
-
this.spinner.start(
|
|
44
|
+
this.spinner.start("Generating API key...");
|
|
37
45
|
try {
|
|
38
|
-
const data = await this.api.post(
|
|
46
|
+
const data = await this.api.post("/client-auth/keys", { name }, "jwt");
|
|
39
47
|
const key = data?.data ?? data;
|
|
40
|
-
this.spinner.succeed(
|
|
41
|
-
console.log(
|
|
42
|
-
console.log(chalk.bold(
|
|
43
|
-
console.log(chalk.gray(
|
|
44
|
-
kvLine(
|
|
45
|
-
kvLine(
|
|
46
|
-
kvLine(
|
|
47
|
-
console.log(
|
|
48
|
-
console.log(chalk.yellow.bold(' ⚠ Save your secret key now — it will not be shown again!'));
|
|
49
|
-
console.log('');
|
|
48
|
+
this.spinner.succeed("API key created!");
|
|
49
|
+
console.log("");
|
|
50
|
+
console.log(chalk.bold(" Your API Key"));
|
|
51
|
+
console.log(chalk.gray(" ────────────"));
|
|
52
|
+
kvLine("Name", key.name ?? name);
|
|
53
|
+
kvLine("Access Key", chalk.cyan(key.accessKey));
|
|
54
|
+
kvLine("Secret Key", chalk.yellow(key.secretKey));
|
|
55
|
+
console.log("");
|
|
50
56
|
// Store in config for CLI use
|
|
51
57
|
setApiKey({
|
|
52
58
|
id: key.id,
|
|
@@ -54,13 +60,13 @@ export default class KeysCreate extends AuthenticatedCommand {
|
|
|
54
60
|
secretKey: key.secretKey,
|
|
55
61
|
name: key.name ?? name,
|
|
56
62
|
});
|
|
57
|
-
success(
|
|
63
|
+
success("API key saved to CLI config.");
|
|
58
64
|
if (this.jsonOutput) {
|
|
59
65
|
this.outputJson(key);
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
catch (error) {
|
|
63
|
-
this.spinner.fail(
|
|
69
|
+
this.spinner.fail("Failed to create API key");
|
|
64
70
|
this.handleError(error);
|
|
65
71
|
}
|
|
66
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/keys/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/keys/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/list.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAQ/D,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,oBAAoB;IACzD,OAAgB,WAAW,SAAwB;IAEnD,OAAgB,QAAQ,WAAmC;IAErD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAqC1B"}
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import chalk from
|
|
2
|
-
import { AuthenticatedCommand } from
|
|
3
|
-
import { createTable, formatDate, statusBadge } from
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { AuthenticatedCommand } from "../../lib/base-command.js";
|
|
3
|
+
import { createTable, formatDate, maskSecret, statusBadge, } from "../../lib/formatters.js";
|
|
4
4
|
export default class KeysList extends AuthenticatedCommand {
|
|
5
|
-
static description =
|
|
6
|
-
static examples = [
|
|
5
|
+
static description = "List your API keys";
|
|
6
|
+
static examples = ["<%= config.bin %> keys:list"];
|
|
7
7
|
async run() {
|
|
8
|
-
this.spinner.start(
|
|
8
|
+
this.spinner.start("Fetching API keys...");
|
|
9
9
|
try {
|
|
10
|
-
const data = await this.api.get(
|
|
10
|
+
const data = await this.api.get("/client-auth/keys", "jwt");
|
|
11
11
|
const keys = data?.data ?? data;
|
|
12
12
|
this.spinner.stop();
|
|
13
13
|
if (!Array.isArray(keys) || keys.length === 0) {
|
|
14
|
-
this.log(`\n No API keys found. Run ${chalk.cyan(
|
|
14
|
+
this.log(`\n No API keys found. Run ${chalk.cyan("apipay keys:create")} to generate one.\n`);
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
console.log(
|
|
18
|
-
const table = createTable([
|
|
19
|
-
k.name ||
|
|
20
|
-
k.accessKey
|
|
21
|
-
statusBadge(k.isActive ?
|
|
17
|
+
console.log("");
|
|
18
|
+
const table = createTable(["Name", "Access Key", "Status", "Created"], keys.map((k) => [
|
|
19
|
+
k.name || "—",
|
|
20
|
+
k.accessKey ? maskSecret(k.accessKey) : "—",
|
|
21
|
+
statusBadge(k.isActive ? "ACTIVE" : "INACTIVE"),
|
|
22
22
|
formatDate(k.createdAt),
|
|
23
23
|
]));
|
|
24
24
|
console.log(table);
|
|
25
|
-
console.log(
|
|
25
|
+
console.log("");
|
|
26
26
|
if (this.jsonOutput) {
|
|
27
27
|
this.outputJson(keys);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
catch (error) {
|
|
31
|
-
this.spinner.fail(
|
|
31
|
+
this.spinner.fail("Failed to fetch API keys");
|
|
32
32
|
this.handleError(error);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/keys/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/keys/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACN,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,GACX,MAAM,yBAAyB,CAAC;AAEjC,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,oBAAoB;IACzD,MAAM,CAAU,WAAW,GAAG,oBAAoB,CAAC;IAEnD,MAAM,CAAU,QAAQ,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3D,KAAK,CAAC,GAAG;QACR,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAE3C,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC5D,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;YAEhC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAEpB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/C,IAAI,CAAC,GAAG,CACP,8BAA8B,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,CACnF,CAAC;gBACF,OAAO;YACR,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,MAAM,KAAK,GAAG,WAAW,CACxB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,CAAC,EAC3C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC;gBACpB,CAAC,CAAC,IAAI,IAAI,GAAG;gBACb,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG;gBAC3C,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;gBAC/C,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;aACvB,CAAC,CACF,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC9C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/revoke.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../../src/commands/keys/revoke.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAK/D,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,oBAAoB;IAC3D,OAAgB,WAAW,SAAuB;IAElD,OAAgB,IAAI;;MAKlB;IAEF,OAAgB,QAAQ,WAGtB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwD1B"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { Args } from
|
|
2
|
-
import chalk from
|
|
3
|
-
import { AuthenticatedCommand } from
|
|
4
|
-
import { clearApiKey, getApiKey } from
|
|
5
|
-
import { success } from
|
|
6
|
-
import { promptConfirm } from
|
|
1
|
+
import { Args } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { AuthenticatedCommand } from "../../lib/base-command.js";
|
|
4
|
+
import { clearApiKey, getApiKey } from "../../lib/config.js";
|
|
5
|
+
import { maskSecret, success } from "../../lib/formatters.js";
|
|
6
|
+
import { promptConfirm } from "../../lib/prompts.js";
|
|
7
7
|
export default class KeysRevoke extends AuthenticatedCommand {
|
|
8
|
-
static description =
|
|
8
|
+
static description = "Revoke an API key";
|
|
9
9
|
static args = {
|
|
10
|
-
id: Args.string({
|
|
10
|
+
id: Args.string({
|
|
11
|
+
description: "API key ID to revoke (defaults to current key)",
|
|
12
|
+
required: false,
|
|
13
|
+
}),
|
|
11
14
|
};
|
|
12
15
|
static examples = [
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
"<%= config.bin %> keys:revoke",
|
|
17
|
+
"<%= config.bin %> keys:revoke <key-id>",
|
|
15
18
|
];
|
|
16
19
|
async run() {
|
|
17
20
|
const { args } = await this.parse(KeysRevoke);
|
|
@@ -21,20 +24,20 @@ export default class KeysRevoke extends AuthenticatedCommand {
|
|
|
21
24
|
const stored = getApiKey();
|
|
22
25
|
if (stored?.id) {
|
|
23
26
|
keyId = stored.id;
|
|
24
|
-
this.log(`Revoking key: ${chalk.cyan(stored.accessKey)}`);
|
|
27
|
+
this.log(`Revoking key: ${chalk.cyan(maskSecret(stored.accessKey))}`);
|
|
25
28
|
}
|
|
26
29
|
else {
|
|
27
30
|
// Fetch from API
|
|
28
|
-
this.spinner.start(
|
|
31
|
+
this.spinner.start("Fetching keys...");
|
|
29
32
|
try {
|
|
30
|
-
const data = await this.api.get(
|
|
33
|
+
const data = await this.api.get("/client-auth/keys", "jwt");
|
|
31
34
|
const keys = data?.data ?? data;
|
|
32
35
|
this.spinner.stop();
|
|
33
36
|
if (!Array.isArray(keys) || keys.length === 0) {
|
|
34
|
-
this.error(
|
|
37
|
+
this.error("No API keys to revoke.", { exit: 1 });
|
|
35
38
|
}
|
|
36
39
|
keyId = keys[0].id;
|
|
37
|
-
this.log(`Revoking key: ${chalk.cyan(keys[0].accessKey)}`);
|
|
40
|
+
this.log(`Revoking key: ${chalk.cyan(maskSecret(keys[0].accessKey))}`);
|
|
38
41
|
}
|
|
39
42
|
catch (error) {
|
|
40
43
|
this.spinner.fail();
|
|
@@ -42,23 +45,23 @@ export default class KeysRevoke extends AuthenticatedCommand {
|
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
|
-
const confirmed = await promptConfirm(`${chalk.red(
|
|
48
|
+
const confirmed = await promptConfirm(`${chalk.red("This action is irreversible.")} Revoke this API key?`);
|
|
46
49
|
if (!confirmed) {
|
|
47
|
-
this.log(
|
|
50
|
+
this.log("Cancelled.");
|
|
48
51
|
return;
|
|
49
52
|
}
|
|
50
|
-
this.spinner.start(
|
|
53
|
+
this.spinner.start("Revoking API key...");
|
|
51
54
|
try {
|
|
52
|
-
await this.api.delete(`/client-auth/keys/${keyId}`,
|
|
55
|
+
await this.api.delete(`/client-auth/keys/${keyId}`, "jwt");
|
|
53
56
|
clearApiKey();
|
|
54
|
-
this.spinner.succeed(
|
|
55
|
-
success(
|
|
57
|
+
this.spinner.succeed("API key revoked");
|
|
58
|
+
success("Key has been permanently revoked.");
|
|
56
59
|
if (this.jsonOutput) {
|
|
57
60
|
this.outputJson({ success: true, id: keyId });
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
catch (error) {
|
|
61
|
-
this.spinner.fail(
|
|
64
|
+
this.spinner.fail("Failed to revoke API key");
|
|
62
65
|
this.handleError(error);
|
|
63
66
|
}
|
|
64
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revoke.js","sourceRoot":"","sources":["../../../src/commands/keys/revoke.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"revoke.js","sourceRoot":"","sources":["../../../src/commands/keys/revoke.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { BaseCommand } from
|
|
1
|
+
import { BaseCommand } from "../lib/base-command.js";
|
|
2
2
|
export default class Login extends BaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
6
|
email: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
7
|
password: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
|
|
8
|
+
"no-browser": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
9
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
11
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAC;AAUnD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAA8B;IAEzD,OAAgB,QAAQ,WAItB;IAEF,OAAgB,KAAK;;;;;;MAcnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBZ,kBAAkB;YA+GlB,iBAAiB;IA4C/B,OAAO,CAAC,KAAK;CAGb"}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { Flags } from
|
|
2
|
-
import chalk from
|
|
3
|
-
import open from
|
|
4
|
-
import { BaseCommand } from
|
|
5
|
-
import {
|
|
6
|
-
import { DASHBOARD_URL, MAGIC_LINK_POLL_INTERVAL_MS, MAGIC_LINK_TIMEOUT_MS } from
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import open from "open";
|
|
4
|
+
import { BaseCommand } from "../lib/base-command.js";
|
|
5
|
+
import { getAuth, isLoggedIn, setAuth } from "../lib/config.js";
|
|
6
|
+
import { DASHBOARD_URL, MAGIC_LINK_POLL_INTERVAL_MS, MAGIC_LINK_TIMEOUT_MS, } from "../lib/constants.js";
|
|
7
|
+
import { info, kvLine, success, warn } from "../lib/formatters.js";
|
|
8
|
+
import { promptConfirm, promptEmail } from "../lib/prompts.js";
|
|
9
9
|
export default class Login extends BaseCommand {
|
|
10
|
-
static description =
|
|
10
|
+
static description = "Authenticate with ApiPay";
|
|
11
11
|
static examples = [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
"<%= config.bin %> login",
|
|
13
|
+
"<%= config.bin %> login --email user@example.com",
|
|
14
|
+
"<%= config.bin %> login --email user@example.com --password mypass",
|
|
15
15
|
];
|
|
16
16
|
static flags = {
|
|
17
17
|
...BaseCommand.baseFlags,
|
|
18
18
|
email: Flags.string({
|
|
19
|
-
char:
|
|
20
|
-
description:
|
|
19
|
+
char: "e",
|
|
20
|
+
description: "Email address (skip interactive prompt)",
|
|
21
21
|
}),
|
|
22
22
|
password: Flags.string({
|
|
23
|
-
char:
|
|
24
|
-
description:
|
|
23
|
+
char: "p",
|
|
24
|
+
description: "Password for email+password login (CI/scripting)",
|
|
25
25
|
}),
|
|
26
|
-
|
|
27
|
-
description:
|
|
26
|
+
"no-browser": Flags.boolean({
|
|
27
|
+
description: "Don't open the browser for magic link",
|
|
28
28
|
default: false,
|
|
29
29
|
}),
|
|
30
30
|
};
|
|
@@ -34,63 +34,66 @@ export default class Login extends BaseCommand {
|
|
|
34
34
|
if (isLoggedIn()) {
|
|
35
35
|
const auth = getAuth();
|
|
36
36
|
warn(`Already logged in as ${chalk.bold(auth.email)}`);
|
|
37
|
-
const relogin = await promptConfirm(
|
|
37
|
+
const relogin = await promptConfirm("Login with a different account?");
|
|
38
38
|
if (!relogin)
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
const email = flags.email ?? (await promptEmail());
|
|
42
42
|
// Password flow (for CI/scripting)
|
|
43
43
|
if (flags.password) {
|
|
44
|
+
warn("Passing --password on the command line stores it in shell history and may be visible in process lists. Prefer the magic-link flow for interactive sessions.");
|
|
44
45
|
return this.loginWithPassword(email, flags.password);
|
|
45
46
|
}
|
|
46
47
|
// Magic link flow (default — best UX)
|
|
47
|
-
return this.loginWithMagicLink(email, flags[
|
|
48
|
+
return this.loginWithMagicLink(email, flags["no-browser"]);
|
|
48
49
|
}
|
|
49
50
|
async loginWithMagicLink(email, noBrowser) {
|
|
50
|
-
this.spinner.start(
|
|
51
|
+
this.spinner.start("Requesting magic link...");
|
|
51
52
|
let data;
|
|
52
53
|
try {
|
|
53
|
-
data = await this.api.post(
|
|
54
|
+
data = await this.api.post("/auth/magic-link/request", { email });
|
|
54
55
|
}
|
|
55
56
|
catch (error) {
|
|
56
|
-
this.spinner.fail(
|
|
57
|
+
this.spinner.fail("Failed to request magic link");
|
|
57
58
|
this.handleError(error);
|
|
58
59
|
}
|
|
59
60
|
const token = data?.data?.token ?? data?.token;
|
|
60
61
|
if (!token) {
|
|
61
|
-
this.spinner.fail(
|
|
62
|
-
this.error(
|
|
62
|
+
this.spinner.fail("Failed to get magic link token");
|
|
63
|
+
this.error("Unexpected response from server", { exit: 2 });
|
|
63
64
|
}
|
|
64
|
-
this.spinner.succeed(
|
|
65
|
+
this.spinner.succeed("Magic link requested!");
|
|
65
66
|
// Open browser
|
|
66
67
|
const verifyUrl = `${DASHBOARD_URL}/auth/verify?token=${token}`;
|
|
67
|
-
console.log(
|
|
68
|
+
console.log("");
|
|
68
69
|
info(`Open this URL to authenticate:`);
|
|
69
70
|
console.log(` ${chalk.underline.cyan(verifyUrl)}`);
|
|
70
|
-
console.log(
|
|
71
|
+
console.log("");
|
|
71
72
|
if (!noBrowser) {
|
|
72
73
|
try {
|
|
73
74
|
await open(verifyUrl);
|
|
74
|
-
info(
|
|
75
|
+
info("Browser opened automatically.");
|
|
75
76
|
}
|
|
76
77
|
catch {
|
|
77
|
-
warn(
|
|
78
|
+
warn("Could not open browser. Please open the URL manually.");
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
// Poll for verification
|
|
81
|
-
this.spinner.start(
|
|
82
|
+
this.spinner.start("Waiting for authentication...");
|
|
82
83
|
const startTime = Date.now();
|
|
83
84
|
while (Date.now() - startTime < MAGIC_LINK_TIMEOUT_MS) {
|
|
84
85
|
await this.sleep(MAGIC_LINK_POLL_INTERVAL_MS);
|
|
85
86
|
try {
|
|
86
87
|
const status = await this.api.get(`/auth/magic-link/status?token=${token}`);
|
|
87
88
|
const st = status?.data?.status ?? status?.status;
|
|
88
|
-
if (st ===
|
|
89
|
+
if (st === "verified") {
|
|
89
90
|
// Token has been consumed — now exchange for auth tokens
|
|
90
|
-
// The verify endpoint was already called by the browser;
|
|
91
|
+
// The verify endpoint was already called by the browser;
|
|
91
92
|
// we need to call it ourselves too to get the tokens for CLI
|
|
92
93
|
try {
|
|
93
|
-
const authResult = await this.api.post(
|
|
94
|
+
const authResult = await this.api.post("/auth/magic-link/verify", {
|
|
95
|
+
token,
|
|
96
|
+
});
|
|
94
97
|
const result = authResult?.data ?? authResult;
|
|
95
98
|
const user = result?.user;
|
|
96
99
|
const tokens = result?.tokens;
|
|
@@ -100,10 +103,10 @@ export default class Login extends BaseCommand {
|
|
|
100
103
|
refreshToken: tokens.refreshToken,
|
|
101
104
|
expiresAt: Date.now() + (tokens.expiresIn ?? 900) * 1000,
|
|
102
105
|
email: user?.email ?? email,
|
|
103
|
-
userId: user?.id ??
|
|
106
|
+
userId: user?.id ?? "",
|
|
104
107
|
});
|
|
105
|
-
this.spinner.succeed(
|
|
106
|
-
console.log(
|
|
108
|
+
this.spinner.succeed("Authenticated!");
|
|
109
|
+
console.log("");
|
|
107
110
|
success(`Logged in as ${chalk.bold(user?.email ?? email)}`);
|
|
108
111
|
if (this.jsonOutput) {
|
|
109
112
|
this.outputJson({ email: user?.email, userId: user?.id });
|
|
@@ -115,52 +118,60 @@ export default class Login extends BaseCommand {
|
|
|
115
118
|
// Token already consumed by browser — that's expected.
|
|
116
119
|
// In this case, the CLI should have its own token.
|
|
117
120
|
// We'll try the password fallback or re-request.
|
|
118
|
-
this.spinner.fail(
|
|
119
|
-
info(`Please run ${chalk.cyan(
|
|
121
|
+
this.spinner.fail("Magic link was verified in browser but could not retrieve tokens for CLI.");
|
|
122
|
+
info(`Please run ${chalk.cyan("apipay login --email " + email + " --password <password>")} instead.`);
|
|
120
123
|
return;
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
|
-
if (st ===
|
|
124
|
-
this.spinner.fail(
|
|
125
|
-
this.error(
|
|
126
|
+
if (st === "expired") {
|
|
127
|
+
this.spinner.fail("Magic link expired");
|
|
128
|
+
this.error("The magic link has expired. Please try again.", {
|
|
129
|
+
exit: 1,
|
|
130
|
+
});
|
|
126
131
|
}
|
|
127
132
|
}
|
|
128
133
|
catch {
|
|
129
134
|
// Network error during poll — continue
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
|
-
this.spinner.fail(
|
|
133
|
-
this.error(
|
|
137
|
+
this.spinner.fail("Authentication timed out");
|
|
138
|
+
this.error("Timed out waiting for authentication. Please try again.", {
|
|
139
|
+
exit: 1,
|
|
140
|
+
});
|
|
134
141
|
}
|
|
135
142
|
async loginWithPassword(email, password) {
|
|
136
|
-
this.spinner.start(
|
|
143
|
+
this.spinner.start("Logging in...");
|
|
137
144
|
try {
|
|
138
|
-
const data = await this.api.post(
|
|
145
|
+
const data = await this.api.post("/auth/login", { email, password });
|
|
139
146
|
const result = data?.data ?? data;
|
|
140
147
|
const user = result?.user;
|
|
141
148
|
const tokens = result?.tokens;
|
|
142
149
|
if (!tokens?.accessToken) {
|
|
143
|
-
this.spinner.fail(
|
|
144
|
-
this.error(
|
|
150
|
+
this.spinner.fail("Login failed");
|
|
151
|
+
this.error("Unexpected response from server", { exit: 2 });
|
|
145
152
|
}
|
|
146
153
|
setAuth({
|
|
147
154
|
accessToken: tokens.accessToken,
|
|
148
155
|
refreshToken: tokens.refreshToken,
|
|
149
156
|
expiresAt: Date.now() + (tokens.expiresIn ?? 900) * 1000,
|
|
150
157
|
email: user?.email ?? email,
|
|
151
|
-
userId: user?.id ??
|
|
158
|
+
userId: user?.id ?? "",
|
|
152
159
|
});
|
|
153
|
-
this.spinner.succeed(
|
|
154
|
-
console.log(
|
|
160
|
+
this.spinner.succeed("Authenticated!");
|
|
161
|
+
console.log("");
|
|
155
162
|
success(`Logged in as ${chalk.bold(user?.email ?? email)}`);
|
|
156
|
-
kvLine(
|
|
157
|
-
kvLine(
|
|
163
|
+
kvLine("User ID", user?.id ?? "");
|
|
164
|
+
kvLine("Role", user?.role ?? "USER");
|
|
158
165
|
if (this.jsonOutput) {
|
|
159
|
-
this.outputJson({
|
|
166
|
+
this.outputJson({
|
|
167
|
+
email: user?.email,
|
|
168
|
+
userId: user?.id,
|
|
169
|
+
role: user?.role,
|
|
170
|
+
});
|
|
160
171
|
}
|
|
161
172
|
}
|
|
162
173
|
catch (error) {
|
|
163
|
-
this.spinner.fail(
|
|
174
|
+
this.spinner.fail("Login failed");
|
|
164
175
|
this.handleError(error);
|
|
165
176
|
}
|
|
166
177
|
}
|