@portaidentity/cli 0.1.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 (157) hide show
  1. package/dist/auth/browser-flow.d.ts +42 -0
  2. package/dist/auth/browser-flow.d.ts.map +1 -0
  3. package/dist/auth/browser-flow.js +193 -0
  4. package/dist/auth/browser-flow.js.map +1 -0
  5. package/dist/auth/callback-server.d.ts +81 -0
  6. package/dist/auth/callback-server.d.ts.map +1 -0
  7. package/dist/auth/callback-server.js +193 -0
  8. package/dist/auth/callback-server.js.map +1 -0
  9. package/dist/auth/metadata.d.ts +43 -0
  10. package/dist/auth/metadata.d.ts.map +1 -0
  11. package/dist/auth/metadata.js +66 -0
  12. package/dist/auth/metadata.js.map +1 -0
  13. package/dist/auth/pkce.d.ts +42 -0
  14. package/dist/auth/pkce.d.ts.map +1 -0
  15. package/dist/auth/pkce.js +52 -0
  16. package/dist/auth/pkce.js.map +1 -0
  17. package/dist/auth/types.d.ts +72 -0
  18. package/dist/auth/types.d.ts.map +1 -0
  19. package/dist/auth/types.js +11 -0
  20. package/dist/auth/types.js.map +1 -0
  21. package/dist/client-factory.d.ts +29 -0
  22. package/dist/client-factory.d.ts.map +1 -0
  23. package/dist/client-factory.js +43 -0
  24. package/dist/client-factory.js.map +1 -0
  25. package/dist/commands/app-claim.d.ts +9 -0
  26. package/dist/commands/app-claim.d.ts.map +1 -0
  27. package/dist/commands/app-claim.js +128 -0
  28. package/dist/commands/app-claim.js.map +1 -0
  29. package/dist/commands/app-module.d.ts +9 -0
  30. package/dist/commands/app-module.d.ts.map +1 -0
  31. package/dist/commands/app-module.js +104 -0
  32. package/dist/commands/app-module.js.map +1 -0
  33. package/dist/commands/app-permission.d.ts +9 -0
  34. package/dist/commands/app-permission.d.ts.map +1 -0
  35. package/dist/commands/app-permission.js +118 -0
  36. package/dist/commands/app-permission.js.map +1 -0
  37. package/dist/commands/app-role.d.ts +9 -0
  38. package/dist/commands/app-role.d.ts.map +1 -0
  39. package/dist/commands/app-role.js +166 -0
  40. package/dist/commands/app-role.js.map +1 -0
  41. package/dist/commands/app.d.ts +12 -0
  42. package/dist/commands/app.d.ts.map +1 -0
  43. package/dist/commands/app.js +255 -0
  44. package/dist/commands/app.js.map +1 -0
  45. package/dist/commands/audit.d.ts +12 -0
  46. package/dist/commands/audit.d.ts.map +1 -0
  47. package/dist/commands/audit.js +96 -0
  48. package/dist/commands/audit.js.map +1 -0
  49. package/dist/commands/bulk.d.ts +12 -0
  50. package/dist/commands/bulk.d.ts.map +1 -0
  51. package/dist/commands/bulk.js +77 -0
  52. package/dist/commands/bulk.js.map +1 -0
  53. package/dist/commands/client-secret.d.ts +18 -0
  54. package/dist/commands/client-secret.d.ts.map +1 -0
  55. package/dist/commands/client-secret.js +126 -0
  56. package/dist/commands/client-secret.js.map +1 -0
  57. package/dist/commands/client.d.ts +27 -0
  58. package/dist/commands/client.d.ts.map +1 -0
  59. package/dist/commands/client.js +385 -0
  60. package/dist/commands/client.js.map +1 -0
  61. package/dist/commands/completion.d.ts +27 -0
  62. package/dist/commands/completion.d.ts.map +1 -0
  63. package/dist/commands/completion.js +42 -0
  64. package/dist/commands/completion.js.map +1 -0
  65. package/dist/commands/config.d.ts +14 -0
  66. package/dist/commands/config.d.ts.map +1 -0
  67. package/dist/commands/config.js +85 -0
  68. package/dist/commands/config.js.map +1 -0
  69. package/dist/commands/doctor.d.ts +25 -0
  70. package/dist/commands/doctor.d.ts.map +1 -0
  71. package/dist/commands/doctor.js +198 -0
  72. package/dist/commands/doctor.js.map +1 -0
  73. package/dist/commands/exports.d.ts +12 -0
  74. package/dist/commands/exports.d.ts.map +1 -0
  75. package/dist/commands/exports.js +80 -0
  76. package/dist/commands/exports.js.map +1 -0
  77. package/dist/commands/health.d.ts +12 -0
  78. package/dist/commands/health.d.ts.map +1 -0
  79. package/dist/commands/health.js +53 -0
  80. package/dist/commands/health.js.map +1 -0
  81. package/dist/commands/keys.d.ts +14 -0
  82. package/dist/commands/keys.d.ts.map +1 -0
  83. package/dist/commands/keys.js +91 -0
  84. package/dist/commands/keys.js.map +1 -0
  85. package/dist/commands/login.d.ts +36 -0
  86. package/dist/commands/login.d.ts.map +1 -0
  87. package/dist/commands/login.js +78 -0
  88. package/dist/commands/login.js.map +1 -0
  89. package/dist/commands/logout.d.ts +25 -0
  90. package/dist/commands/logout.d.ts.map +1 -0
  91. package/dist/commands/logout.js +43 -0
  92. package/dist/commands/logout.js.map +1 -0
  93. package/dist/commands/org.d.ts +26 -0
  94. package/dist/commands/org.d.ts.map +1 -0
  95. package/dist/commands/org.js +396 -0
  96. package/dist/commands/org.js.map +1 -0
  97. package/dist/commands/provision.d.ts +47 -0
  98. package/dist/commands/provision.d.ts.map +1 -0
  99. package/dist/commands/provision.js +400 -0
  100. package/dist/commands/provision.js.map +1 -0
  101. package/dist/commands/sessions.d.ts +14 -0
  102. package/dist/commands/sessions.d.ts.map +1 -0
  103. package/dist/commands/sessions.js +122 -0
  104. package/dist/commands/sessions.js.map +1 -0
  105. package/dist/commands/stats.d.ts +12 -0
  106. package/dist/commands/stats.d.ts.map +1 -0
  107. package/dist/commands/stats.js +46 -0
  108. package/dist/commands/stats.js.map +1 -0
  109. package/dist/commands/user-claim.d.ts +17 -0
  110. package/dist/commands/user-claim.d.ts.map +1 -0
  111. package/dist/commands/user-claim.js +123 -0
  112. package/dist/commands/user-claim.js.map +1 -0
  113. package/dist/commands/user-role.d.ts +17 -0
  114. package/dist/commands/user-role.d.ts.map +1 -0
  115. package/dist/commands/user-role.js +118 -0
  116. package/dist/commands/user-role.js.map +1 -0
  117. package/dist/commands/user.d.ts +26 -0
  118. package/dist/commands/user.d.ts.map +1 -0
  119. package/dist/commands/user.js +352 -0
  120. package/dist/commands/user.js.map +1 -0
  121. package/dist/commands/version.d.ts +25 -0
  122. package/dist/commands/version.d.ts.map +1 -0
  123. package/dist/commands/version.js +83 -0
  124. package/dist/commands/version.js.map +1 -0
  125. package/dist/commands/whoami.d.ts +26 -0
  126. package/dist/commands/whoami.d.ts.map +1 -0
  127. package/dist/commands/whoami.js +66 -0
  128. package/dist/commands/whoami.js.map +1 -0
  129. package/dist/credential-store.d.ts +101 -0
  130. package/dist/credential-store.d.ts.map +1 -0
  131. package/dist/credential-store.js +121 -0
  132. package/dist/credential-store.js.map +1 -0
  133. package/dist/error-handler.d.ts +47 -0
  134. package/dist/error-handler.d.ts.map +1 -0
  135. package/dist/error-handler.js +166 -0
  136. package/dist/error-handler.js.map +1 -0
  137. package/dist/global-options.d.ts +50 -0
  138. package/dist/global-options.d.ts.map +1 -0
  139. package/dist/global-options.js +62 -0
  140. package/dist/global-options.js.map +1 -0
  141. package/dist/index.d.ts +29 -0
  142. package/dist/index.d.ts.map +1 -0
  143. package/dist/index.js +122 -0
  144. package/dist/index.js.map +1 -0
  145. package/dist/output.d.ts +75 -0
  146. package/dist/output.d.ts.map +1 -0
  147. package/dist/output.js +100 -0
  148. package/dist/output.js.map +1 -0
  149. package/dist/parsers.d.ts +74 -0
  150. package/dist/parsers.d.ts.map +1 -0
  151. package/dist/parsers.js +125 -0
  152. package/dist/parsers.js.map +1 -0
  153. package/dist/prompt.d.ts +50 -0
  154. package/dist/prompt.d.ts.map +1 -0
  155. package/dist/prompt.js +98 -0
  156. package/dist/prompt.js.map +1 -0
  157. package/package.json +46 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * CLI doctor command — diagnostic checks for the CLI environment.
