opal-security 3.1.1-beta.e5e99da → 3.1.1-beta.f2bce00

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.
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.headerMessage = headerMessage;
4
4
  exports.treeifyRequestMap = treeifyRequestMap;
5
5
  exports.displayFinalRequestSummary = displayFinalRequestSummary;
6
+ exports.displayRequestDetails = displayRequestDetails;
7
+ exports.displayRequestList = displayRequestList;
8
+ const chalk_1 = require("chalk");
6
9
  const treeify = require("object-treeify");
7
10
  const Table = require("cli-table3");
8
11
  const tableStyle = {
@@ -24,7 +27,7 @@ const tableStyle = {
24
27
  };
25
28
  function headerMessage(cmd) {
26
29
  console.clear();
27
- cmd.log("============================================================");
30
+ cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
28
31
  cmd.log("Opal Access Request ✏️");
29
32
  cmd.log("Press Ctrl+C to cancel at any time.\n");
30
33
  }
@@ -63,3 +66,152 @@ function displayFinalRequestSummary(cmd, requestMap, reason, expiration) {
63
66
  table.push(["Requested Assets", requestedAssets], ["Reason", reason], ["Expiration", expiration]);
64
67
  cmd.log(table.toString());
65
68
  }
69
+ function displayRequestDetails(cmd, requestResp) {
70
+ var _a, _b, _c, _d, _e, _f;
71
+ switch (requestResp.data.request.__typename) {
72
+ case "RequestResult": {
73
+ cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
74
+ cmd.log(`Request Details ${chalk_1.default.cyan(requestResp.data.request.request.id)}`);
75
+ cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
76
+ const status = requestResp.data.request.request.status;
77
+ switch (status) {
78
+ case "PENDING": {
79
+ cmd.log(`${chalk_1.default.bold("Status:")} ${chalk_1.default.blueBright(status)}`);
80
+ break;
81
+ }
82
+ case "APPROVED": {
83
+ cmd.log(`${chalk_1.default.bold("Status:")} ${chalk_1.default.greenBright(status)}`);
84
+ break;
85
+ }
86
+ case "DENIED": {
87
+ cmd.log(`${chalk_1.default.bold("Status:")} ${chalk_1.default.redBright(status)}`);
88
+ break;
89
+ }
90
+ case "CANCELED": {
91
+ cmd.log(`${chalk_1.default.bold("Status:")} ${chalk_1.default.redBright(status)}`);
92
+ break;
93
+ }
94
+ }
95
+ // Request users "Requested by: <requester> -> Requested for: <targetUser>"
96
+ const requester = (_a = requestResp.data.request.request.requester) === null || _a === void 0 ? void 0 : _a.displayName;
97
+ const targetUser = (_b = requestResp.data.request.request.targetUser) === null || _b === void 0 ? void 0 : _b.displayName;
98
+ if (requester && targetUser) {
99
+ cmd.log(`${chalk_1.default.bold("Requested by:")} ${requester} ${chalk_1.default.gray("->")} ${chalk_1.default.bold("Requested for:")} ${targetUser}`);
100
+ }
101
+ const durationInMinutes = requestResp.data.request.request.durationInMinutes;
102
+ if (durationInMinutes) {
103
+ cmd.log(`${chalk_1.default.bold("Duration:")} ${formatDuration(durationInMinutes)}`);
104
+ }
105
+ const reason = requestResp.data.request.request.reason;
106
+ if (reason) {
107
+ cmd.log(`${chalk_1.default.bold("Reason:")} "${chalk_1.default.italic(reason)}"`);
108
+ }
109
+ // Requested resources
110
+ const requestedResources = (_d = (_c = requestResp.data.request.request.requestedResources) === null || _c === void 0 ? void 0 : _c.map((resource) => {
111
+ var _a, _b, _c;
112
+ if (((_a = resource.resource) === null || _a === void 0 ? void 0 : _a.__typename) === "Resource") {
113
+ return formatAssetName((_b = resource.resource) === null || _b === void 0 ? void 0 : _b.displayName, ((_c = resource.accessLevel) === null || _c === void 0 ? void 0 : _c.accessLevelName) || "");
114
+ }
115
+ })) !== null && _d !== void 0 ? _d : [];
116
+ const requestedGroups = (_f = (_e = requestResp.data.request.request.requestedGroups) === null || _e === void 0 ? void 0 : _e.map((group) => {
117
+ var _a, _b, _c;
118
+ if (((_a = group.group) === null || _a === void 0 ? void 0 : _a.__typename) === "Group") {
119
+ return formatAssetName((_b = group.group) === null || _b === void 0 ? void 0 : _b.name, ((_c = group.accessLevel) === null || _c === void 0 ? void 0 : _c.accessLevelName) || "");
120
+ }
121
+ })) !== null && _f !== void 0 ? _f : [];
122
+ const requestedItems = [...requestedResources, ...requestedGroups].join(", ");
123
+ if (requestedItems) {
124
+ cmd.log(`${chalk_1.default.bold("Requested Items:")} ${chalk_1.default.cyan(requestedItems)}`);
125
+ }
126
+ }
127
+ }
128
+ }
129
+ function displayRequestList(cmd, requestResp) {
130
+ var _a, _b, _c, _d, _e;
131
+ switch (requestResp.data.requests.__typename) {
132
+ case "RequestsResult": {
133
+ const requests = requestResp.data.requests.requests;
134
+ if (requests && requests.length > 0) {
135
+ const table = new Table({
136
+ chars: tableStyle,
137
+ head: [
138
+ "Request ID",
139
+ "Status",
140
+ "For",
141
+ "Duration",
142
+ "Requested Items",
143
+ "Reason",
144
+ ],
145
+ colWidths: [null, null, 20, null, 30, 20],
146
+ wordWrap: true,
147
+ wrapOnWordBoundary: false,
148
+ });
149
+ for (const request of requests) {
150
+ const targetUser = (_a = request.targetUser) === null || _a === void 0 ? void 0 : _a.displayName;
151
+ const reason = request.reason;
152
+ const status = request.status;
153
+ let formattedDuration = "";
154
+ if (request.durationInMinutes) {
155
+ formattedDuration = formatDuration(request.durationInMinutes);
156
+ }
157
+ const requestedResources = (_c = (_b = request.requestedResources) === null || _b === void 0 ? void 0 : _b.map((resource) => {
158
+ var _a, _b, _c;
159
+ if (((_a = resource.resource) === null || _a === void 0 ? void 0 : _a.__typename) === "Resource") {
160
+ return formatAssetName((_b = resource.resource) === null || _b === void 0 ? void 0 : _b.displayName, ((_c = resource.accessLevel) === null || _c === void 0 ? void 0 : _c.accessLevelName) || "");
161
+ }
162
+ })) !== null && _c !== void 0 ? _c : [];
163
+ const requestedGroups = (_e = (_d = request.requestedGroups) === null || _d === void 0 ? void 0 : _d.map((group) => {
164
+ var _a, _b, _c;
165
+ if (((_a = group.group) === null || _a === void 0 ? void 0 : _a.__typename) === "Group") {
166
+ return formatAssetName((_b = group.group) === null || _b === void 0 ? void 0 : _b.name, ((_c = group.accessLevel) === null || _c === void 0 ? void 0 : _c.accessLevelName) || "");
167
+ }
168
+ })) !== null && _e !== void 0 ? _e : [];
169
+ const requestedItems = [
170
+ ...requestedResources,
171
+ ...requestedGroups,
172
+ ].join(", ");
173
+ table.push([
174
+ request.id,
175
+ status,
176
+ targetUser,
177
+ formattedDuration,
178
+ requestedItems,
179
+ reason,
180
+ ]);
181
+ }
182
+ cmd.log(table.toString());
183
+ }
184
+ else {
185
+ cmd.log("No requests found.");
186
+ }
187
+ return;
188
+ }
189
+ default: {
190
+ cmd.log("No requests found.");
191
+ }
192
+ }
193
+ }
194
+ function formatDuration(durationInMinutes) {
195
+ const days = Math.floor(durationInMinutes / 1440);
196
+ const remainingMinutes = durationInMinutes % 1440;
197
+ const hours = Math.floor(remainingMinutes / 60);
198
+ const minutes = remainingMinutes % 60;
199
+ let durationStr = "";
200
+ if (days > 0)
201
+ durationStr += `${days}d`;
202
+ if (hours > 0)
203
+ durationStr += `${hours}h`;
204
+ if (minutes > 0)
205
+ durationStr += `${minutes}m`;
206
+ if (durationStr === "")
207
+ durationStr = `${durationInMinutes}m`;
208
+ durationStr += ` (${durationInMinutes}m)`;
209
+ return durationStr;
210
+ }
211
+ function formatAssetName(assetName, roleName) {
212
+ let str = `${assetName}`;
213
+ if (roleName) {
214
+ str += ` (${roleName})`;
215
+ }
216
+ return str;
217
+ }
@@ -597,7 +597,7 @@
597
597
  "request:create": {
598
598
  "aliases": [],
599
599
  "args": {},
600
- "description": "Opens an Opal access request",
600
+ "description": "Creates an Opal access request via an interactive form",
601
601
  "flags": {},
602
602
  "hasDynamicHelp": false,
603
603
  "hidden": true,
@@ -620,6 +620,10 @@
620
620
  "aliases": [],
621
621
  "args": {},
622
622
  "description": "Lists access requests",
623
+ "examples": [
624
+ "opal request get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4",
625
+ "opal request get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4 --verbose"
626
+ ],
623
627
  "flags": {
624
628
  "help": {
625
629
  "char": "h",
@@ -635,6 +639,13 @@
635
639
  "hasDynamicHelp": false,
636
640
  "multiple": false,
637
641
  "type": "option"
642
+ },
643
+ "verbose": {
644
+ "char": "v",
645
+ "description": "Enable verbose output, prints full response in JSON format. Defaults to false.",
646
+ "name": "verbose",
647
+ "allowNo": false,
648
+ "type": "boolean"
638
649
  }
639
650
  },
640
651
  "hasDynamicHelp": false,
@@ -657,8 +668,45 @@
657
668
  "request:list": {
658
669
  "aliases": [],
659
670
  "args": {},
660
- "description": "Lists access requests",
661
- "flags": {},
671
+ "description": "Lists your n recent outgoing access requests",
672
+ "examples": [
673
+ "opal request list --n 5",
674
+ "opal request list --n 5 --pending",
675
+ "opal request list --n 5 --verbose",
676
+ "opal request list --n 5 --pending --verbose"
677
+ ],
678
+ "flags": {
679
+ "help": {
680
+ "char": "h",
681
+ "description": "Show CLI help.",
682
+ "name": "help",
683
+ "allowNo": false,
684
+ "type": "boolean"
685
+ },
686
+ "n": {
687
+ "char": "n",
688
+ "description": "Defines number of requests to be returned. 1 <= n <= 100.",
689
+ "name": "n",
690
+ "default": 10,
691
+ "hasDynamicHelp": false,
692
+ "multiple": false,
693
+ "type": "option"
694
+ },
695
+ "pending": {
696
+ "char": "p",
697
+ "description": "Show only pending requests. Defaults to false.",
698
+ "name": "pending",
699
+ "allowNo": false,
700
+ "type": "boolean"
701
+ },
702
+ "verbose": {
703
+ "char": "v",
704
+ "description": "Enable verbose output, prints full response in JSON format. Defaults to false.",
705
+ "name": "verbose",
706
+ "allowNo": false,
707
+ "type": "boolean"
708
+ }
709
+ },
662
710
  "hasDynamicHelp": false,
663
711
  "hidden": true,
664
712
  "hiddenAliases": [],
@@ -923,5 +971,5 @@
923
971
  ]
924
972
  }
925
973
  },
926
- "version": "3.1.1-beta.e5e99da"
974
+ "version": "3.1.1-beta.f2bce00"
927
975
  }
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.e5e99da",
4
+ "version": "3.1.1-beta.f2bce00",
5
5
  "author": "Stephen Cobbe",
6
6
  "bin": {
7
7
  "opal": "./bin/run"
@@ -16,6 +16,7 @@
16
16
  "argon2": "^0.40.1",
17
17
  "chalk": "^2.4.2",
18
18
  "cli-table3": "^0.6.5",
19
+ "enquirer": "^2.4.1",
19
20
  "graphql": "^15.5.0",
20
21
  "inquirer": "^8.2.6",
21
22
  "inquirer-autocomplete-prompt": "^2.0.1",
@@ -39,6 +40,7 @@
39
40
  "@types/lodash": "^4.14.169",
40
41
  "@types/node": "^22.14.0",
41
42
  "@types/prettyjson": "0.0.29",
43
+ "@types/react": "^19.1.4",
42
44
  "@types/semver": "^7.3.8",
43
45
  "better-npm-audit": "^3.7.3",
44
46
  "get-graphql-schema": "^2.1.2",