@uic-coe-connect/cli 0.2.1 → 0.2.2
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/dist/commands/roles.js +69 -0
- package/dist/types.d.ts +9 -0
- package/package.json +1 -1
package/dist/commands/roles.js
CHANGED
|
@@ -184,6 +184,75 @@ export function registerRoleCommands() {
|
|
|
184
184
|
rules.forEach((rule, i) => info(` [${i}] ${describeRule(rule)}`));
|
|
185
185
|
});
|
|
186
186
|
},
|
|
187
|
+
}, {
|
|
188
|
+
name: "roles token",
|
|
189
|
+
summary: "Show, issue, or rotate the app's role-resolve token",
|
|
190
|
+
usage: "roles token <app> [--issue | --rotate | --revoke]",
|
|
191
|
+
details: [
|
|
192
|
+
"The token your app puts in COE_ROLES_TOKEN so the SDK can resolve roles.",
|
|
193
|
+
"It is stored hashed and shown ONCE, at issue — there is no way to read it",
|
|
194
|
+
"back later. Lost it? Rotate and update the app's env.",
|
|
195
|
+
"",
|
|
196
|
+
" coe roles token myapp --issue # first time",
|
|
197
|
+
" coe roles token myapp --rotate # replace a live one",
|
|
198
|
+
"",
|
|
199
|
+
"Then: coe env set myapp COE_ROLES_TOKEN=<value>, and deploy.",
|
|
200
|
+
],
|
|
201
|
+
async run({ args, client }) {
|
|
202
|
+
const c = client();
|
|
203
|
+
const app = await resolveApp(c, args.arg(0, "app"));
|
|
204
|
+
const path = `/registered-apps/${app.id}/roles/token`;
|
|
205
|
+
if (args.bool("revoke")) {
|
|
206
|
+
await c.request("DELETE", path);
|
|
207
|
+
emit({ appId: app.id, revoked: true }, () => {
|
|
208
|
+
info(`✓ Revoked ${app.id}'s roles token`);
|
|
209
|
+
info(" Role resolution now fails for this app until you issue a new one,");
|
|
210
|
+
info(" and users sign in with rolesResolved: false.");
|
|
211
|
+
});
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const issuing = args.bool("issue") || args.bool("rotate");
|
|
215
|
+
if (!issuing) {
|
|
216
|
+
const { token } = await c.request("GET", path);
|
|
217
|
+
emit({ appId: app.id, token }, () => {
|
|
218
|
+
if (!token) {
|
|
219
|
+
info(`${app.id} has no roles token.`);
|
|
220
|
+
info(` Issue one with: coe roles token ${app.id} --issue`);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
details([
|
|
224
|
+
["App", app.id],
|
|
225
|
+
["Token", `${token.prefix}… (stored hashed; issue a new one to see a value)`],
|
|
226
|
+
["Created", `${new Date(token.createdAt).toLocaleString()} by ${token.createdBy}`],
|
|
227
|
+
[
|
|
228
|
+
"Last used",
|
|
229
|
+
token.lastUsedAt
|
|
230
|
+
? new Date(token.lastUsedAt).toLocaleString()
|
|
231
|
+
: "never — the app hasn't resolved a role yet",
|
|
232
|
+
],
|
|
233
|
+
]);
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
// Rotating invalidates the value the deployed app is holding, so it
|
|
238
|
+
// can't be something you do by reaching for the wrong flag.
|
|
239
|
+
const existing = await c.request("GET", path);
|
|
240
|
+
if (existing.token && !args.bool("rotate")) {
|
|
241
|
+
throw new CliError(`${app.id} already has a roles token (${existing.token.prefix}…).`, 6, "Re-run with --rotate to replace it. The deployed app will fail to resolve roles until you update COE_ROLES_TOKEN and redeploy.");
|
|
242
|
+
}
|
|
243
|
+
const result = await c.request("POST", path);
|
|
244
|
+
emit(result, () => {
|
|
245
|
+
info(`✓ ${result.rotated ? "Rotated" : "Issued"} ${app.id}'s roles token`);
|
|
246
|
+
info("");
|
|
247
|
+
info(` ${result.token}`);
|
|
248
|
+
info("");
|
|
249
|
+
info(" This is the only time it is shown. Store it now:");
|
|
250
|
+
info(` coe env set ${app.id} COE_ROLES_TOKEN=${result.token}`);
|
|
251
|
+
if (result.rotated) {
|
|
252
|
+
info(" The previous token stopped working immediately — deploy to pick this one up.");
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
},
|
|
187
256
|
}, {
|
|
188
257
|
name: "roles remove-rule",
|
|
189
258
|
summary: "Remove a rule by its index (see roles show)",
|
package/dist/types.d.ts
CHANGED
|
@@ -61,6 +61,15 @@ export interface AppAccess {
|
|
|
61
61
|
devTeam: string[];
|
|
62
62
|
staff: StaffAccess;
|
|
63
63
|
}
|
|
64
|
+
/** An app's role-resolve token, minus anything that could reconstruct it. */
|
|
65
|
+
export interface RolesTokenInfo {
|
|
66
|
+
appId: string;
|
|
67
|
+
/** Leading characters only — enough to recognise which token is deployed. */
|
|
68
|
+
prefix: string;
|
|
69
|
+
createdAt: string;
|
|
70
|
+
createdBy: string;
|
|
71
|
+
lastUsedAt?: string;
|
|
72
|
+
}
|
|
64
73
|
export interface RegisteredApp {
|
|
65
74
|
id: string;
|
|
66
75
|
name: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uic-coe-connect/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "The coe CLI \u2014 manage COEConnect apps (pipelines, deploys, access, env) from a terminal, with browser-approved auth. Designed to be driven by an AI agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|