3
+ *
4
+ * Runs a series of checks to verify the CLI setup is correct:
5
+ * 1. Node.js version (>= 22.0.0 required)
6
+ * 2. Credentials file exists and is readable
7
+ * 3. Token validity (not expired)
8
+ * 4. Server reachability (health endpoint)
9
+ * 5. Admin metadata endpoint accessible
10
+ *
11
+ * Useful for troubleshooting authentication or connectivity issues.
12
+ *
13
+ * Usage:
14
+ * porta doctor # Run all diagnostic checks
15
+ * porta doctor --json # JSON output (machine-readable)
16
+ *
17
+ * @module commands/doctor
18
+ */
19
+ import { loadCredentials, isTokenExpired, getCredentialsPath, hasCredentials, } from '../credential-store.js';
20
+ import { fetchHealthStatus, fetchAdminMetadata } from '../auth/metadata.js';
21
+ import { printJson, success, warn, error as printError } from '../output.js';
22
+ // ---------------------------------------------------------------------------
23
+ // Diagnostic Checks
24
+ // ---------------------------------------------------------------------------
25
+ /**
26
+ * Check Node.js version meets the minimum requirement.
27
+ */
28
+ function checkNodeVersion() {
29
+ const version = process.version;
30
+ const major = parseInt(version.slice(1).split('.')[0], 10);
31
+ if (major >= 22) {
32
+ return { name: 'Node.js version', status: 'pass', message: `${version} (>= 22 required)` };
33
+ }
34
+ return { name: 'Node.js version', status: 'fail', message: `${version} — Node.js >= 22.0.0 is required` };
35
+ }
36
+ /**
37
+ * Check credential file existence and validity.
38
+ */
39
+ function checkCredentials() {
40
+ const path = getCredentialsPath();
41
+ if (!hasCredentials()) {
42
+ return {
43
+ name: 'Credentials',
44
+ status: 'warn',
45
+ message: `Not found at ${path}. Run "porta login" to authenticate.`,
46
+ };
47
+ }
48
+ const creds = loadCredentials();
49
+ if (!creds) {
50
+ return {
51
+ name: 'Credentials',
52
+ status: 'fail',
53
+ message: `File exists at ${path} but cannot be parsed. Try "porta logout" then "porta login".`,
54
+ };
55
+ }
56
+ return {
57
+ name: 'Credentials',
58
+ status: 'pass',
59
+ message: `Found at ${path} (user: ${creds.userInfo.email || creds.userInfo.sub})`,
60
+ };
61
+ }
62
+ /**
63
+ * Check token expiry status.
64
+ */
65
+ function checkTokenExpiry() {
66
+ const creds = loadCredentials();
67
+ if (!creds) {
68
+ return { name: 'Token validity', status: 'warn', message: 'No credentials — skipped' };
69
+ }
70
+ if (isTokenExpired(creds)) {
71
+ return {
72
+ name: 'Token validity',
73
+ status: 'warn',
74
+ message: `Expired at ${creds.expiresAt}. Run "porta login" to re-authenticate.`,
75
+ };
76
+ }
77
+ return {
78
+ name: 'Token validity',
79
+ status: 'pass',
80
+ message: `Valid until ${creds.expiresAt}`,
81
+ };
82
+ }
83
+ /**
84
+ * Check server reachability via health endpoint.
85
+ */
86
+ async function checkServerHealth(serverUrl) {
87
+ if (!serverUrl) {
88
+ return {
89
+ name: 'Server health',
90
+ status: 'warn',
91
+ message: 'No server configured — skipped',
92
+ };
93
+ }
94
+ const health = await fetchHealthStatus(serverUrl);
95
+ if (!health) {
96
+ return {
97
+ name: 'Server health',
98
+ status: 'fail',
99
+ message: `Cannot reach ${serverUrl}/health`,
100
+ };
101
+ }
102
+ if (health.status === 'ok') {
103
+ const services = health.services
104
+ ? Object.entries(health.services).map(([k, v]) => `${k}=${v}`).join(', ')
105
+ : '';
106
+ return {
107
+ name: 'Server health',
108
+ status: 'pass',
109
+ message: `${serverUrl} — OK${services ? ` (${services})` : ''}`,
110
+ };
111
+ }
112
+ return {
113
+ name: 'Server health',
114
+ status: 'warn',
115
+ message: `${serverUrl} — status: ${health.status}`,
116
+ };
117
+ }
118
+ /**
119
+ * Check admin metadata endpoint accessibility.
120
+ */
121
+ async function checkMetadata(serverUrl) {
122
+ if (!serverUrl) {
123
+ return {
124
+ name: 'Admin metadata',
125
+ status: 'warn',
126
+ message: 'No server configured — skipped',
127
+ };
128
+ }
129
+ try {
130
+ const metadata = await fetchAdminMetadata(serverUrl);
131
+ return {
132
+ name: 'Admin metadata',
133
+ status: 'pass',
134
+ message: `Org: ${metadata.orgSlug}, Client: ${metadata.clientId.slice(0, 8)}...`,
135
+ };
136
+ }
137
+ catch (err) {
138
+ return {
139
+ name: 'Admin metadata',
140
+ status: 'fail',
141
+ message: err instanceof Error ? err.message : 'Unknown error',
142
+ };
143
+ }
144
+ }
145
+ // ---------------------------------------------------------------------------
146
+ // Command Definition
147
+ // ---------------------------------------------------------------------------
148
+ /**
149
+ * The doctor command module — runs diagnostic checks.
150
+ */
151
+ export const doctorCommand = {
152
+ command: 'doctor',
153
+ describe: 'Run diagnostic checks on CLI configuration',
154
+ handler: async (argv) => {
155
+ // Handle --insecure flag before any HTTP calls
156
+ if (argv.insecure) {
157
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
158
+ }
159
+ // Resolve server URL for network checks
160
+ const creds = loadCredentials();
161
+ const serverUrl = argv.server || process.env.PORTA_SERVER || creds?.server;
162
+ // Run all checks
163
+ const results = [
164
+ checkNodeVersion(),
165
+ checkCredentials(),
166
+ checkTokenExpiry(),
167
+ await checkServerHealth(serverUrl),
168
+ await checkMetadata(serverUrl),
169
+ ];
170
+ // Output
171
+ if (argv.json) {
172
+ printJson(results);
173
+ }
174
+ else {
175
+ console.log('\nPorta CLI Diagnostics\n');
176
+ for (const check of results) {
177
+ const icon = check.status === 'pass' ? '✅' : check.status === 'warn' ? '⚠️' : '❌';
178
+ console.log(` ${icon} ${check.name}: ${check.message}`);
179
+ }
180
+ console.log('');
181
+ const failures = results.filter((r) => r.status === 'fail');
182
+ const warnings = results.filter((r) => r.status === 'warn');
183
+ if (failures.length > 0) {
184
+ printError(`${failures.length} check(s) failed`);
185
+ }
186
+ else if (warnings.length > 0) {
187
+ warn(`All checks passed with ${warnings.length} warning(s)`);
188
+ }
189
+ else {
190
+ success('All checks passed');
191
+ }
192
+ }
193
+ // Exit with failure if any check failed
194
+ const hasFailure = results.some((r) => r.status === 'fail');
195
+ process.exit(hasFailure ? 1 : 0);
196
+ },
197
+ };
198
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EACL,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAa7E,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;GAEG;AACH,SAAS,gBAAgB;IACvB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE3D,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,mBAAmB,EAAE,CAAC;IAC7F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,kCAAkC,EAAE,CAAC;AAC5G,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB;IACvB,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;IAElC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gBAAgB,IAAI,sCAAsC;SACpE,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,kBAAkB,IAAI,+DAA+D;SAC/F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,YAAY,IAAI,WAAW,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,GAAG;KAClF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB;IACvB,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACzF,CAAC;IAED,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,cAAc,KAAK,CAAC,SAAS,yCAAyC;SAChF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,eAAe,KAAK,CAAC,SAAS,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB,CAAC,SAA6B;IAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gCAAgC;SAC1C,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gBAAgB,SAAS,SAAS;SAC5C,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ;YAC9B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACzE,CAAC,CAAC,EAAE,CAAC;QACP,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,GAAG,SAAS,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;SAChE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,GAAG,SAAS,cAAc,MAAM,CAAC,MAAM,EAAE;KACnD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAAC,SAA6B;IACxD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gCAAgC;SAC1C,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,QAAQ,QAAQ,CAAC,OAAO,aAAa,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK;SACjF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAgD;IACxE,OAAO,EAAE,QAAQ;IACjB,QAAQ,EAAE,4CAA4C;IAEtD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,+CAA+C;QAC/C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,GAAG,CAAC;QACjD,CAAC;QAED,wCAAwC;QACxC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,KAAK,EAAE,MAAM,CAAC;QAE3E,iBAAiB;QACjB,MAAM,OAAO,GAAkB;YAC7B,gBAAgB,EAAE;YAClB,gBAAgB,EAAE;YAClB,gBAAgB,EAAE;YAClB,MAAM,iBAAiB,CAAC,SAAS,CAAC;YAClC,MAAM,aAAa,CAAC,SAAS,CAAC;SAC/B,CAAC;QAEF,SAAS;QACT,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,SAAS,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YAEzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;gBAClF,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3D,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;YAE5D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,UAAU,CAAC,GAAG,QAAQ,CAAC,MAAM,kBAAkB,CAAC,CAAC;YACnD,CAAC;iBAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,0BAA0B,QAAQ,CAAC,MAAM,aAAa,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,mBAAmB,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;CACF,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Exports command — export data as CSV or JSON.
3
+ *
4
+ * Subcommands:
5
+ * download Export entity data to a file or stdout
6
+ *
7
+ * @module commands/exports
8
+ */
9
+ import type { CommandModule } from 'yargs';
10
+ import type { GlobalOptions } from '../global-options.js';
11
+ export declare const exportsCommand: CommandModule<GlobalOptions, GlobalOptions>;
12
+ //# sourceMappingURL=exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../src/commands/exports.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqB1D,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,aAAa,EAAE,aAAa,CAsEtE,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Exports command — export data as CSV or JSON.
3
+ *
4
+ * Subcommands:
5
+ * download Export entity data to a file or stdout
6
+ *
7
+ * @module commands/exports
8
+ */
9
+ import fs from 'node:fs';
10
+ import { createClient } from '../client-factory.js';
11
+ import { handleError } from '../error-handler.js';
12
+ import { success, info } from '../output.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Command
15
+ // ---------------------------------------------------------------------------
16
+ export const exportsCommand = {
17
+ command: 'exports',
18
+ describe: 'Export data as CSV or JSON',
19
+ builder: (yargs) => yargs
20
+ .command('download', 'Export entity data', (y) => y
21
+ .option('entity-type', {
22
+ type: 'string',
23
+ describe: 'Entity type to export',
24
+ choices: ['organizations', 'applications', 'clients', 'users', 'roles', 'permissions', 'audit'],
25
+ demandOption: true,
26
+ })
27
+ .option('format', {
28
+ type: 'string',
29
+ describe: 'Export format',
30
+ choices: ['csv', 'json'],
31
+ default: 'csv',
32
+ })
33
+ .option('org-id', {
34
+ type: 'string',
35
+ describe: 'Filter by organization ID',
36
+ })
37
+ .option('app-id', {
38
+ type: 'string',
39
+ describe: 'Filter by application ID',
40
+ })
41
+ .option('output', {
42
+ alias: 'o',
43
+ type: 'string',
44
+ describe: 'Output file path (default: stdout)',
45
+ }), async (argv) => {
46
+ try {
47
+ const client = createClient(argv);
48
+ const response = await client.exports.download({
49
+ entityType: argv['entity-type'],
50
+ format: argv.format,
51
+ organizationId: argv['org-id'],
52
+ applicationId: argv['app-id'],
53
+ });
54
+ // The SDK returns a TransportResponse with raw body
55
+ const content = typeof response.body === 'string'
56
+ ? response.body
57
+ : JSON.stringify(response.body, null, 2);
58
+ if (argv.output) {
59
+ fs.writeFileSync(argv.output, content, 'utf-8');
60
+ success(`Exported ${argv['entity-type']} to ${argv.output}`);
61
+ }
62
+ else {
63
+ // Write to stdout
64
+ process.stdout.write(content);
65
+ if (!content.endsWith('\n')) {
66
+ process.stdout.write('\n');
67
+ }
68
+ info(`Exported ${argv['entity-type']} (${argv.format})`);
69
+ }
70
+ }
71
+ catch (err) {
72
+ handleError(err, argv.verbose);
73
+ }
74
+ })
75
+ .demandCommand(1, 'Please specify an exports subcommand: download'),
76
+ handler: () => {
77
+ // No-op — subcommands handle execution
78
+ },
79
+ };
80
+ //# sourceMappingURL=exports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.js","sourceRoot":"","sources":["../../src/commands/exports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Health command — check server health.
3
+ *
4
+ * Makes a simple HTTP GET to /health on the Porta server.
5
+ * Does not require authentication.
6
+ *
7
+ * @module commands/health
8
+ */
9
+ import type { CommandModule } from 'yargs';
10
+ import type { GlobalOptions } from '../global-options.js';
11
+ export declare const healthCommand: CommandModule<GlobalOptions, GlobalOptions>;
12
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqB1D,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,aAAa,EAAE,aAAa,CAuCrE,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Health command — check server health.
3
+ *
4
+ * Makes a simple HTTP GET to /health on the Porta server.
5
+ * Does not require authentication.
6
+ *
7
+ * @module commands/health
8
+ */
9
+ import { resolveServerUrl } from '../global-options.js';
10
+ import { handleError } from '../error-handler.js';
11
+ import { printJson, success, error as printError } from '../output.js';
12
+ // ---------------------------------------------------------------------------
13
+ // Command
14
+ // ---------------------------------------------------------------------------
15
+ export const healthCommand = {
16
+ command: 'health',
17
+ describe: 'Check Porta server health',
18
+ builder: (y) => y,
19
+ handler: async (argv) => {
20
+ try {
21
+ const serverUrl = resolveServerUrl(argv);
22
+ const url = new URL('/health', serverUrl);
23
+ // Use fetch (Node 22 built-in) for unauthenticated health check
24
+ const response = await fetch(url.toString(), {
25
+ method: 'GET',
26
+ headers: { Accept: 'application/json' },
27
+ // Respect --insecure flag for self-signed certs
28
+ ...(argv.insecure ? { dispatcher: undefined } : {}),
29
+ });
30
+ const body = (await response.json());
31
+ if (argv.json) {
32
+ printJson(body);
33
+ return;
34
+ }
35
+ if (response.ok && body.status === 'ok') {
36
+ success(`Server is healthy (${serverUrl})`);
37
+ console.log(` Database: ${body.database}`);
38
+ console.log(` Redis: ${body.redis}`);
39
+ }
40
+ else {
41
+ printError(`Server is unhealthy (${serverUrl})`);
42
+ console.log(` Status: ${body.status}`);
43
+ console.log(` Database: ${body.database}`);
44
+ console.log(` Redis: ${body.redis}`);
45
+ process.exitCode = 1;
46
+ }
47
+ }
48
+ catch (err) {
49
+ handleError(err, argv.verbose);
50
+ }
51
+ },
52
+ };
53
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAcvE,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,CAAC,MAAM,aAAa,GAAgD;IACxE,OAAO,EAAE,QAAQ;IACjB,QAAQ,EAAE,2BAA2B;IACrC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAE1C,gEAAgE;YAChE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;gBAC3C,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;gBACvC,gDAAgD;gBAChD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;YAEvD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBACxC,OAAO,CAAC,sBAAsB,SAAS,GAAG,CAAC,CAAC;gBAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3C,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,wBAAwB,SAAS,GAAG,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Keys command — manage signing keys.
3
+ *
4
+ * Subcommands:
5
+ * list List all signing keys
6
+ * generate Generate a new ES256 key pair
7
+ * rotate Rotate: generate new + retire current active
8
+ *
9
+ * @module commands/keys
10
+ */
11
+ import type { CommandModule } from 'yargs';
12
+ import type { GlobalOptions } from '../global-options.js';
13
+ export declare const keysCommand: CommandModule<GlobalOptions, GlobalOptions>;
14
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAgB1D,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,aAAa,EAAE,aAAa,CAkGnE,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Keys command — manage signing keys.
3
+ *
4
+ * Subcommands:
5
+ * list List all signing keys
6
+ * generate Generate a new ES256 key pair
7
+ * rotate Rotate: generate new + retire current active
8
+ *
9
+ * @module commands/keys
10
+ */
11
+ import { createClient } from '../client-factory.js';
12
+ import { handleError } from '../error-handler.js';
13
+ import { printTable, printJson, success, warn, formatDate, truncate } from '../output.js';
14
+ import { confirm } from '../prompt.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Command
17
+ // ---------------------------------------------------------------------------
18
+ export const keysCommand = {
19
+ command: 'keys',
20
+ describe: 'Manage signing keys',
21
+ builder: (yargs) => yargs
22
+ // ── list ──────────────────────────────────────────────────────────
23
+ .command('list', 'List all signing keys', (y) => y, async (argv) => {
24
+ try {
25
+ const client = createClient(argv);
26
+ const keys = await client.keys.list();
27
+ if (argv.json) {
28
+ printJson(keys);
29
+ return;
30
+ }
31
+ if (keys.length === 0) {
32
+ warn('No signing keys found');
33
+ return;
34
+ }
35
+ printTable(['ID', 'KID', 'Algorithm', 'Status', 'Created', 'Rotated'], keys.map((k) => [
36
+ truncate(k.id, 12),
37
+ k.kid,
38
+ k.algorithm,
39
+ k.isActive ? 'active' : 'retired',
40
+ formatDate(k.createdAt),
41
+ formatDate(k.rotatedAt),
42
+ ]));
43
+ success(`${keys.length} signing key(s)`);
44
+ }
45
+ catch (err) {
46
+ handleError(err, argv.verbose);
47
+ }
48
+ })
49
+ // ── generate ──────────────────────────────────────────────────────
50
+ .command('generate', 'Generate a new ES256 key pair', (y) => y, async (argv) => {
51
+ try {
52
+ const client = createClient(argv);
53
+ const key = await client.keys.generate();
54
+ if (argv.json) {
55
+ printJson(key);
56
+ return;
57
+ }
58
+ success(`Generated signing key: ${key.kid} (${truncate(key.id, 12)})`);
59
+ }
60
+ catch (err) {
61
+ handleError(err, argv.verbose);
62
+ }
63
+ })
64
+ // ── rotate ────────────────────────────────────────────────────────
65
+ .command('rotate', 'Rotate signing keys (generate new + retire current active)', (y) => y, async (argv) => {
66
+ try {
67
+ if (!argv.force) {
68
+ const ok = await confirm('Rotate signing keys? This will retire the current active key.');
69
+ if (!ok) {
70
+ warn('Aborted');
71
+ return;
72
+ }
73
+ }
74
+ const client = createClient(argv);
75
+ const key = await client.keys.rotate();
76
+ if (argv.json) {
77
+ printJson(key);
78
+ return;
79
+ }
80
+ success(`Rotated signing keys. New active key: ${key.kid}`);
81
+ }
82
+ catch (err) {
83
+ handleError(err, argv.verbose);
84
+ }
85
+ })
86
+ .demandCommand(1, 'Please specify a keys subcommand: list, generate, rotate'),
87
+ handler: () => {
88
+ // No-op — subcommands handle execution
89
+ },
90
+ };
91
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * CLI login command — authenticate with a Porta server.
3
+ *
4
+ * Implements the OIDC Authorization Code + PKCE flow for CLI authentication.
5
+ * This is the same pattern used by `az login`, `gh auth login`, and similar
6
+ * CLI tools that authenticate via browser-based flows.
7
+ *
8
+ * Usage:
9
+ * porta login # Login to default server
10
+ * porta login --server https://example.com # Login to remote server
11
+ * porta login --no-browser # Manual mode: print URL, paste callback
12
+ * porta login --client-id <id> # Override auto-discovered client ID
13
+ *
14
+ * Docker / headless environments:
15
+ * When running inside a Docker container (auto-detected via /.dockerenv),
16
+ * the command automatically uses manual mode (--no-browser).
17
+ *
18
+ * @module commands/login
19
+ */
20
+ import type { CommandModule } from 'yargs';
21
+ import type { GlobalOptions } from '../global-options.js';
22
+ /** Options specific to the login command */
23
+ interface LoginOptions extends GlobalOptions {
24
+ server: string;
25
+ 'client-id'?: string;
26
+ 'no-browser': boolean;
27
+ }
28
+ /**
29
+ * The login command module — authenticates the CLI with a Porta server.
30
+ *
31
+ * Uses OIDC Authorization Code + PKCE flow. Opens a browser for
32
+ * interactive authentication, then stores the tokens locally.
33
+ */
34
+ export declare const loginCommand: CommandModule<GlobalOptions, LoginOptions>;
35
+ export {};
36
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAiB1D,4CAA4C;AAC5C,UAAU,YAAa,SAAQ,aAAa;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;CACvB;AAMD;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,aAAa,EAAE,YAAY,CA+CnE,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * CLI login command — authenticate with a Porta server.
3
+ *
4
+ * Implements the OIDC Authorization Code + PKCE flow for CLI authentication.
5
+ * This is the same pattern used by `az login`, `gh auth login`, and similar
6
+ * CLI tools that authenticate via browser-based flows.
7
+ *
8
+ * Usage:
9
+ * porta login # Login to default server
10
+ * porta login --server https://example.com # Login to remote server
11
+ * porta login --no-browser # Manual mode: print URL, paste callback
12
+ * porta login --client-id <id> # Override auto-discovered client ID
13
+ *
14
+ * Docker / headless environments:
15
+ * When running inside a Docker container (auto-detected via /.dockerenv),
16
+ * the command automatically uses manual mode (--no-browser).
17
+ *
18
+ * @module commands/login
19
+ */
20
+ import { executeBrowserFlow } from '../auth/browser-flow.js';
21
+ import { saveCredentials } from '../credential-store.js';
22
+ import { success } from '../output.js';
23
+ import { handleError } from '../error-handler.js';
24
+ // ---------------------------------------------------------------------------
25
+ // Constants
26
+ // ---------------------------------------------------------------------------
27
+ /** Default Porta server URL for local development */
28
+ const DEFAULT_SERVER = 'https://porta.local:3443';
29
+ // ---------------------------------------------------------------------------
30
+ // Command Definition
31
+ // ---------------------------------------------------------------------------
32
+ /**
33
+ * The login command module — authenticates the CLI with a Porta server.
34
+ *
35
+ * Uses OIDC Authorization Code + PKCE flow. Opens a browser for
36
+ * interactive authentication, then stores the tokens locally.
37
+ */
38
+ export const loginCommand = {
39
+ command: 'login',
40
+ describe: 'Authenticate with a Porta server',
41
+ builder: (yargs) => yargs
42
+ .option('server', {
43
+ type: 'string',
44
+ describe: 'Porta server URL',
45
+ default: DEFAULT_SERVER,
46
+ })
47
+ .option('client-id', {
48
+ type: 'string',
49
+ describe: 'Override admin client ID (normally auto-discovered from server)',
50
+ })
51
+ .option('no-browser', {
52
+ type: 'boolean',
53
+ describe: 'Print login URL instead of opening browser',
54
+ default: false,
55
+ }),
56
+ handler: async (argv) => {
57
+ try {
58
+ // Handle --insecure flag before any HTTP calls
59
+ if (argv.insecure) {
60
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
61
+ }
62
+ // Execute the OIDC browser flow
63
+ const result = await executeBrowserFlow({
64
+ server: argv.server,
65
+ clientId: argv['client-id'],
66
+ noBrowser: argv['no-browser'],
67
+ });
68
+ // Store credentials to disk
69
+ saveCredentials(result);
70
+ success(`Logged in as ${result.userInfo.email || result.userInfo.sub}`);
71
+ process.exit(0);
72
+ }
73
+ catch (err) {
74
+ handleError(err, argv.verbose);
75
+ }
76
+ },
77
+ };
78
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,qDAAqD;AACrD,MAAM,cAAc,GAAG,0BAA0B,CAAC;AAalD,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAA+C;IACtE,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,kCAAkC;IAE5C,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK;SACF,MAAM,CAAC,QAAQ,EAAE;QAChB,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,kBAAkB;QAC5B,OAAO,EAAE,cAAc;KACxB,CAAC;SACD,MAAM,CAAC,WAAW,EAAE;QACnB,IAAI,EAAE,QAAQ;QACd,QAAQ,EACN,iEAAiE;KACpE,CAAC;SACD,MAAM,CAAC,YAAY,EAAE;QACpB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,4CAA4C;QACtD,OAAO,EAAE,KAAK;KACf,CAAC;IAEN,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,IAAI,CAAC;YACH,+CAA+C;YAC/C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,GAAG,CAAC;YACjD,CAAC;YAED,gCAAgC;YAChC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;gBACtC,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC;gBAC3B,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC;aAC9B,CAAC,CAAC;YAEH,4BAA4B;YAC5B,eAAe,CAAC,MAAM,CAAC,CAAC;YAExB,OAAO,CACL,gBAAgB,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAC/D,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * CLI logout command — clear stored authentication tokens.
3
+ *
4
+ * Removes the ~/.porta/credentials.json file, effectively logging out
5
+ * the CLI user. Does NOT revoke tokens on the server — the access token
6
+ * will expire naturally based on its TTL.
7
+ *
8
+ * This is a local-only operation that does not require a network connection
9
+ * or a running Porta server.
10
+ *
11
+ * Usage:
12
+ * porta logout
13
+ *
14
+ * @module commands/logout
15
+ */
16
+ import type { CommandModule } from 'yargs';
17
+ import type { GlobalOptions } from '../global-options.js';
18
+ /**
19
+ * The logout command module — clears stored CLI authentication tokens.
20
+ *
21
+ * Reads existing credentials to show who was logged in, then deletes
22
+ * the credentials file. Safe to run even when not logged in.
23
+ */
24
+ export declare const logoutCommand: CommandModule<GlobalOptions, GlobalOptions>;
25
+ //# sourceMappingURL=logout.d.ts.map