@access-tokens/cli 1.0.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.
Files changed (71) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +412 -0
  3. package/dist/cli.d.ts +9 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +141 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/generate.d.ts +9 -0
  8. package/dist/commands/generate.d.ts.map +1 -0
  9. package/dist/commands/generate.js +33 -0
  10. package/dist/commands/generate.js.map +1 -0
  11. package/dist/commands/issue.d.ts +16 -0
  12. package/dist/commands/issue.d.ts.map +1 -0
  13. package/dist/commands/issue.js +36 -0
  14. package/dist/commands/issue.js.map +1 -0
  15. package/dist/commands/list.d.ts +16 -0
  16. package/dist/commands/list.d.ts.map +1 -0
  17. package/dist/commands/list.js +53 -0
  18. package/dist/commands/list.js.map +1 -0
  19. package/dist/commands/register.d.ts +18 -0
  20. package/dist/commands/register.d.ts.map +1 -0
  21. package/dist/commands/register.js +33 -0
  22. package/dist/commands/register.js.map +1 -0
  23. package/dist/commands/restore.d.ts +13 -0
  24. package/dist/commands/restore.d.ts.map +1 -0
  25. package/dist/commands/restore.js +16 -0
  26. package/dist/commands/restore.js.map +1 -0
  27. package/dist/commands/revoke.d.ts +14 -0
  28. package/dist/commands/revoke.d.ts.map +1 -0
  29. package/dist/commands/revoke.js +20 -0
  30. package/dist/commands/revoke.js.map +1 -0
  31. package/dist/commands/sync.d.ts +14 -0
  32. package/dist/commands/sync.d.ts.map +1 -0
  33. package/dist/commands/sync.js +197 -0
  34. package/dist/commands/sync.js.map +1 -0
  35. package/dist/commands/update.d.ts +17 -0
  36. package/dist/commands/update.d.ts.map +1 -0
  37. package/dist/commands/update.js +33 -0
  38. package/dist/commands/update.js.map +1 -0
  39. package/dist/config/loader.d.ts +17 -0
  40. package/dist/config/loader.d.ts.map +1 -0
  41. package/dist/config/loader.js +138 -0
  42. package/dist/config/loader.js.map +1 -0
  43. package/dist/config/schemas.d.ts +52 -0
  44. package/dist/config/schemas.d.ts.map +1 -0
  45. package/dist/config/schemas.js +67 -0
  46. package/dist/config/schemas.js.map +1 -0
  47. package/dist/main.d.ts +3 -0
  48. package/dist/main.d.ts.map +1 -0
  49. package/dist/main.js +18 -0
  50. package/dist/main.js.map +1 -0
  51. package/dist/utils/client-factory.d.ts +4 -0
  52. package/dist/utils/client-factory.d.ts.map +1 -0
  53. package/dist/utils/client-factory.js +13 -0
  54. package/dist/utils/client-factory.js.map +1 -0
  55. package/dist/utils/date-parser.d.ts +3 -0
  56. package/dist/utils/date-parser.d.ts.map +1 -0
  57. package/dist/utils/date-parser.js +21 -0
  58. package/dist/utils/date-parser.js.map +1 -0
  59. package/dist/utils/diff.d.ts +17 -0
  60. package/dist/utils/diff.d.ts.map +1 -0
  61. package/dist/utils/diff.js +66 -0
  62. package/dist/utils/diff.js.map +1 -0
  63. package/dist/utils/logger.d.ts +17 -0
  64. package/dist/utils/logger.d.ts.map +1 -0
  65. package/dist/utils/logger.js +62 -0
  66. package/dist/utils/logger.js.map +1 -0
  67. package/dist/utils/permissions.d.ts +2 -0
  68. package/dist/utils/permissions.d.ts.map +1 -0
  69. package/dist/utils/permissions.js +55 -0
  70. package/dist/utils/permissions.js.map +1 -0
  71. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2025, Loan Crate, Inc.
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,412 @@
1
+ # @access-tokens/cli
2
+
3
+ [![npm](https://img.shields.io/npm/v/@access-tokens/cli)](https://www.npmjs.com/package/@access-tokens/cli)
4
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
5
+
6
+ Command-line interface for managing Personal Access Tokens (PATs).
7
+
8
+ ## Features
9
+
10
+ - **Token Management**: Issue, list, update, revoke, and restore tokens
11
+ - **Configuration**: Named endpoints for easy multi-environment management
12
+ - **Bulk Operations**: Sync tokens across environments from YAML config
13
+ - **Local Generation**: Generate tokens without server connection
14
+ - **Flexible Output**: JSON or human-readable output formats
15
+ - **Secure Credentials**: Config file permission validation
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install -g @access-tokens/cli
21
+ ```
22
+
23
+ Or use with npx (no installation):
24
+
25
+ ```bash
26
+ npx @access-tokens/cli --help
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ### Issue a Token
32
+
33
+ ```bash
34
+ access-tokens issue \
35
+ --url https://api.example.com \
36
+ --admin-token <your-admin-token> \
37
+ --owner user@example.com \
38
+ --admin
39
+ ```
40
+
41
+ ### List Tokens
42
+
43
+ ```bash
44
+ access-tokens list \
45
+ --url https://api.example.com \
46
+ --admin-token <your-admin-token>
47
+ ```
48
+
49
+ ### Using Named Endpoints
50
+
51
+ Create a config file at `~/.access-tokens-cli/config.yaml`:
52
+
53
+ ```yaml
54
+ endpoints:
55
+ prod:
56
+ url: https://api.example.com
57
+ adminToken: pat_prod_admin_token_here
58
+ staging:
59
+ url: https://staging.example.com
60
+ adminToken: pat_staging_admin_token_here
61
+ ```
62
+
63
+ Then use the endpoint name:
64
+
65
+ ```bash
66
+ access-tokens list --endpoint prod
67
+ access-tokens issue --endpoint staging --owner user@example.com
68
+ ```
69
+
70
+ ## Commands
71
+
72
+ ### `generate`
73
+
74
+ Generate a token locally without storing in database. Useful for pre-generating tokens.
75
+
76
+ ```bash
77
+ access-tokens generate
78
+ access-tokens generate --token-prefix myapp_
79
+ access-tokens generate --token-id specific-id-123
80
+ access-tokens generate --json
81
+ ```
82
+
83
+ **Options:**
84
+
85
+ - `--token-prefix <prefix>` - Token prefix (default: `pat_`)
86
+ - `--token-id <id>` - Use specific token ID
87
+ - `--json` - Output as JSON
88
+ - `--verbose` - Verbose output
89
+ - `--quiet` - Minimal output
90
+
91
+ **Output:**
92
+
93
+ ```
94
+ Token: pat_9Xj2kLm5nPqRs7tUv.a8b9c0d1e2f3g4h5i6j7k8l9m0n1o2p3q4r5s6t7u8v9w0x1y2z3
95
+ Token ID: 9Xj2kLm5nPqRs7tUv
96
+ Secret PHC: $scrypt$n=16384,r=8,p=1$...
97
+ ```
98
+
99
+ ### `list`
100
+
101
+ List all tokens.
102
+
103
+ ```bash
104
+ access-tokens list --endpoint prod
105
+ access-tokens list --url https://api.example.com --admin-token <token>
106
+ access-tokens list --endpoint prod --include-revoked --include-expired
107
+ access-tokens list --endpoint prod --json
108
+ ```
109
+
110
+ **Options:**
111
+
112
+ - `--endpoint <name>` - Named endpoint from config
113
+ - `--url <url>` - Direct endpoint URL
114
+ - `--admin-token <token>` - Admin token (required with --url)
115
+ - `--auth-path <path>` - Auth path (default: /auth)
116
+ - `--admin-path <path>` - Admin path (default: /admin)
117
+ - `--config-dir <path>` - Config directory (default: ~/.access-tokens-cli)
118
+ - `--include-revoked` - Include revoked tokens
119
+ - `--include-expired` - Include expired tokens
120
+ - `--include-secret-phc` - Include secret PHC hashes
121
+ - `--json` - Output as JSON
122
+ - `--verbose` - Verbose output
123
+ - `--quiet` - Minimal output
124
+
125
+ ### `issue`
126
+
127
+ Issue a new token.
128
+
129
+ ```bash
130
+ access-tokens issue \
131
+ --endpoint prod \
132
+ --owner user@example.com \
133
+ --admin
134
+
135
+ access-tokens issue \
136
+ --url https://api.example.com \
137
+ --admin-token <token> \
138
+ --owner user@example.com \
139
+ --expires-at 2025-12-31
140
+ ```
141
+
142
+ **Options:**
143
+
144
+ - `--endpoint <name>` - Named endpoint from config
145
+ - `--url <url>` - Direct endpoint URL
146
+ - `--admin-token <token>` - Admin token (required with --url)
147
+ - `--auth-path <path>` - Auth path (default: /auth)
148
+ - `--admin-path <path>` - Admin path (default: /admin)
149
+ - `--config-dir <path>` - Config directory (default: ~/.access-tokens-cli)
150
+ - `--owner <email>` - Token owner (required)
151
+ - `--admin` - Make token an admin token
152
+ - `--expires-at <date>` - Expiration date (ISO 8601 or Unix timestamp)
153
+ - `--json` - Output as JSON
154
+ - `--verbose` - Verbose output
155
+ - `--quiet` - Minimal output
156
+
157
+ **Date Formats:**
158
+
159
+ - ISO 8601: `2025-12-31`, `2025-12-31T23:59:59Z`
160
+ - Unix timestamp: `1735689599`
161
+
162
+ ### `register`
163
+
164
+ Register a pre-generated token (from `generate` command).
165
+
166
+ ```bash
167
+ access-tokens register \
168
+ --endpoint prod \
169
+ --token-id 9Xj2kLm5nPqRs7tUv \
170
+ --secret-phc '$scrypt$n=16384,r=8,p=1$...' \
171
+ --owner user@example.com
172
+ ```
173
+
174
+ **Options:**
175
+
176
+ - `--endpoint <name>` - Named endpoint from config
177
+ - `--url <url>` - Direct endpoint URL
178
+ - `--admin-token <token>` - Admin token (required with --url)
179
+ - `--auth-path <path>` - Auth path (default: /auth)
180
+ - `--admin-path <path>` - Admin path (default: /admin)
181
+ - `--config-dir <path>` - Config directory (default: ~/.access-tokens-cli)
182
+ - `--token-id <id>` - Pre-generated token ID (required)
183
+ - `--secret-phc <phc>` - Secret PHC hash (required)
184
+ - `--owner <email>` - Token owner (required)
185
+ - `--admin` - Make token an admin token
186
+ - `--expires-at <date>` - Expiration date
187
+ - `--json` - Output as JSON
188
+ - `--verbose` - Verbose output
189
+ - `--quiet` - Minimal output
190
+
191
+ ### `update`
192
+
193
+ Update an existing token's properties.
194
+
195
+ ```bash
196
+ access-tokens update \
197
+ --endpoint prod \
198
+ --token-id 9Xj2kLm5nPqRs7tUv \
199
+ --owner newuser@example.com
200
+
201
+ access-tokens update \
202
+ --endpoint prod \
203
+ --token-id 9Xj2kLm5nPqRs7tUv \
204
+ --admin true
205
+
206
+ access-tokens update \
207
+ --endpoint prod \
208
+ --token-id 9Xj2kLm5nPqRs7tUv \
209
+ --expires-at null
210
+ ```
211
+
212
+ **Options:**
213
+
214
+ - `--endpoint <name>` - Named endpoint from config
215
+ - `--url <url>` - Direct endpoint URL
216
+ - `--admin-token <token>` - Admin token (required with --url)
217
+ - `--auth-path <path>` - Auth path (default: /auth)
218
+ - `--admin-path <path>` - Admin path (default: /admin)
219
+ - `--config-dir <path>` - Config directory (default: ~/.access-tokens-cli)
220
+ - `--token-id <id>` - Token ID to update (required)
221
+ - `--owner <email>` - New owner
222
+ - `--admin <boolean>` - New admin status (true/false)
223
+ - `--secret-phc <phc>` - New secret PHC hash
224
+ - `--expires-at <date>` - New expiration or "null" to remove
225
+ - `--verbose` - Verbose output
226
+ - `--quiet` - Minimal output
227
+
228
+ ### `revoke`
229
+
230
+ Revoke a token.
231
+
232
+ ```bash
233
+ access-tokens revoke --endpoint prod --token-id 9Xj2kLm5nPqRs7tUv
234
+
235
+ # Revoke with cleanup in 30 days
236
+ access-tokens revoke \
237
+ --endpoint prod \
238
+ --token-id 9Xj2kLm5nPqRs7tUv \
239
+ --expires-at 2025-12-31
240
+ ```
241
+
242
+ **Options:**
243
+
244
+ - `--endpoint <name>` - Named endpoint from config
245
+ - `--url <url>` - Direct endpoint URL
246
+ - `--admin-token <token>` - Admin token (required with --url)
247
+ - `--auth-path <path>` - Auth path (default: /auth)
248
+ - `--admin-path <path>` - Admin path (default: /admin)
249
+ - `--config-dir <path>` - Config directory (default: ~/.access-tokens-cli)
250
+ - `--token-id <id>` - Token ID to revoke (required)
251
+ - `--expires-at <date>` - Expiration for cleanup (optional)
252
+ - `--verbose` - Verbose output
253
+ - `--quiet` - Minimal output
254
+
255
+ ### `restore`
256
+
257
+ Restore a previously revoked token.
258
+
259
+ ```bash
260
+ access-tokens restore --endpoint prod --token-id 9Xj2kLm5nPqRs7tUv
261
+ ```
262
+
263
+ **Options:**
264
+
265
+ - `--endpoint <name>` - Named endpoint from config
266
+ - `--url <url>` - Direct endpoint URL
267
+ - `--admin-token <token>` - Admin token (required with --url)
268
+ - `--auth-path <path>` - Auth path (default: /auth)
269
+ - `--admin-path <path>` - Admin path (default: /admin)
270
+ - `--config-dir <path>` - Config directory (default: ~/.access-tokens-cli)
271
+ - `--token-id <id>` - Token ID to restore (required)
272
+ - `--verbose` - Verbose output
273
+ - `--quiet` - Minimal output
274
+
275
+ ### `sync`
276
+
277
+ Sync tokens from YAML config to endpoints. Ensures tokens exist with correct properties.
278
+
279
+ **Sync Config (`sync.yaml`):**
280
+
281
+ ```yaml
282
+ tokens:
283
+ - tokenId: service-a-prod
284
+ owner: service-a@example.com
285
+ isAdmin: false
286
+ secretPhc: $scrypt$n=16384,r=8,p=1$...
287
+ expiresAt: 1735689599
288
+
289
+ - tokenId: admin-bot
290
+ owner: admin-bot@example.com
291
+ isAdmin: true
292
+ secretPhc: $scrypt$n=16384,r=8,p=1$...
293
+ ```
294
+
295
+ **Usage:**
296
+
297
+ ```bash
298
+ # Sync to configured endpoints
299
+ access-tokens sync --config sync.yaml
300
+
301
+ # Sync to specific endpoint
302
+ access-tokens sync --config sync.yaml --endpoint prod
303
+
304
+ # Sync to direct URL
305
+ access-tokens sync --config sync.yaml --url https://api.example.com --admin-token <token>
306
+
307
+ # Dry run (preview changes)
308
+ access-tokens sync --config sync.yaml --dry-run
309
+ ```
310
+
311
+ **Options:**
312
+
313
+ - `--config <path>` - Path to sync config YAML (required)
314
+ - `--endpoint <name>` - Target endpoint(s), comma-separated
315
+ - `--url <url>` - Direct endpoint URL (overrides config)
316
+ - `--admin-token <token>` - Admin token (required with --url)
317
+ - `--auth-path <path>` - Auth path (default: /auth)
318
+ - `--admin-path <path>` - Admin path (default: /admin)
319
+ - `--config-dir <path>` - Config directory (default: ~/.access-tokens-cli)
320
+ - `--dry-run` - Show changes without applying
321
+ - `--verbose` - Verbose output
322
+ - `--quiet` - Minimal output
323
+
324
+ ## Configuration
325
+
326
+ ### Config File Location
327
+
328
+ Default: `~/.access-tokens-cli/config.yaml`
329
+
330
+ Override: `--config-dir <path>`
331
+
332
+ ### Config File Format
333
+
334
+ ```yaml
335
+ endpoints:
336
+ prod:
337
+ url: https://api.example.com
338
+ adminToken: pat_prod_admin_token
339
+ authPath: /auth # optional, default: /auth
340
+ adminPath: /admin # optional, default: /admin
341
+
342
+ staging:
343
+ url: https://staging.example.com
344
+ adminToken: pat_staging_admin_token
345
+ ```
346
+
347
+ ### Security
348
+
349
+ The CLI validates config file permissions and warns if the file is world-readable (mode 0644 or more permissive).
350
+
351
+ **Secure your config:**
352
+
353
+ ```bash
354
+ chmod 600 ~/.access-tokens-cli/config.yaml
355
+ ```
356
+
357
+ ## Output Formats
358
+
359
+ ### Human-Readable (Default)
360
+
361
+ ```
362
+ Token issued successfully!
363
+
364
+ TOKEN (save this securely, it won't be shown again):
365
+ pat_9Xj2kLm5nPqRs7tUv.a8b9c0d1e2f3g4h5i6j7k8l9m0n1o2p3q4r5s6t7u8v9w0x1y2z3
366
+
367
+ Token ID: 9Xj2kLm5nPqRs7tUv
368
+ Owner: user@example.com
369
+ Admin: true
370
+ ```
371
+
372
+ ### JSON (--json)
373
+
374
+ ```json
375
+ {
376
+ "token": "pat_9Xj2kLm5nPqRs7tUv.a8b9c0d1e2f3g4h5i6j7k8l9m0n1o2p3q4r5s6t7u8v9w0x1y2z3",
377
+ "record": {
378
+ "tokenId": "9Xj2kLm5nPqRs7tUv",
379
+ "owner": "user@example.com",
380
+ "isAdmin": true,
381
+ "isRevoked": false,
382
+ "createdAt": 1704067200,
383
+ "updatedAt": 1704067200
384
+ }
385
+ }
386
+ ```
387
+
388
+ ## Exit Codes
389
+
390
+ - `0` - Success
391
+ - `1` - Error (invalid arguments, API error, etc.)
392
+
393
+ ## Requirements
394
+
395
+ - Node.js 20+
396
+ - @access-tokens/express server (except generate)
397
+
398
+ ## Related Packages
399
+
400
+ - [@access-tokens/core](https://www.npmjs.com/package/@access-tokens/core) - Core token management library
401
+ - [@access-tokens/express](https://www.npmjs.com/package/@access-tokens/express) - Express routes and middleware
402
+ - [@access-tokens/client](https://www.npmjs.com/package/@access-tokens/client) - HTTP client for PAT API
403
+
404
+ ## License
405
+
406
+ [ISC](https://opensource.org/licenses/ISC) © 2025 Loan Crate, Inc.
407
+
408
+ ## Links
409
+
410
+ - [GitHub Repository](https://github.com/loancrate/access-tokens)
411
+ - [npm Package](https://www.npmjs.com/package/@access-tokens/cli)
412
+ - [Documentation](https://github.com/loancrate/access-tokens#readme)
package/dist/cli.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type RunParameters = {
2
+ argv: string[];
3
+ env: NodeJS.ProcessEnv;
4
+ stdin: NodeJS.ReadableStream;
5
+ stdout: NodeJS.WritableStream;
6
+ stderr: NodeJS.WritableStream;
7
+ };
8
+ export declare function run(params: RunParameters): Promise<number>;
9
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CAC/B,CAAC;AAEF,wBAAsB,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAmMhE"}
package/dist/cli.js ADDED
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.run = run;
4
+ const commander_1 = require("commander");
5
+ const generate_1 = require("./commands/generate");
6
+ const issue_1 = require("./commands/issue");
7
+ const list_1 = require("./commands/list");
8
+ const register_1 = require("./commands/register");
9
+ const restore_1 = require("./commands/restore");
10
+ const revoke_1 = require("./commands/revoke");
11
+ const sync_1 = require("./commands/sync");
12
+ const update_1 = require("./commands/update");
13
+ async function run(params) {
14
+ const endpointOptions = () => [
15
+ new commander_1.Option("--endpoint <name>", "Named endpoint from config"),
16
+ new commander_1.Option("--url <url>", "Direct endpoint URL"),
17
+ new commander_1.Option("--admin-token <token>", "Admin token (required with --url)"),
18
+ new commander_1.Option("--auth-path <path>", "Auth path (default: /auth)"),
19
+ new commander_1.Option("--admin-path <path>", "Admin path (default: /admin)"),
20
+ new commander_1.Option("--config-dir <path>", "Config directory (default: ~/.access-tokens-cli)"),
21
+ ];
22
+ const outputOptions = () => [
23
+ new commander_1.Option("--verbose", "Verbose output"),
24
+ new commander_1.Option("--quiet", "Minimal output"),
25
+ ];
26
+ const jsonOption = () => new commander_1.Option("--json", "Output as JSON");
27
+ let exitCode = 0;
28
+ // Configure output streams for testing
29
+ function configureCommandOutput(cmd) {
30
+ cmd.configureOutput({
31
+ writeOut: (str) => params.stdout.write(str),
32
+ writeErr: (str) => params.stderr.write(str),
33
+ outputError: (str, write) => write(str),
34
+ });
35
+ }
36
+ // Configure exitOverride to prevent process.exit calls during tests
37
+ function configureExitOverride(cmd) {
38
+ cmd.exitOverride((err) => {
39
+ exitCode = err.exitCode ?? 1;
40
+ throw err;
41
+ });
42
+ }
43
+ function addOptions(command, options) {
44
+ options.forEach((opt) => command.addOption(opt));
45
+ configureCommandOutput(command);
46
+ configureExitOverride(command);
47
+ return command;
48
+ }
49
+ const program = new commander_1.Command();
50
+ program
51
+ .name("access-tokens-cli")
52
+ .description("CLI for managing personal access tokens");
53
+ addOptions(program
54
+ .command("generate")
55
+ .description("Generate a new token locally (without storing in database)")
56
+ .option("--token-prefix <prefix>", "Token prefix (default: pat_)")
57
+ .option("--token-id <id>", "Pre-generate with specific token ID"), [...outputOptions(), jsonOption()]).action(async (options) => {
58
+ await (0, generate_1.generateCommand)(options);
59
+ });
60
+ addOptions(program
61
+ .command("list")
62
+ .description("List tokens")
63
+ .option("--include-revoked", "Include revoked tokens")
64
+ .option("--include-expired", "Include expired tokens")
65
+ .option("--include-secret-phc", "Include secret PHC hashes"), [...endpointOptions(), ...outputOptions(), jsonOption()]).action(async (options) => {
66
+ await (0, list_1.listCommand)(options);
67
+ });
68
+ addOptions(program
69
+ .command("issue")
70
+ .description("Issue a new token")
71
+ .requiredOption("--owner <email>", "Token owner (usually email)")
72
+ .option("--admin", "Make token an admin token")
73
+ .option("--expires-at <date>", "Expiration date (ISO 8601 or Unix timestamp)"), [...endpointOptions(), ...outputOptions(), jsonOption()]).action(async (options) => {
74
+ await (0, issue_1.issueCommand)(options);
75
+ });
76
+ addOptions(program
77
+ .command("register")
78
+ .description("Register a token with pre-generated ID and secret hash")
79
+ .requiredOption("--token-id <id>", "Token ID")
80
+ .requiredOption("--secret-phc <phc>", "Secret PHC hash")
81
+ .requiredOption("--owner <email>", "Token owner (usually email)")
82
+ .option("--admin", "Make token an admin token")
83
+ .option("--expires-at <date>", "Expiration date (ISO 8601 or Unix timestamp)"), [...endpointOptions(), ...outputOptions(), jsonOption()]).action(async (options) => {
84
+ await (0, register_1.registerCommand)(options);
85
+ });
86
+ addOptions(program
87
+ .command("update")
88
+ .description("Update token properties")
89
+ .requiredOption("--token-id <id>", "Token ID")
90
+ .option("--owner <email>", "Update owner")
91
+ .option("--admin <boolean>", "Update admin status (true/false)", (val) => val === "true")
92
+ .option("--secret-phc <phc>", "Update secret PHC hash")
93
+ .option("--expires-at <date>", "Update expiration (ISO 8601, Unix timestamp, or 'null')"), [...endpointOptions(), ...outputOptions()]).action(async (options) => {
94
+ await (0, update_1.updateCommand)(options);
95
+ });
96
+ addOptions(program
97
+ .command("revoke")
98
+ .description("Revoke a token")
99
+ .requiredOption("--token-id <id>", "Token ID")
100
+ .option("--expires-at <date>", "Expiration date for revocation (ISO 8601 or Unix timestamp)"), [...endpointOptions(), ...outputOptions()]).action(async (options) => {
101
+ await (0, revoke_1.revokeCommand)(options);
102
+ });
103
+ addOptions(program
104
+ .command("restore")
105
+ .description("Restore a revoked token")
106
+ .requiredOption("--token-id <id>", "Token ID"), [...endpointOptions(), ...outputOptions()]).action(async (options) => {
107
+ await (0, restore_1.restoreCommand)(options);
108
+ });
109
+ addOptions(program
110
+ .command("sync")
111
+ .description("Sync tokens from YAML config to endpoints")
112
+ .requiredOption("--config <path>", "Path to sync config YAML file")
113
+ .option("--endpoint <name>", "Target specific endpoint(s) (comma-separated or multiple flags)")
114
+ .option("--url <url>", "Direct endpoint URL (overrides config endpoints)")
115
+ .option("--admin-token <token>", "Admin token (required with --url)")
116
+ .option("--auth-path <path>", "Auth path (default: /auth)")
117
+ .option("--admin-path <path>", "Admin path (default: /admin)")
118
+ .option("--dry-run", "Show what would be done without making changes")
119
+ .option("--config-dir <path>", "Config directory (default: ~/.access-tokens-cli)"), outputOptions()).action(async (options) => {
120
+ await (0, sync_1.syncCommand)(options);
121
+ });
122
+ // Configure output and exit override on the main program too
123
+ configureCommandOutput(program);
124
+ configureExitOverride(program);
125
+ try {
126
+ await program.parseAsync(params.argv, { from: "user" });
127
+ }
128
+ catch (err) {
129
+ if (err instanceof commander_1.CommanderError) {
130
+ // Commander errors are already handled by exitOverride
131
+ // exitCode is already set
132
+ }
133
+ else {
134
+ // Handle errors from command actions
135
+ params.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
136
+ exitCode = 1;
137
+ }
138
+ }
139
+ return exitCode;
140
+ }
141
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type GenerateOptions = {
2
+ tokenPrefix?: string;
3
+ tokenId?: string;
4
+ json?: boolean;
5
+ verbose?: boolean;
6
+ quiet?: boolean;
7
+ };
8
+ export declare function generateCommand(options: GenerateOptions): Promise<void>;
9
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC7E"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateCommand = generateCommand;
4
+ const core_1 = require("@access-tokens/core");
5
+ const logger_1 = require("../utils/logger");
6
+ async function generateCommand(options) {
7
+ const logger = new logger_1.Logger(options);
8
+ // Create a DynamoDBPat instance with minimal configuration
9
+ // Table name is not used by generate()
10
+ const pat = new core_1.DynamoDBPat({
11
+ tableName: "unused-table-name",
12
+ tokenPrefix: options.tokenPrefix,
13
+ });
14
+ logger.verbose("Generating new token...");
15
+ // Generate a new token
16
+ const { token, tokenId, secretPhc } = await pat.generate({
17
+ tokenId: options.tokenId,
18
+ });
19
+ if (options.json) {
20
+ logger.json({ token, tokenId, secretPhc });
21
+ }
22
+ else {
23
+ logger.success("Here is your new personal access token. Don't share it with anyone!");
24
+ logger.info("");
25
+ logger.info(token);
26
+ logger.info("");
27
+ logger.info("Provide the following information to your administrator to register the token:");
28
+ logger.info("");
29
+ logger.info(`Token ID: ${tokenId}`);
30
+ logger.info(`Secret hash: ${secretPhc}`);
31
+ }
32
+ }
33
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":";;AAYA,0CAiCC;AA7CD,8CAAkD;AAElD,4CAAyC;AAUlC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,OAAO,CAAC,CAAC;IAEnC,2DAA2D;IAC3D,uCAAuC;IACvC,MAAM,GAAG,GAAG,IAAI,kBAAW,CAAC;QAC1B,SAAS,EAAE,mBAAmB;QAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAE1C,uBAAuB;IACvB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC;QACvD,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,OAAO,CACZ,qEAAqE,CACtE,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CACT,gFAAgF,CACjF,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ export type IssueOptions = {
2
+ endpoint?: string;
3
+ url?: string;
4
+ adminToken?: string;
5
+ authPath?: string;
6
+ adminPath?: string;
7
+ owner: string;
8
+ admin?: boolean;
9
+ expiresAt?: string;
10
+ configDir?: string;
11
+ json?: boolean;
12
+ verbose?: boolean;
13
+ quiet?: boolean;
14
+ };
15
+ export declare function issueCommand(options: IssueOptions): Promise<void>;
16
+ //# sourceMappingURL=issue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/commands/issue.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCvE"}