opal-security 3.1.1-beta.03364ed → 3.1.1-beta.12730e0

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 CHANGED
@@ -22,7 +22,7 @@ $ npm install -g opal-security
22
22
  $ opal COMMAND
23
23
  running command...
24
24
  $ opal (--version)
25
- opal-security/3.1.1-beta.03364ed linux-x64 node-v20.19.2
25
+ opal-security/3.1.1-beta.12730e0 linux-x64 node-v20.19.2
26
26
  $ opal --help [COMMAND]
27
27
  USAGE
28
28
  $ opal COMMAND
@@ -44,6 +44,9 @@ USAGE
44
44
  * [`opal login`](#opal-login)
45
45
  * [`opal logout`](#opal-logout)
46
46
  * [`opal postgres-instances start`](#opal-postgres-instances-start)
47
+ * [`opal request create`](#opal-request-create)
48
+ * [`opal request get`](#opal-request-get)
49
+ * [`opal request list`](#opal-request-list)
47
50
  * [`opal resources get`](#opal-resources-get)
48
51
  * [`opal set-auth-provider`](#opal-set-auth-provider)
49
52
  * [`opal set-custom-header`](#opal-set-custom-header)
@@ -53,6 +56,7 @@ USAGE
53
56
  * [`opal ssh copyTo`](#opal-ssh-copyto)
54
57
  * [`opal ssh start`](#opal-ssh-start)
55
58
  * [`opal version`](#opal-version)
59
+ * [`opal whoami`](#opal-whoami)
56
60
 
57
61
  ## `opal autocomplete [SHELL]`
58
62
 
@@ -101,7 +105,7 @@ EXAMPLES
101
105
  $ opal aws:identity
102
106
  ```
103
107
 
104
- _See code: [src/commands/aws/identity.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/aws/identity.ts)_
108
+ _See code: [src/commands/aws/identity.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/aws/identity.ts)_
105
109
 
106
110
  ## `opal clear-auth-provider`
107
111
 
@@ -121,7 +125,7 @@ EXAMPLES
121
125
  $ opal clear-auth-provider
122
126
  ```
123
127
 
124
- _See code: [src/commands/clear-auth-provider.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/clear-auth-provider.ts)_
128
+ _See code: [src/commands/clear-auth-provider.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/clear-auth-provider.ts)_
125
129
 
126
130
  ## `opal curl-example`
127
131
 
@@ -138,7 +142,7 @@ DESCRIPTION
138
142
  Prints out an example cURL command containing the parameters the CLI uses to query the Opal server.
139
143
  ```
140
144
 
141
- _See code: [src/commands/curl-example.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/curl-example.ts)_
145
+ _See code: [src/commands/curl-example.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/curl-example.ts)_
142
146
 
143
147
  ## `opal groups get`
144
148
 
@@ -159,7 +163,7 @@ EXAMPLES
159
163
  $ opal groups:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4
160
164
  ```
161
165
 
162
- _See code: [src/commands/groups/get.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/groups/get.ts)_
166
+ _See code: [src/commands/groups/get.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/groups/get.ts)_
163
167
 
164
168
  ## `opal help [COMMANDS]`
165
169
 
@@ -209,7 +213,7 @@ EXAMPLES
209
213
  $ opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --profileName "custom-profile"
210
214
  ```
211
215
 
212
- _See code: [src/commands/iam-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/iam-roles/start.ts)_
216
+ _See code: [src/commands/iam-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/iam-roles/start.ts)_
213
217
 
214
218
  ## `opal kube-roles start`
215
219
 
@@ -240,7 +244,7 @@ EXAMPLES
240
244
  $ opal kube-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId "arn:aws:iam::712234975475:role/acme-eks-cluster-admin-role"
241
245
  ```
242
246
 
243
- _See code: [src/commands/kube-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/kube-roles/start.ts)_
247
+ _See code: [src/commands/kube-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/kube-roles/start.ts)_
244
248
 
245
249
  ## `opal login`
246
250
 
@@ -261,7 +265,7 @@ EXAMPLES
261
265
  $ opal login
262
266
  ```
263
267
 
264
- _See code: [src/commands/login.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/login.ts)_
268
+ _See code: [src/commands/login.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/login.ts)_
265
269
 
266
270
  ## `opal logout`
267
271
 
@@ -281,7 +285,7 @@ EXAMPLES
281
285
  $ opal logout
282
286
  ```
283
287
 
284
- _See code: [src/commands/logout.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/logout.ts)_
288
+ _See code: [src/commands/logout.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/logout.ts)_
285
289
 
286
290
  ## `opal postgres-instances start`
287
291
 
@@ -318,7 +322,82 @@ EXAMPLES
318
322
  $ opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId fullaccess --action view
319
323
  ```
320
324
 
321
- _See code: [src/commands/postgres-instances/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/postgres-instances/start.ts)_
325
+ _See code: [src/commands/postgres-instances/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/postgres-instances/start.ts)_
326
+
327
+ ## `opal request create`
328
+
329
+ Creates an Opal access request via an interactive form
330
+
331
+ ```
332
+ USAGE
333
+ $ opal request create [-h] [-a <value>...] [-r <value>] [-d <value>]
334
+
335
+ FLAGS
336
+ -a, --assets=<value>... The ids of the assets (resource, group) to request access to. Append a role ID using a colon
337
+ if needed, e.g. `--assets 123:456`.
338
+ If not provided, an interactive selection flow will be available to select assets to request.
339
+ -d, --duration=<value> The duration of access for the request in minutes. If not provided, you will be prompted.
340
+ -h, --help Show CLI help.
341
+ -r, --reason=<value> The reason for the request, contained in quotes. If not provided, you will be prompted.
342
+
343
+ DESCRIPTION
344
+ Creates an Opal access request via an interactive form
345
+ ```
346
+
347
+ _See code: [src/commands/request/create.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/request/create.ts)_
348
+
349
+ ## `opal request get`
350
+
351
+ Lists access requests
352
+
353
+ ```
354
+ USAGE
355
+ $ opal request get [-h] [-i <value>] [-v]
356
+
357
+ FLAGS
358
+ -h, --help Show CLI help.
359
+ -i, --id=<value> The Opal ID of the asset. You can find this from the URL, e.g. https://opal.dev/resources/[ID]
360
+ -v, --verbose Enable verbose output, prints full response in JSON format. Defaults to false.
361
+
362
+ DESCRIPTION
363
+ Lists access requests
364
+
365
+ EXAMPLES
366
+ $ opal request get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4
367
+
368
+ $ opal request get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4 --verbose
369
+ ```
370
+
371
+ _See code: [src/commands/request/get.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/request/get.ts)_
372
+
373
+ ## `opal request list`
374
+
375
+ Lists your n recent outgoing access requests
376
+
377
+ ```
378
+ USAGE
379
+ $ opal request list [-h] [-n <value>] [-p] [-v]
380
+
381
+ FLAGS
382
+ -h, --help Show CLI help.
383
+ -n, --n=<value> [default: 10] Defines number of requests to be returned. 1 <= n <= 100.
384
+ -p, --pending Show only pending requests. Defaults to false.
385
+ -v, --verbose Enable verbose output, prints full response in JSON format. Defaults to false.
386
+
387
+ DESCRIPTION
388
+ Lists your n recent outgoing access requests
389
+
390
+ EXAMPLES
391
+ $ opal request list --n 5
392
+
393
+ $ opal request list --n 5 --pending
394
+
395
+ $ opal request list --n 5 --verbose
396
+
397
+ $ opal request list --n 5 --pending --verbose
398
+ ```
399
+
400
+ _See code: [src/commands/request/list.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/request/list.ts)_
322
401
 
323
402
  ## `opal resources get`
324
403
 
@@ -339,7 +418,7 @@ EXAMPLES
339
418
  $ opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4
340
419
  ```
341
420
 
342
- _See code: [src/commands/resources/get.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/resources/get.ts)_
421
+ _See code: [src/commands/resources/get.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/resources/get.ts)_
343
422
 
344
423
  ## `opal set-auth-provider`
345
424
 
@@ -365,7 +444,7 @@ EXAMPLES
365
444
  $ opal set-auth-provider --clientID 1234asdf --issuerUrl https://auth.example.com
366
445
  ```
367
446
 
368
- _See code: [src/commands/set-auth-provider.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/set-auth-provider.ts)_
447
+ _See code: [src/commands/set-auth-provider.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/set-auth-provider.ts)_
369
448
 
370
449
  ## `opal set-custom-header`
371
450
 
@@ -386,7 +465,7 @@ EXAMPLES
386
465
  $ opal set-custom-header --header 'cf-access-token: $TOKEN'
387
466
  ```
388
467
 
389
- _See code: [src/commands/set-custom-header.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/set-custom-header.ts)_
468
+ _See code: [src/commands/set-custom-header.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/set-custom-header.ts)_
390
469
 
391
470
  ## `opal set-token`
392
471
 
@@ -406,7 +485,7 @@ EXAMPLES
406
485
  $ opal set-token
407
486
  ```
408
487
 
409
- _See code: [src/commands/set-token.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/set-token.ts)_
488
+ _See code: [src/commands/set-token.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/set-token.ts)_
410
489
 
411
490
  ## `opal set-url [URL]`
412
491
 
@@ -430,7 +509,7 @@ EXAMPLES
430
509
  $ opal set-url
431
510
  ```
432
511
 
433
- _See code: [src/commands/set-url.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/set-url.ts)_
512
+ _See code: [src/commands/set-url.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/set-url.ts)_
434
513
 
435
514
  ## `opal ssh copyFrom`
436
515
 
@@ -461,7 +540,7 @@ EXAMPLES
461
540
  $ opal ssh:copyFrom --src instance/dir --dest my/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
462
541
  ```
463
542
 
464
- _See code: [src/commands/ssh/copyFrom.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/ssh/copyFrom.ts)_
543
+ _See code: [src/commands/ssh/copyFrom.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/ssh/copyFrom.ts)_
465
544
 
466
545
  ## `opal ssh copyTo`
467
546
 
@@ -492,7 +571,7 @@ EXAMPLES
492
571
  $ opal ssh:copyTo --src my/dir --dest instance/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
493
572
  ```
494
573
 
495
- _See code: [src/commands/ssh/copyTo.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/ssh/copyTo.ts)_
574
+ _See code: [src/commands/ssh/copyTo.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/ssh/copyTo.ts)_
496
575
 
497
576
  ## `opal ssh start`
498
577
 
@@ -519,7 +598,7 @@ EXAMPLES
519
598
  $ opal ssh:start --id 51f7176b-0464-4a6f-8369-e951e187b398
520
599
  ```
521
600
 
522
- _See code: [src/commands/ssh/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.03364ed/src/commands/ssh/start.ts)_
601
+ _See code: [src/commands/ssh/start.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/ssh/start.ts)_
523
602
 
524
603
  ## `opal version`
525
604
 
@@ -540,4 +619,21 @@ FLAG DESCRIPTIONS
540
619
  ```
541
620
 
542
621
  _See code: [@oclif/plugin-version](https://github.com/oclif/plugin-version/blob/v2.2.27/src/commands/version.ts)_
622
+
623
+ ## `opal whoami`
624
+
625
+ Describes current url set, organization name, and logged in user if applicable.
626
+
627
+ ```
628
+ USAGE
629
+ $ opal whoami [-h]
630
+
631
+ FLAGS
632
+ -h, --help Show CLI help.
633
+
634
+ DESCRIPTION
635
+ Describes current url set, organization name, and logged in user if applicable.
636
+ ```
637
+
638
+ _See code: [src/commands/whoami.ts](https://github.com/opalsecurity/opal-cli/blob/v3.1.1-beta.12730e0/src/commands/whoami.ts)_
543
639
  <!-- commandsstop -->
@@ -88,12 +88,14 @@ class Login extends core_1.Command {
88
88
  const configData = (0, config_1.getOrCreateConfigData)(configDir);
89
89
  let email = flags.email;
90
90
  let organizationId;
91
+ let organizationName;
91
92
  let clientIDCandidate;
92
93
  const existingCreds = await (0, credentials_1.getOpalCredentials)(this, false);
93
94
  // Only use the previous email + organizationID if email isn't explicitly specified.
94
95
  if (!email) {
95
96
  email = existingCreds.email;
96
97
  organizationId = existingCreds.organizationID;
98
+ organizationName = existingCreds.organizationName;
97
99
  clientIDCandidate = existingCreds.clientIDCandidate;
98
100
  }
99
101
  await (0, credentials_1.removeOpalCredentials)(this);
@@ -149,6 +151,7 @@ class Login extends core_1.Command {
149
151
  if (signInOrganizations && signInOrganizations.length > 0) {
150
152
  if (signInOrganizations.length === 1) {
151
153
  organizationId = signInOrganizations[0].organizationId;
154
+ organizationName = signInOrganizations[0].organizationName;
152
155
  clientIDCandidate = signInOrganizations[0].cliClientId;
153
156
  }
154
157
  else {
@@ -164,6 +167,7 @@ class Login extends core_1.Command {
164
167
  },
165
168
  ]);
166
169
  organizationId = responses.signInOrganization.organizationId;
170
+ organizationName = responses.signInOrganization.organizationName;
167
171
  clientIDCandidate = responses.signInOrganization.cliClientId;
168
172
  }
169
173
  }
@@ -238,10 +242,10 @@ class Login extends core_1.Command {
238
242
  if (tokenExchangeError) {
239
243
  this.log("WARN: Failed to exchange access token for session in Opal. Falling back to using access token for authenticating requests\n");
240
244
  // TODO: consider adding a warn line recommending upgrading Opal to version XYZ, once accompanying PR is pushed to prod
241
- await (0, credentials_1.setOpalCredentials)(this, email, organizationId !== null && organizationId !== void 0 ? organizationId : "", clientIDCandidate, (tokenSet === null || tokenSet === void 0 ? void 0 : tokenSet.access_token) || "", credentials_1.SecretType.ApiToken);
245
+ await (0, credentials_1.setOpalCredentials)(this, email, organizationId !== null && organizationId !== void 0 ? organizationId : "", clientIDCandidate, (tokenSet === null || tokenSet === void 0 ? void 0 : tokenSet.access_token) || "", credentials_1.SecretType.ApiToken, organizationName);
242
246
  }
243
247
  else {
244
- await (0, credentials_1.setOpalCredentials)(this, email, organizationId !== null && organizationId !== void 0 ? organizationId : "", clientIDCandidate, apollo_1.cookieStr, credentials_1.SecretType.Cookie);
248
+ await (0, credentials_1.setOpalCredentials)(this, email, organizationId !== null && organizationId !== void 0 ? organizationId : "", clientIDCandidate, apollo_1.cookieStr, credentials_1.SecretType.Cookie, organizationName);
245
249
  }
246
250
  // "Representative" authenticated call to check the log-in worked as expected.
247
251
  const { resp: authCheckResp, error: authCheckErr } = await (0, handler_1.runQueryDeprecated)({
@@ -1,10 +1,9 @@
1
1
  import { Command } from "@oclif/core";
2
2
  export default class RequestCreate extends Command {
3
- static hidden: boolean;
4
3
  static description: string;
5
4
  static flags: {
6
5
  help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
7
- id: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
6
+ assets: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
7
  reason: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
8
  duration: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
10
9
  };
@@ -2,20 +2,20 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const apollo_1 = require("../../lib/apollo");
5
+ const cmd_1 = require("../../lib/cmd");
5
6
  const flags_1 = require("../../lib/flags");
6
7
  const requests_1 = require("../../lib/requests");
7
8
  const displays_1 = require("../../utils/displays");
8
- const utils_1 = require("../../utils/utils");
9
9
  class RequestCreate extends core_1.Command {
10
10
  async run() {
11
+ (0, cmd_1.setMostRecentCommand)(this);
11
12
  await (0, apollo_1.initClient)(this, true);
12
13
  const client = await (0, apollo_1.getClient)(this, true);
13
- (0, utils_1.restrictToDev)(); //TODO: Remove after development is complete
14
14
  const { flags } = await this.parse(RequestCreate);
15
15
  const metadata = (0, requests_1.initEmptyRequestMetadata)();
16
- if (flags.id) {
16
+ if (flags.assets) {
17
17
  // if IDs are provided, bypass the interactive selection process
18
- await (0, requests_1.bypassRequestSelection)(this, client, flags.id, metadata);
18
+ await (0, requests_1.bypassRequestSelection)(this, client, flags.assets, metadata);
19
19
  }
20
20
  else {
21
21
  (0, displays_1.headerMessage)(this);
@@ -36,7 +36,9 @@ class RequestCreate extends core_1.Command {
36
36
  if (flags.reason) {
37
37
  metadata.reason = flags.reason;
38
38
  }
39
- else {
39
+ else if (!(metadata.requestDefaults.reasonOptional &&
40
+ flags.assets &&
41
+ flags.duration)) {
40
42
  await (0, requests_1.promptForReason)(metadata);
41
43
  }
42
44
  // Step 5: Prompt for expiration
@@ -47,21 +49,24 @@ class RequestCreate extends core_1.Command {
47
49
  await (0, requests_1.promptForExpiration)(metadata);
48
50
  }
49
51
  // Step 6: Display final summary of request
50
- if (!(flags.id && flags.reason && flags.duration)) {
51
- await (0, requests_1.promptRequestSubmission)(this, metadata);
52
+ let canSubmit = true;
53
+ if (!(flags.assets &&
54
+ flags.duration &&
55
+ (metadata.requestDefaults.reasonOptional || flags.reason))) {
56
+ canSubmit = await (0, requests_1.promptRequestSubmission)(this, metadata);
52
57
  }
53
58
  // Step 7: Prompt for final submission
54
- await (0, requests_1.submitFinalRequest)(this, client, metadata);
59
+ if (canSubmit)
60
+ await (0, requests_1.submitFinalRequest)(this, client, metadata);
55
61
  }
56
62
  }
57
- RequestCreate.hidden = true;
58
63
  RequestCreate.description = "Creates an Opal access request via an interactive form";
59
64
  RequestCreate.flags = {
60
65
  help: flags_1.SHARED_FLAGS.help,
61
- id: core_1.Flags.string({
62
- char: "i",
66
+ assets: core_1.Flags.string({
67
+ char: "a",
63
68
  multiple: true,
64
- description: "The id of the asset (resource, group) to request access to. Append a role ID using a colon if needed, e.g. `--id 123:456`.\
69
+ description: "The ids of the assets (resource, group) to request access to. Append a role ID using a colon if needed, e.g. `--assets 123:456`.\
65
70
  \n If not provided, an interactive selection flow will be available to select assets to request.",
66
71
  }),
67
72
  reason: core_1.Flags.string({
@@ -1,6 +1,5 @@
1
1
  import { Command } from "@oclif/core";
2
2
  export default class GetRequest extends Command {
3
- static hidden: boolean;
4
3
  static description: string;
5
4
  static flags: {
6
5
  help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
@@ -8,7 +8,6 @@ const cmd_1 = require("../../lib/cmd");
8
8
  const config_1 = require("../../lib/config");
9
9
  const flags_1 = require("../../lib/flags");
10
10
  const displays_1 = require("../../utils/displays");
11
- const utils_1 = require("../../utils/utils");
12
11
  const GET_REQUEST = (0, graphql_1.graphql)(`
13
12
  query GetRequest(
14
13
  $id: RequestId!
@@ -58,14 +57,13 @@ const GET_REQUEST = (0, graphql_1.graphql)(`
58
57
  `);
59
58
  class GetRequest extends core_1.Command {
60
59
  async run() {
61
- (0, utils_1.restrictToDev)(); //TODO: Remove after development is complete
62
60
  (0, cmd_1.setMostRecentCommand)(this);
63
61
  const configData = (0, config_1.getOrCreateConfigData)(this.config.configDir);
64
62
  const client = await (0, apollo_1.getClient)(this, true);
65
63
  // Verify id tag was provided
66
64
  const { flags } = await this.parse(GetRequest);
67
65
  if (!flags.id) {
68
- this.log("Error: Please provide a group ID using the --id flag.");
66
+ this.log("Error: Please provide a request ID using the --id flag.");
69
67
  this.log("ex. opal request get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4");
70
68
  return;
71
69
  }
@@ -96,7 +94,6 @@ class GetRequest extends core_1.Command {
96
94
  }
97
95
  }
98
96
  }
99
- GetRequest.hidden = true;
100
97
  GetRequest.description = "Lists access requests";
101
98
  GetRequest.flags = {
102
99
  help: flags_1.SHARED_FLAGS.help,
@@ -1,6 +1,5 @@
1
1
  import { Command } from "@oclif/core";
2
2
  export default class ListRequests extends Command {
3
- static hidden: boolean;
4
3
  static description: string;
5
4
  static examples: string[];
6
5
  static flags: {
@@ -6,7 +6,6 @@ const apollo_1 = require("../../lib/apollo");
6
6
  const cmd_1 = require("../../lib/cmd");
7
7
  const flags_1 = require("../../lib/flags");
8
8
  const displays_1 = require("../../utils/displays");
9
- const utils_1 = require("../../utils/utils");
10
9
  // Add date filters, search query,
11
10
  const GET_REQUESTS = (0, graphql_1.graphql)(`
12
11
  query GetRequests($pageSize: Int, $showPendingOnly: Boolean!) {
@@ -59,7 +58,6 @@ const GET_REQUESTS = (0, graphql_1.graphql)(`
59
58
  }`);
60
59
  class ListRequests extends core_1.Command {
61
60
  async run() {
62
- (0, utils_1.restrictToDev)(); //TODO: Remove after development is complete
63
61
  (0, cmd_1.setMostRecentCommand)(this);
64
62
  const client = await (0, apollo_1.getClient)(this, true);
65
63
  let pageSize = 10;
@@ -88,7 +86,6 @@ class ListRequests extends core_1.Command {
88
86
  }
89
87
  }
90
88
  }
91
- ListRequests.hidden = true;
92
89
  ListRequests.description = "Lists your n recent outgoing access requests";
93
90
  ListRequests.examples = [
94
91
  "opal request list --n 5",
@@ -0,0 +1,8 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class WhoAmI extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
6
+ };
7
+ run(): Promise<void>;
8
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const config_1 = require("../lib/config");
5
+ const credentials_1 = require("../lib/credentials");
6
+ const flags_1 = require("../lib/flags");
7
+ class WhoAmI extends core_1.Command {
8
+ async run() {
9
+ const opalCreds = await (0, credentials_1.getOpalCredentials)(this, false);
10
+ const organizationName = opalCreds === null || opalCreds === void 0 ? void 0 : opalCreds.organizationName;
11
+ const email = opalCreds === null || opalCreds === void 0 ? void 0 : opalCreds.email;
12
+ const configData = (0, config_1.getOrCreateConfigData)(this.config.configDir);
13
+ const url = configData[config_1.urlKey];
14
+ if (email) {
15
+ this.log(`User: ${email}`);
16
+ }
17
+ if (organizationName) {
18
+ if (organizationName === "unset-org-id") {
19
+ this.log("Authenticated with Opal API Token.");
20
+ }
21
+ else {
22
+ this.log(`Organization: ${organizationName}`);
23
+ }
24
+ }
25
+ if (url) {
26
+ this.log(`Server: ${url}`);
27
+ }
28
+ }
29
+ }
30
+ WhoAmI.description = "Describes current url set, organization name, and logged in user if applicable.";
31
+ WhoAmI.flags = {
32
+ help: flags_1.SHARED_FLAGS.help,
33
+ };
34
+ exports.default = WhoAmI;
package/lib/lib/apollo.js CHANGED
@@ -155,7 +155,7 @@ const initClient = async (command, fetchAccessToken = true) => {
155
155
  return response;
156
156
  });
157
157
  });
158
- const errorLink = (0, error_1.onError)(({ networkError, operation }) => {
158
+ const errorLink = (0, error_1.onError)(({ networkError, operation, forward }) => {
159
159
  var _a;
160
160
  // There's a few GQL operations where we don't want to use this error handler:
161
161
  const customErrorOperations = [
@@ -186,7 +186,7 @@ const initClient = async (command, fetchAccessToken = true) => {
186
186
  case 401: {
187
187
  command.log("Your session is invalid or expired. Authenticating now...\n");
188
188
  const loginCommand = new login_1.default([], command.config);
189
- loginCommand.run().then(() => {
189
+ return (0, core_1.fromPromise)(loginCommand.run().then(() => {
190
190
  if (cmd_1.mostRecentCommandTime && cmd_1.mostRecentCommand) {
191
191
  const lastCommandReexecutionDuration = moment.duration(2, "minutes");
192
192
  const lastCommandReexecutionDurationHasElapsed = cmd_1.mostRecentCommandTime.add(lastCommandReexecutionDuration) >
@@ -195,8 +195,7 @@ const initClient = async (command, fetchAccessToken = true) => {
195
195
  cmd_1.mostRecentCommand.run();
196
196
  }
197
197
  }
198
- });
199
- break;
198
+ })).flatMap(() => forward(operation));
200
199
  }
201
200
  default:
202
201
  return (0, exports.handleError)(command, `Received status code ${networkError.statusCode} from server${errorMessage ? ` with message "${errorMessage}"` : ""}`);
@@ -5,12 +5,13 @@ interface OpalCredentials {
5
5
  clientIDCandidate?: string;
6
6
  secret?: string;
7
7
  secretType?: SecretType;
8
+ organizationName?: string;
8
9
  }
9
10
  export declare enum SecretType {
10
11
  Cookie = "COOKIE",
11
12
  ApiToken = "API_TOKEN"
12
13
  }
13
- export declare const setOpalCredentials: (command: Command, email: string | undefined, organizationID: string, clientIDCandidate: string | undefined | null, secret: string, secretType: SecretType) => Promise<void>;
14
+ export declare const setOpalCredentials: (command: Command, email: string | undefined, organizationID: string, clientIDCandidate: string | undefined | null, secret: string, secretType: SecretType, organizationName?: string) => Promise<void>;
14
15
  export declare const getOpalCredentials: (command: Command, includeAuthSecret?: boolean) => Promise<OpalCredentials>;
15
16
  export declare const removeOpalCredentials: (command: Command) => Promise<void>;
16
17
  export {};
@@ -9,13 +9,14 @@ var SecretType;
9
9
  SecretType["Cookie"] = "COOKIE";
10
10
  SecretType["ApiToken"] = "API_TOKEN";
11
11
  })(SecretType || (exports.SecretType = SecretType = {}));
12
- const setOpalCredentials = async (command, email, organizationID, clientIDCandidate, secret, secretType) => {
12
+ const setOpalCredentials = async (command, email, organizationID, clientIDCandidate, secret, secretType, organizationName) => {
13
13
  const givenEmail = email || "email-unset";
14
14
  const configData = (0, config_1.getOrCreateConfigData)(command.config.configDir);
15
15
  configData.creds = {
16
16
  clientIDCandidate,
17
17
  email,
18
18
  organizationID,
19
+ organizationName,
19
20
  secretType,
20
21
  };
21
22
  (0, config_1.writeConfigData)(command.config.configDir, configData);
@@ -19,6 +19,7 @@ type RoleNode = {
19
19
  roleName: string;
20
20
  };
21
21
  export type RequestMap = Record<string, AppNode>;
22
+ export declare const DISPLAY_LABELS: Partial<Record<EntityType, string>>;
22
23
  type DurationOption = {
23
24
  durationInMinutes: number;
24
25
  label: string;
@@ -45,7 +46,7 @@ export declare function doneSelectingAssets(): Promise<boolean>;
45
46
  export declare function setRequestDefaults(cmd: Command, client: ApolloClient<NormalizedCacheObject>, metadata: RequestMetadata): Promise<void>;
46
47
  export declare function promptForReason(metadata: RequestMetadata): Promise<void>;
47
48
  export declare function promptForExpiration(metadata: RequestMetadata): Promise<void>;
48
- export declare function promptRequestSubmission(cmd: Command, metadata: RequestMetadata): Promise<void>;
49
+ export declare function promptRequestSubmission(cmd: Command, metadata: RequestMetadata): Promise<boolean>;
49
50
  export declare function submitFinalRequest(cmd: Command, client: ApolloClient<NormalizedCacheObject>, metadata: RequestMetadata): Promise<void>;
50
51
  export declare function bypassRequestSelection(cmd: Command, client: ApolloClient<NormalizedCacheObject>, flagValue: string[], metadata: RequestMetadata): Promise<void>;
51
52
  export declare function bypassDuration(cmd: Command, duration: number, metadata: RequestMetadata): void;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DISPLAY_LABELS = void 0;
3
4
  exports.initEmptyRequestMetadata = initEmptyRequestMetadata;
4
5
  exports.selectRequestableItems = selectRequestableItems;
5
6
  exports.doneSelectingAssets = doneSelectingAssets;
@@ -11,22 +12,26 @@ exports.submitFinalRequest = submitFinalRequest;
11
12
  exports.bypassRequestSelection = bypassRequestSelection;
12
13
  exports.bypassDuration = bypassDuration;
13
14
  const chalk_1 = require("chalk");
14
- const inquirer = require("inquirer");
15
15
  const graphql_1 = require("../graphql");
16
16
  const graphql_2 = require("../graphql/graphql");
17
17
  const displays_1 = require("../utils/displays");
18
18
  const config_1 = require("./config");
19
19
  const { AutoComplete, Select, prompt, Form } = require("enquirer");
20
20
  function entityTypeFromString(str) {
21
- if (str === "Resource") {
21
+ const capStr = str === null || str === void 0 ? void 0 : str.toLocaleUpperCase();
22
+ if (capStr === "RESOURCE") {
22
23
  return graphql_2.EntityType.Resource;
23
24
  }
24
- if (str === "Group") {
25
+ if (capStr === "GROUP") {
25
26
  return graphql_2.EntityType.Group;
26
27
  }
27
28
  // if type unknown, default to resource
28
29
  return graphql_2.EntityType.Resource;
29
30
  }
31
+ exports.DISPLAY_LABELS = {
32
+ [graphql_2.EntityType.Resource]: "Resource",
33
+ [graphql_2.EntityType.Group]: "Group",
34
+ };
30
35
  function initEmptyRequestMetadata() {
31
36
  // Initialize with empty defaults
32
37
  const requestDefaults = {
@@ -179,7 +184,7 @@ async function queryRequestableAssets(cmd, client, appId, input) {
179
184
  value: {
180
185
  name: name || "",
181
186
  id: id || "",
182
- type: ((_g = item.resource) === null || _g === void 0 ? void 0 : _g.__typename) || ((_h = item.group) === null || _h === void 0 ? void 0 : _h.__typename) || "",
187
+ type: entityTypeFromString(((_g = item.resource) === null || _g === void 0 ? void 0 : _g.__typename) || ((_h = item.group) === null || _h === void 0 ? void 0 : _h.__typename)),
183
188
  },
184
189
  };
185
190
  });
@@ -238,7 +243,7 @@ async function queryAssetRoles(cmd, client, assetType, assetId) {
238
243
  var _a, _b, _c, _d, _e, _f, _g, _h;
239
244
  try {
240
245
  switch (assetType) {
241
- case "Resource": {
246
+ case graphql_2.EntityType.Resource: {
242
247
  const resp = await client.query({
243
248
  query: RESOURCE_ROLES_QUERY,
244
249
  variables: {
@@ -267,7 +272,7 @@ async function queryAssetRoles(cmd, client, assetType, assetId) {
267
272
  }
268
273
  return;
269
274
  }
270
- case "Group": {
275
+ case graphql_2.EntityType.Group: {
271
276
  const resp = await client.query({
272
277
  query: GROUP_ROLES_QUERY,
273
278
  variables: {
@@ -623,8 +628,8 @@ async function queryAssociatedItems(cmd, client, id, input) {
623
628
  }
624
629
  }
625
630
  // Helper functions
626
- const selectInstructions = chalk_1.default.dim("↑↓ Navigate · Enter Select · Type to filter");
627
- const multiSelectInstructions = chalk_1.default.dim("↑↓ Navigate · Space Select · Enter Confirm · Type to filter");
631
+ const selectInstructions = chalk_1.default.dim("[↑↓] Navigate · [Enter] Select · Type to filter");
632
+ const multiSelectInstructions = chalk_1.default.dim("[↑↓] Navigate · [Space] Select · [Enter] Confirm · Type to filter");
628
633
  async function selectRequestableItems(cmd, client, requestMap) {
629
634
  const initial = (await queryRequestableApps(cmd, client, "")) || [];
630
635
  const appPrompt = new AutoComplete({
@@ -669,7 +674,7 @@ async function chooseOktaAzureRoles(cmd, client, app, requestMap) {
669
674
  },
670
675
  validate: (answer) => {
671
676
  if (answer.length !== 1) {
672
- return "You must select only one item.";
677
+ return "Only one role is allowed to be requested for on Okta or Azure apps.";
673
678
  }
674
679
  return true;
675
680
  },
@@ -697,7 +702,7 @@ function appRolesFromEdge(edge) {
697
702
  value: {
698
703
  id: edge.node.id + accessLevel.accessLevelRemoteId,
699
704
  name: accessLevel.accessLevelName,
700
- type: graphql_2.EntityType.Resource,
705
+ type: exports.DISPLAY_LABELS[graphql_2.EntityType.Resource],
701
706
  toString: () => accessLevel.accessLevelName,
702
707
  },
703
708
  }));
@@ -708,7 +713,7 @@ function appRolesFromEdge(edge) {
708
713
  value: {
709
714
  id: edge.node.id,
710
715
  name: (_b = edge.alias) !== null && _b !== void 0 ? _b : edge.node.name,
711
- type: graphql_2.EntityType.Resource,
716
+ type: exports.DISPLAY_LABELS[graphql_2.EntityType.Resource],
712
717
  toString: () => { var _a; return (_a = edge.alias) !== null && _a !== void 0 ? _a : edge.node.name; },
713
718
  },
714
719
  },
@@ -717,11 +722,11 @@ function appRolesFromEdge(edge) {
717
722
  case "Group":
718
723
  return [
719
724
  {
720
- message: (_c = edge.alias) !== null && _c !== void 0 ? _c : edge.node.name,
725
+ message: `${(_c = edge.alias) !== null && _c !== void 0 ? _c : edge.node.name} ${graphql_2.EntityType.Group}`,
721
726
  value: {
722
727
  id: edge.node.id,
723
728
  name: (_d = edge.alias) !== null && _d !== void 0 ? _d : edge.node.name,
724
- type: graphql_2.EntityType.Group,
729
+ type: exports.DISPLAY_LABELS[graphql_2.EntityType.Group],
725
730
  toString: () => { var _a; return (_a = edge.alias) !== null && _a !== void 0 ? _a : edge.node.name; },
726
731
  },
727
732
  },
@@ -913,6 +918,7 @@ async function promptForExpiration(metadata) {
913
918
  const expirationSelect = new AutoComplete({
914
919
  name: "expiration",
915
920
  message: "When should access expire?",
921
+ hint: "Type to filter",
916
922
  type: "list",
917
923
  choices: durations,
918
924
  pageSize: 15,
@@ -1000,26 +1006,13 @@ async function promptRequestSubmission(cmd, metadata) {
1000
1006
  (0, displays_1.displayFinalRequestSummary)(cmd, metadata);
1001
1007
  const submitMessage = "✅ Yes, submit request";
1002
1008
  const cancelMessage = "❌ No, cancel request";
1003
- const { submit } = await inquirer.prompt([
1004
- {
1005
- name: "submit",
1006
- message: "Submit request?",
1007
- type: "list",
1008
- choices: [submitMessage, cancelMessage],
1009
- },
1010
- ]);
1011
- switch (submit) {
1012
- case submitMessage: {
1013
- return;
1014
- }
1015
- case cancelMessage: {
1016
- cmd.log("🚫 Access Request has been cancelled.");
1017
- return;
1018
- }
1019
- default: {
1020
- cmd.error("Unknown error occurred.");
1021
- }
1022
- }
1009
+ const prompt = new Select({
1010
+ name: "submitOrCancel",
1011
+ message: "Is this all you want to request?",
1012
+ choices: [submitMessage, cancelMessage],
1013
+ });
1014
+ const submitOrCancel = await prompt.run();
1015
+ return submitOrCancel === submitMessage;
1023
1016
  }
1024
1017
  async function submitFinalRequest(cmd, client, metadata) {
1025
1018
  var _a, _b, _c, _d;
@@ -1078,11 +1071,13 @@ async function submitFinalRequest(cmd, client, metadata) {
1078
1071
  return;
1079
1072
  }
1080
1073
  async function bypassRequestSelection(cmd, client, flagValue, metadata) {
1081
- var _a, _b, _c, _d;
1074
+ var _a, _b;
1082
1075
  try {
1083
1076
  // Query Catalog Item endpoint to identify what the id belongs to (resource or group)
1084
- for (const id of flagValue) {
1085
- const [assetId, roleName] = id.split(":");
1077
+ for (const val of flagValue) {
1078
+ const delimiterIndex = val.indexOf(":");
1079
+ const assetId = val.substring(0, delimiterIndex);
1080
+ const roleName = val.substring(delimiterIndex + 1);
1086
1081
  const resp = await client.query({
1087
1082
  query: CATALOG_ITEM,
1088
1083
  variables: {
@@ -1091,28 +1086,30 @@ async function bypassRequestSelection(cmd, client, flagValue, metadata) {
1091
1086
  fetchPolicy: "network-only", // to avoid caching
1092
1087
  });
1093
1088
  switch (resp.data.catalogItem.__typename) {
1089
+ case "Group":
1094
1090
  case "Resource": {
1095
- const resourceName = resp.data.catalogItem.displayName;
1096
- const requestableRoles = (resp.data.catalogItem.accessLevels || [])
1091
+ const item = resp.data.catalogItem;
1092
+ const assetName = item.__typename === "Resource" ? item.displayName : item.name;
1093
+ const requestableRoles = (item.accessLevels || [])
1097
1094
  // TODO: Support okta azure apps ?.filter((role) => role.accessLevelName !== "") // This assumes length == 1
1098
1095
  .map((role) => ({
1099
1096
  id: role.accessLevelRemoteId,
1100
1097
  name: role.accessLevelName,
1101
1098
  }));
1102
- const appId = ((_a = resp.data.catalogItem.connection) === null || _a === void 0 ? void 0 : _a.id) || "";
1099
+ const appId = ((_a = item.connection) === null || _a === void 0 ? void 0 : _a.id) || "";
1103
1100
  if (!(appId in metadata.requestMap)) {
1104
1101
  metadata.requestMap[appId] = {
1105
- appName: ((_b = resp.data.catalogItem.connection) === null || _b === void 0 ? void 0 : _b.displayName) || "",
1102
+ appName: ((_b = item.connection) === null || _b === void 0 ? void 0 : _b.displayName) || "",
1106
1103
  appId: appId,
1107
1104
  assets: {},
1108
1105
  };
1109
1106
  }
1110
- const assetEntry = metadata.requestMap[appId].assets[id];
1107
+ const assetEntry = metadata.requestMap[appId].assets[assetId];
1111
1108
  if (!assetEntry) {
1112
1109
  metadata.requestMap[appId].assets[assetId] = {
1113
1110
  assetId: assetId,
1114
- assetName: resourceName,
1115
- type: graphql_2.EntityType.Resource,
1111
+ assetName: assetName,
1112
+ type: entityTypeFromString(item.__typename),
1116
1113
  roles: {},
1117
1114
  };
1118
1115
  }
@@ -1129,54 +1126,13 @@ async function bypassRequestSelection(cmd, client, flagValue, metadata) {
1129
1126
  };
1130
1127
  }
1131
1128
  else {
1132
- cmd.error(`Access level specified does not match one of ${resourceName}'s defined access levels:${requestableRoles.map((role) => role.name)}`);
1133
- }
1134
- }
1135
- break;
1136
- }
1137
- case "Group": {
1138
- const groupName = resp.data.catalogItem.name;
1139
- const roles = (resp.data.catalogItem.accessLevels || []).map((role) => ({
1140
- id: role.accessLevelRemoteId,
1141
- name: role.accessLevelName,
1142
- }));
1143
- if (roles.length > 0 &&
1144
- !(roles.length === 1 && roles[0].name === "")) {
1145
- cmd.log(`Roles not implemented yet for group ${groupName}. Skipping roles selection.`); //TODO: Implement group roles support
1146
- continue;
1147
- }
1148
- const appId = ((_c = resp.data.catalogItem.connection) === null || _c === void 0 ? void 0 : _c.id) || "";
1149
- if (!(appId in metadata.requestMap)) {
1150
- metadata.requestMap[appId] = {
1151
- appName: ((_d = resp.data.catalogItem.connection) === null || _d === void 0 ? void 0 : _d.displayName) || "",
1152
- appId: appId,
1153
- assets: {},
1154
- };
1155
- }
1156
- const assetEntry = metadata.requestMap[appId].assets[id];
1157
- if (!assetEntry) {
1158
- metadata.requestMap[appId].assets[id] = {
1159
- assetId: id,
1160
- assetName: groupName,
1161
- type: graphql_2.EntityType.Group,
1162
- roles: {},
1163
- };
1164
- }
1165
- if (roles) {
1166
- if (!metadata.requestMap[appId].assets[id].roles) {
1167
- metadata.requestMap[appId].assets[id].roles = {};
1168
- }
1169
- for (const role of roles) {
1170
- metadata.requestMap[appId].assets[id].roles[role.id] = {
1171
- roleId: role.id,
1172
- roleName: role.name,
1173
- };
1129
+ cmd.error(`Access level specified does not match one of ${assetName}'s defined access levels: ${requestableRoles.map((role) => `"${role.name}"`)}`);
1174
1130
  }
1175
1131
  }
1176
1132
  break;
1177
1133
  }
1178
1134
  default:
1179
- cmd.error("Invad asset id was passed in using the --id flag.");
1135
+ cmd.error("Invalid asset id was passed in using the --id flag.");
1180
1136
  }
1181
1137
  }
1182
1138
  }
@@ -1,7 +1,7 @@
1
1
  import type { ApolloQueryResult } from "@apollo/client";
2
2
  import type { Command } from "@oclif/core/lib/command";
3
3
  import type { GetRequestQuery, GetRequestsQuery } from "../graphql/graphql";
4
- import type { RequestMap, RequestMetadata } from "../lib/requests";
4
+ import { type RequestMap, type RequestMetadata } from "../lib/requests";
5
5
  export declare function headerMessage(cmd: Command): void;
6
6
  export declare function treeifyRequestMap(cmd: Command, requestMap: RequestMap): void;
7
7
  export declare function displayFinalRequestSummary(cmd: Command, metadata: RequestMetadata): void;
@@ -7,6 +7,7 @@ exports.getStyledStatus = getStyledStatus;
7
7
  exports.displayRequestDetails = displayRequestDetails;
8
8
  exports.displayRequestListTable = displayRequestListTable;
9
9
  const chalk_1 = require("chalk");
10
+ const requests_1 = require("../lib/requests");
10
11
  const Table = require("cli-table3");
11
12
  const treeify = require("object-treeify").default;
12
13
  function headerMessage(cmd) {
@@ -30,7 +31,7 @@ function treeifyRequestMap(cmd, requestMap) {
30
31
  for (const [_assetId, assetNode] of Object.entries(appNode.assets)) {
31
32
  // If okta/azure asset with no role, change asset name
32
33
  const assetName = assetNode.assetName || "No Role (Direct access)";
33
- const assetKey = `${assetName} ${chalk_1.default.dim(`[${assetNode.type}]`)}`;
34
+ const assetKey = `${assetName} ${chalk_1.default.dim(`[${requests_1.DISPLAY_LABELS[assetNode.type]}]`)}`;
34
35
  if (assetNode.roles !== undefined) {
35
36
  assetsTree[assetKey] = {};
36
37
  for (const [_roleId, roleNode] of Object.entries(assetNode.roles)) {
@@ -316,6 +316,34 @@
316
316
  "set-url.js"
317
317
  ]
318
318
  },
319
+ "whoami": {
320
+ "aliases": [],
321
+ "args": {},
322
+ "description": "Describes current url set, organization name, and logged in user if applicable.",
323
+ "flags": {
324
+ "help": {
325
+ "char": "h",
326
+ "description": "Show CLI help.",
327
+ "name": "help",
328
+ "allowNo": false,
329
+ "type": "boolean"
330
+ }
331
+ },
332
+ "hasDynamicHelp": false,
333
+ "hiddenAliases": [],
334
+ "id": "whoami",
335
+ "pluginAlias": "opal-security",
336
+ "pluginName": "opal-security",
337
+ "pluginType": "core",
338
+ "strict": true,
339
+ "enableJsonFlag": false,
340
+ "isESM": false,
341
+ "relativePath": [
342
+ "lib",
343
+ "commands",
344
+ "whoami.js"
345
+ ]
346
+ },
319
347
  "aws:identity": {
320
348
  "aliases": [],
321
349
  "args": {},
@@ -606,10 +634,10 @@
606
634
  "allowNo": false,
607
635
  "type": "boolean"
608
636
  },
609
- "id": {
610
- "char": "i",
611
- "description": "The id of the asset (resource, group) to request access to. Append a role ID using a colon if needed, e.g. `--id 123:456`. \n If not provided, an interactive selection flow will be available to select assets to request.",
612
- "name": "id",
637
+ "assets": {
638
+ "char": "a",
639
+ "description": "The ids of the assets (resource, group) to request access to. Append a role ID using a colon if needed, e.g. `--assets 123:456`. \n If not provided, an interactive selection flow will be available to select assets to request.",
640
+ "name": "assets",
613
641
  "hasDynamicHelp": false,
614
642
  "multiple": true,
615
643
  "type": "option"
@@ -632,7 +660,6 @@
632
660
  }
633
661
  },
634
662
  "hasDynamicHelp": false,
635
- "hidden": true,
636
663
  "hiddenAliases": [],
637
664
  "id": "request:create",
638
665
  "pluginAlias": "opal-security",
@@ -681,7 +708,6 @@
681
708
  }
682
709
  },
683
710
  "hasDynamicHelp": false,
684
- "hidden": true,
685
711
  "hiddenAliases": [],
686
712
  "id": "request:get",
687
713
  "pluginAlias": "opal-security",
@@ -740,7 +766,6 @@
740
766
  }
741
767
  },
742
768
  "hasDynamicHelp": false,
743
- "hidden": true,
744
769
  "hiddenAliases": [],
745
770
  "id": "request:list",
746
771
  "pluginAlias": "opal-security",
@@ -1003,5 +1028,5 @@
1003
1028
  ]
1004
1029
  }
1005
1030
  },
1006
- "version": "3.1.1-beta.03364ed"
1031
+ "version": "3.1.1-beta.12730e0"
1007
1032
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opal-security",
3
3
  "description": "Opal allows you to centrally manage access to all of your sensitive systems.",
4
- "version": "3.1.1-beta.03364ed",
4
+ "version": "3.1.1-beta.12730e0",
5
5
  "author": "Stephen Cobbe",
6
6
  "bin": {
7
7
  "opal": "./bin/run"
@@ -63,9 +63,7 @@
63
63
  "/scripts"
64
64
  ],
65
65
  "homepage": "https://github.com/opalsecurity/opal-cli/",
66
- "keywords": [
67
- "oclif"
68
- ],
66
+ "keywords": ["oclif"],
69
67
  "license": "MIT",
70
68
  "main": "lib/index.js",
71
69
  "oclif": {
@@ -91,7 +89,7 @@
91
89
  "prepack": "npm run build && oclif manifest && oclif readme",
92
90
  "test": "vitest",
93
91
  "coverage": "vitest run --coverage",
94
- "version": "oclif readme && git add README.md",
92
+ "version": "oclif readme && git add README.md && biome check --write",
95
93
  "posttest": "biome check",
96
94
  "biome-ci": "biome ci --reporter=github",
97
95
  "gql-codegen": "graphql-codegen",