opal-security 3.2.1 → 3.2.3

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 (63) hide show
  1. package/README.md +28 -25
  2. package/lib/commands/login.js +18 -11
  3. package/lib/commands/request/create.d.ts +2 -0
  4. package/lib/commands/request/create.js +41 -20
  5. package/lib/commands/request/get.js +7 -58
  6. package/lib/commands/request/list.js +3 -60
  7. package/lib/graphql/gql.d.ts +35 -15
  8. package/lib/graphql/gql.js +9 -5
  9. package/lib/graphql/graphql.d.ts +1138 -383
  10. package/lib/graphql/graphql.js +1780 -1104
  11. package/lib/handler.d.ts +6 -6
  12. package/lib/handler.js +1 -1
  13. package/lib/labels.d.ts +3 -0
  14. package/lib/labels.js +40 -0
  15. package/lib/lib/apollo.d.ts +3 -3
  16. package/lib/lib/apollo.js +24 -47
  17. package/lib/lib/request/api/index.d.ts +6 -0
  18. package/lib/lib/request/api/index.js +20 -0
  19. package/lib/lib/request/api/mutations/create-request.d.ts +8 -0
  20. package/lib/lib/request/api/mutations/create-request.js +159 -0
  21. package/lib/lib/request/api/queries/apps.d.ts +4 -0
  22. package/lib/lib/request/api/queries/apps.js +73 -0
  23. package/lib/lib/request/api/queries/assets.d.ts +6 -0
  24. package/lib/lib/request/api/queries/assets.js +136 -0
  25. package/lib/lib/request/api/queries/request-defaults.d.ts +5 -0
  26. package/lib/lib/request/api/queries/request-defaults.js +52 -0
  27. package/lib/lib/request/api/queries/requests.d.ts +4 -0
  28. package/lib/lib/request/api/queries/requests.js +163 -0
  29. package/lib/lib/request/api/queries/roles.d.ts +5 -0
  30. package/lib/lib/request/api/queries/roles.js +239 -0
  31. package/lib/{utils → lib/request}/displays.d.ts +7 -5
  32. package/lib/{utils → lib/request}/displays.js +52 -30
  33. package/lib/lib/request/prompts/apps-prompt.d.ts +4 -0
  34. package/lib/lib/request/prompts/apps-prompt.js +35 -0
  35. package/lib/lib/request/prompts/asset-prompt.d.ts +5 -0
  36. package/lib/lib/request/prompts/asset-prompt.js +81 -0
  37. package/lib/lib/request/prompts/duration-prompt.d.ts +2 -0
  38. package/lib/lib/request/prompts/duration-prompt.js +125 -0
  39. package/lib/lib/request/prompts/index.d.ts +8 -0
  40. package/lib/lib/request/prompts/index.js +20 -0
  41. package/lib/lib/request/prompts/reason-prompt.d.ts +2 -0
  42. package/lib/lib/request/prompts/reason-prompt.js +20 -0
  43. package/lib/lib/request/prompts/role-prompt.d.ts +4 -0
  44. package/lib/lib/request/prompts/role-prompt.js +44 -0
  45. package/lib/lib/request/prompts/validate-prompt.d.ts +4 -0
  46. package/lib/lib/request/prompts/validate-prompt.js +29 -0
  47. package/lib/lib/request/request-utils.d.ts +14 -0
  48. package/lib/lib/request/request-utils.js +468 -0
  49. package/lib/lib/request/types.d.ts +55 -0
  50. package/lib/lib/request/types.js +15 -0
  51. package/lib/lib/resources.d.ts +1 -1
  52. package/lib/lib/sessions.d.ts +1 -1
  53. package/lib/lib/sessions.js +3 -2
  54. package/lib/lib/util.d.ts +1 -0
  55. package/lib/lib/util.js +16 -0
  56. package/lib/types.d.ts +19 -3
  57. package/lib/types.js +18 -2
  58. package/oclif.manifest.json +54 -38
  59. package/package.json +4 -3
  60. package/lib/lib/requests.d.ts +0 -54
  61. package/lib/lib/requests.js +0 -1160
  62. package/lib/utils/utils.d.ts +0 -1
  63. package/lib/utils/utils.js +0 -18
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryRequestDefaults = queryRequestDefaults;
4
+ const graphql_1 = require("../../../../graphql");
5
+ const REQUEST_DEFAULTS_QUERY = (0, graphql_1.graphql)(`
6
+ query RequestDefaults(
7
+ $requestedResources: [RequestConfigurationResourceInput!]!
8
+ $requestedGroups: [RequestConfigurationGroupInput!]!
9
+ ) {
10
+ requestDefaults(input: {
11
+ requestedResources: $requestedResources,
12
+ requestedGroups: $requestedGroups,
13
+ }
14
+ ) {
15
+ ... on RequestDefaults {
16
+ durationOptions {
17
+ durationInMinutes
18
+ label
19
+ }
20
+ recommendedDurationInMinutes
21
+ defaultDurationInMinutes
22
+ maxDurationInMinutes
23
+ requireSupportTicket
24
+ reasonOptional
25
+ requesterIsAdmin
26
+ messages {
27
+ entityId
28
+ level
29
+ code
30
+ }
31
+ }
32
+ }
33
+ }`);
34
+ async function queryRequestDefaults(cmd, client, requestedResources, requestedGroups) {
35
+ var _a;
36
+ try {
37
+ const resp = await client.query({
38
+ query: REQUEST_DEFAULTS_QUERY,
39
+ variables: {
40
+ requestedResources: requestedResources,
41
+ requestedGroups: requestedGroups,
42
+ },
43
+ fetchPolicy: "network-only", // to avoid caching
44
+ });
45
+ return (_a = resp === null || resp === void 0 ? void 0 : resp.data) === null || _a === void 0 ? void 0 : _a.requestDefaults;
46
+ }
47
+ catch (error) {
48
+ if (error instanceof Error || typeof error === "string") {
49
+ cmd.error(error);
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,4 @@
1
+ import type { ApolloClient } from "@apollo/client";
2
+ export declare const queryRequest: (client: ApolloClient, requestId: string) => Promise<ApolloClient.QueryResult<import("../../../../graphql/graphql").GetRequestQuery>>;
3
+ export declare const queryRequests: (client: ApolloClient, pageSize: number, showPendingOnly: boolean) => Promise<ApolloClient.QueryResult<import("../../../../graphql/graphql").GetRequestsQuery>>;
4
+ export declare const queryBundle: (client: ApolloClient, bundleId: string) => Promise<ApolloClient.QueryResult<import("../../../../graphql/graphql").GetBundleQuery>>;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryBundle = exports.queryRequests = exports.queryRequest = void 0;
4
+ const graphql_1 = require("../../../../graphql");
5
+ const RESOURCE_FRAGMENT = (0, graphql_1.graphql)(`
6
+ fragment ResourceFields on Resource {
7
+ displayName
8
+ id
9
+ connectionId
10
+ connection {
11
+ name
12
+ connectionType
13
+ }
14
+ }
15
+ `);
16
+ const GROUP_FRAGMENT = (0, graphql_1.graphql)(`
17
+ fragment GroupFields on Group {
18
+ name
19
+ id
20
+ connectionId
21
+ connection {
22
+ name
23
+ connectionType
24
+ }
25
+ }
26
+ `);
27
+ const REQUEST_FIELDS_FRAGMENT = (0, graphql_1.graphql)(`
28
+ fragment RequestFields on Request {
29
+ id
30
+ createdAt
31
+ status
32
+ durationInMinutes
33
+ reason
34
+ requester {
35
+ displayName
36
+ }
37
+ targetUser {
38
+ displayName
39
+ }
40
+ requestedResources {
41
+ resource {
42
+ ...ResourceFields
43
+ }
44
+ accessLevel {
45
+ accessLevelName
46
+ accessLevelRemoteId
47
+ }
48
+ }
49
+ requestedGroups {
50
+ group {
51
+ ...GroupFields
52
+ }
53
+ accessLevel {
54
+ accessLevelName
55
+ accessLevelRemoteId
56
+ }
57
+ }
58
+ }
59
+ `);
60
+ const GET_REQUEST = (0, graphql_1.graphql)(`
61
+ query GetRequest(
62
+ $id: RequestId!
63
+ ) {
64
+ request(input: {id: $id}) {
65
+ __typename
66
+ ... on RequestResult {
67
+ request {
68
+ ...RequestFields
69
+ }
70
+ }
71
+ ... on RequestNotFoundError {
72
+ message
73
+ }
74
+ }
75
+ }
76
+ `);
77
+ const queryRequest = async (client, requestId) => {
78
+ const resp = await client.query({
79
+ query: GET_REQUEST,
80
+ variables: {
81
+ id: requestId,
82
+ },
83
+ fetchPolicy: "network-only", // to avoid caching
84
+ });
85
+ return resp;
86
+ };
87
+ exports.queryRequest = queryRequest;
88
+ // TODO: Add date filters, search query,
89
+ const GET_OUTGOING_REQUESTS = (0, graphql_1.graphql)(`
90
+ query GetRequests($showPendingOnly: Boolean!, $pageSize: Int) {
91
+ requests(input: {
92
+ requestType: OUTGOING
93
+ maxNumEntries: $pageSize
94
+ filters: {
95
+ showPendingOnly: $showPendingOnly
96
+ }
97
+ }) {
98
+ __typename
99
+ ... on RequestsResult {
100
+ requestType
101
+ requests {
102
+ ...RequestFields
103
+ }
104
+
105
+ }
106
+
107
+ }
108
+ }`);
109
+ const queryRequests = async (client, pageSize, showPendingOnly) => {
110
+ const resp = await client.query({
111
+ query: GET_OUTGOING_REQUESTS,
112
+ variables: {
113
+ pageSize: pageSize,
114
+ showPendingOnly: showPendingOnly,
115
+ },
116
+ fetchPolicy: "network-only", // to avoid caching
117
+ });
118
+ return resp;
119
+ };
120
+ exports.queryRequests = queryRequests;
121
+ const GET_BUNDLE = (0, graphql_1.graphql)(`query GetBundle($id: BundleId!) {
122
+ bundle(input: { id: $id }) {
123
+ __typename
124
+ ... on BundleResult {
125
+ bundle {
126
+ name
127
+ id
128
+ items {
129
+ edges {
130
+ accessLevel {
131
+ accessLevelName
132
+ accessLevelRemoteId
133
+ }
134
+ node {
135
+ ... on Resource {
136
+ ...ResourceFields
137
+ isRequestable
138
+ }
139
+ ... on Group {
140
+ ...GroupFields
141
+ isRequestable
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ... on BundleNotFoundError {
149
+ message
150
+ }
151
+ }
152
+ }`);
153
+ const queryBundle = async (client, bundleId) => {
154
+ const resp = await client.query({
155
+ query: GET_BUNDLE,
156
+ variables: {
157
+ id: bundleId,
158
+ },
159
+ fetchPolicy: "network-only", // to avoid caching
160
+ });
161
+ return resp;
162
+ };
163
+ exports.queryBundle = queryBundle;
@@ -0,0 +1,5 @@
1
+ import type { ApolloClient } from "@apollo/client";
2
+ import type { Command } from "@oclif/core";
3
+ import type { PromptChoice } from "../../types";
4
+ export declare function queryAssetRoles(cmd: Command, client: ApolloClient, assetType: string, assetId: string): Promise<PromptChoice[] | undefined>;
5
+ export declare function queryAssociatedItems(cmd: Command, client: ApolloClient, id: string, input: string | undefined): Promise<PromptChoice[] | undefined>;
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryAssetRoles = queryAssetRoles;
4
+ exports.queryAssociatedItems = queryAssociatedItems;
5
+ const graphql_1 = require("../../../../graphql");
6
+ const graphql_2 = require("../../../../graphql/graphql");
7
+ const labels_1 = require("../../../../labels");
8
+ const RESOURCE_ROLES_QUERY = (0, graphql_1.graphql)(`
9
+ query ResourceAccessLevels($resourceId: ResourceId!) {
10
+ accessLevels(input: {
11
+ resourceId: $resourceId,
12
+ onlyMine: false,
13
+ }) {
14
+ __typename
15
+ ... on ResourceAccessLevelsResult {
16
+ accessLevels {
17
+ ... on ResourceAccessLevel {
18
+ accessLevelName
19
+ accessLevelRemoteId
20
+ }
21
+ }
22
+ }
23
+ ... on ResourceNotFoundError {
24
+ message
25
+ }
26
+ }
27
+ }
28
+ `);
29
+ const GROUP_ROLES_QUERY = (0, graphql_1.graphql)(`
30
+ query GroupAccessLevels($groupId: GroupId!) {
31
+ groupAccessLevels(
32
+ input: { groupId: $groupId }
33
+ ) {
34
+ ... on GroupAccessLevelsResult {
35
+ groupId
36
+ accessLevels {
37
+ ... on GroupAccessLevel {
38
+ accessLevelName
39
+ accessLevelRemoteId
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+ `);
46
+ async function queryAssetRoles(cmd, client, assetType, assetId) {
47
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
48
+ try {
49
+ switch (assetType) {
50
+ case graphql_2.EntityType.Resource: {
51
+ const resp = await client.query({
52
+ query: RESOURCE_ROLES_QUERY,
53
+ variables: {
54
+ resourceId: assetId,
55
+ },
56
+ fetchPolicy: "network-only", // to avoid caching
57
+ });
58
+ // no fall through doesn't consider process.exit();
59
+ let x;
60
+ switch ((_a = resp === null || resp === void 0 ? void 0 : resp.data) === null || _a === void 0 ? void 0 : _a.accessLevels.__typename) {
61
+ case "ResourceAccessLevelsResult":
62
+ return (_d = (_c = (_b = resp.data) === null || _b === void 0 ? void 0 : _b.accessLevels) === null || _c === void 0 ? void 0 : _c.accessLevels) === null || _d === void 0 ? void 0 : _d.map((role) => {
63
+ return {
64
+ message: role.accessLevelName || "",
65
+ value: {
66
+ name: role.accessLevelName || "",
67
+ id: role.accessLevelRemoteId || "",
68
+ },
69
+ };
70
+ });
71
+ case "ResourceNotFoundError":
72
+ x = cmd.error((_f = (_e = resp.data) === null || _e === void 0 ? void 0 : _e.accessLevels) === null || _f === void 0 ? void 0 : _f.message);
73
+ break;
74
+ default:
75
+ cmd.error(resp.error || "Unknown error occurred.");
76
+ }
77
+ return;
78
+ }
79
+ case graphql_2.EntityType.Group: {
80
+ const resp = await client.query({
81
+ query: GROUP_ROLES_QUERY,
82
+ variables: {
83
+ groupId: assetId,
84
+ },
85
+ fetchPolicy: "network-only", // to avoid caching
86
+ });
87
+ // no fall through doesn't consider process.exit();
88
+ let x;
89
+ switch ((_g = resp === null || resp === void 0 ? void 0 : resp.data) === null || _g === void 0 ? void 0 : _g.groupAccessLevels.__typename) {
90
+ case "GroupAccessLevelsResult":
91
+ return (_k = (_j = (_h = resp.data) === null || _h === void 0 ? void 0 : _h.groupAccessLevels) === null || _j === void 0 ? void 0 : _j.accessLevels) === null || _k === void 0 ? void 0 : _k.map((role) => {
92
+ return {
93
+ message: role.accessLevelName,
94
+ value: {
95
+ name: role.accessLevelName,
96
+ id: role.accessLevelRemoteId,
97
+ },
98
+ };
99
+ });
100
+ default:
101
+ x = cmd.error(resp.error || "Unknown error occurred.");
102
+ }
103
+ return;
104
+ }
105
+ }
106
+ }
107
+ catch (error) {
108
+ if (error instanceof Error || typeof error === "string") {
109
+ cmd.error(error);
110
+ }
111
+ }
112
+ }
113
+ const ASSOCIATED_ITEMS_QUERY = (0, graphql_1.graphql)(`
114
+ query GetAssociatedItems($resourceId: ResourceId!, $searchQuery: String) {
115
+ resource(input: {
116
+ id: $resourceId
117
+ }) {
118
+ __typename
119
+ ... on ResourceResult {
120
+ __typename
121
+ resource {
122
+ associatedItems(
123
+ first: 200
124
+ filters: {
125
+ searchQuery: {
126
+ contains: $searchQuery
127
+ }
128
+ access: REQUESTABLE
129
+ endUserVisible: true
130
+ entityType: {
131
+ in: [GROUP, RESOURCE]
132
+ }
133
+ }
134
+ ) {
135
+ edges {
136
+ __typename
137
+ ... on ResourceAssociatedItemEdge {
138
+ alias
139
+ node {
140
+ __typename
141
+ id
142
+ name
143
+ ... on Resource {
144
+ accessLevels(
145
+ filters: {
146
+ skipRemoteAccessLevels: false # azure app roles are remote
147
+ }
148
+ ) {
149
+ __typename
150
+ accessLevelName
151
+ accessLevelRemoteId
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+ }
160
+ ... on ResourceNotFoundError {
161
+ message
162
+ }
163
+ }
164
+ }
165
+ `);
166
+ function appRolesFromEdge(edge) {
167
+ var _a, _b, _c, _d;
168
+ switch (edge.node.__typename) {
169
+ case "Resource": {
170
+ if (edge.node.accessLevels && edge.node.accessLevels.length > 0) {
171
+ return edge.node.accessLevels.map((accessLevel) => ({
172
+ message: accessLevel.accessLevelName || "No Role (Direct access)",
173
+ value: {
174
+ id: edge.node.id + accessLevel.accessLevelRemoteId,
175
+ name: accessLevel.accessLevelName,
176
+ type: labels_1.DisplayLabels[graphql_2.EntityType.Resource],
177
+ toString: () => accessLevel.accessLevelName,
178
+ },
179
+ }));
180
+ }
181
+ return [
182
+ {
183
+ message: (_a = edge.alias) !== null && _a !== void 0 ? _a : edge.node.name,
184
+ value: {
185
+ id: edge.node.id,
186
+ name: (_b = edge.alias) !== null && _b !== void 0 ? _b : edge.node.name,
187
+ type: labels_1.DisplayLabels[graphql_2.EntityType.Resource],
188
+ toString: () => { var _a; return (_a = edge.alias) !== null && _a !== void 0 ? _a : edge.node.name; },
189
+ },
190
+ },
191
+ ];
192
+ }
193
+ case "Group":
194
+ return [
195
+ {
196
+ message: `${(_c = edge.alias) !== null && _c !== void 0 ? _c : edge.node.name} ${graphql_2.EntityType.Group}`,
197
+ value: {
198
+ id: edge.node.id,
199
+ name: (_d = edge.alias) !== null && _d !== void 0 ? _d : edge.node.name,
200
+ type: labels_1.DisplayLabels[graphql_2.EntityType.Group],
201
+ toString: () => { var _a; return (_a = edge.alias) !== null && _a !== void 0 ? _a : edge.node.name; },
202
+ },
203
+ },
204
+ ];
205
+ }
206
+ }
207
+ async function queryAssociatedItems(cmd, client, id, input) {
208
+ var _a, _b, _c;
209
+ try {
210
+ const resp = await client.query({
211
+ query: ASSOCIATED_ITEMS_QUERY,
212
+ variables: {
213
+ resourceId: id || "",
214
+ searchQuery: input || "",
215
+ },
216
+ fetchPolicy: "network-only", // to avoid caching
217
+ });
218
+ switch ((_a = resp === null || resp === void 0 ? void 0 : resp.data) === null || _a === void 0 ? void 0 : _a.resource.__typename) {
219
+ case "ResourceResult": {
220
+ const associatedItems = resp.data.resource.resource.associatedItems.edges.filter((edge) => edge.__typename === "ResourceAssociatedItemEdge");
221
+ const initial = [];
222
+ for (const edge of associatedItems) {
223
+ initial.push(...appRolesFromEdge(edge));
224
+ }
225
+ return initial;
226
+ }
227
+ case "ResourceNotFoundError":
228
+ cmd.log((_c = (_b = resp.data) === null || _b === void 0 ? void 0 : _b.resource) === null || _c === void 0 ? void 0 : _c.message);
229
+ break;
230
+ default:
231
+ cmd.error(resp.error || "Unknown error occurred.");
232
+ }
233
+ }
234
+ catch (error) {
235
+ if (error instanceof Error || typeof error === "string") {
236
+ cmd.error(error);
237
+ }
238
+ }
239
+ }
@@ -1,10 +1,12 @@
1
- import type { ApolloQueryResult } from "@apollo/client";
1
+ import type { ApolloClient } from "@apollo/client";
2
2
  import type { Command } from "@oclif/core/lib/command";
3
- import type { GetRequestQuery, GetRequestsQuery } from "../graphql/graphql";
4
- import { type RequestMap, type RequestMetadata } from "../lib/requests";
3
+ import type { GetRequestQuery, GetRequestsQuery } from "../../graphql/graphql";
4
+ import type { RequestMap, RequestMetadata } from "./types";
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;
8
8
  export declare function getStyledStatus(status: string): string;
9
- export declare function displayRequestDetails(cmd: Command, requestResp: ApolloQueryResult<GetRequestQuery>): void;
10
- export declare function displayRequestListTable(cmd: Command, requestResp: ApolloQueryResult<GetRequestsQuery>): void;
9
+ export declare function displayRequestDetails(cmd: Command, requestResp: ApolloClient.QueryResult<GetRequestQuery>): void;
10
+ export declare function displayRequestListTable(cmd: Command, requestResp: ApolloClient.QueryResult<GetRequestsQuery>): void;
11
+ export declare function formatDuration(durationInMinutes: number): string;
12
+ export declare function displayRequestAgain(cmd: Command, id: string): void;
@@ -6,8 +6,10 @@ exports.displayFinalRequestSummary = displayFinalRequestSummary;
6
6
  exports.getStyledStatus = getStyledStatus;
7
7
  exports.displayRequestDetails = displayRequestDetails;
8
8
  exports.displayRequestListTable = displayRequestListTable;
9
+ exports.formatDuration = formatDuration;
10
+ exports.displayRequestAgain = displayRequestAgain;
9
11
  const chalk_1 = require("chalk");
10
- const requests_1 = require("../lib/requests");
12
+ const labels_1 = require("../../labels");
11
13
  const Table = require("cli-table3");
12
14
  function headerMessage(cmd) {
13
15
  console.clear();
@@ -15,6 +17,16 @@ function headerMessage(cmd) {
15
17
  cmd.log("Opal Access Request ✏️");
16
18
  cmd.log("Press Ctrl+C to cancel at any time.\n");
17
19
  }
20
+ /*
21
+ Example treeified output:
22
+
23
+ Opal [App]
24
+ └── Infosec Group [Group]
25
+ └── Infosec Prod Databases [Group]
26
+ MongoDB Atlas Test [App]
27
+ └── my-mongo-db-atlas [Resource]
28
+ └── admin:test [Role]
29
+ */
18
30
  function treeifyRequestMap(cmd, requestMap) {
19
31
  for (const [_appId, appNode] of Object.entries(requestMap)) {
20
32
  // Print App title first (without tree lines)
@@ -22,7 +34,7 @@ function treeifyRequestMap(cmd, requestMap) {
22
34
  for (const [_assetId, assetNode] of Object.entries(appNode.assets)) {
23
35
  // If okta/azure asset with no role, change asset name
24
36
  const assetName = assetNode.assetName || "No Role (Direct access)";
25
- cmd.log(`└── ${assetName} ${chalk_1.default.dim(`[${requests_1.DISPLAY_LABELS[assetNode.type]}]`)}`);
37
+ cmd.log(`└── ${assetName} ${chalk_1.default.dim(`[${labels_1.DisplayLabels[assetNode.type]}]`)}`);
26
38
  if (assetNode.roles !== undefined) {
27
39
  for (const [_roleId, roleNode] of Object.entries(assetNode.roles)) {
28
40
  const roleName = roleNode.roleName;
@@ -72,39 +84,42 @@ function getStyledStatus(status) {
72
84
  }
73
85
  }
74
86
  function displayRequestDetails(cmd, requestResp) {
75
- var _a, _b, _c, _d, _e, _f;
76
- switch (requestResp.data.request.__typename) {
87
+ var _a, _b, _c, _d, _e, _f, _g;
88
+ switch ((_a = requestResp.data) === null || _a === void 0 ? void 0 : _a.request.__typename) {
77
89
  case "RequestResult": {
90
+ const request = requestResp.data.request.request;
78
91
  cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
79
- cmd.log(`Request Details ${chalk_1.default.cyan(requestResp.data.request.request.id)}`);
92
+ cmd.log(`Request Details ${chalk_1.default.cyan(request.id)}`);
80
93
  cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
81
- const status = requestResp.data.request.request.status;
94
+ const status = request.status;
82
95
  cmd.log(getStyledStatus(status));
83
96
  // Request users "Requested by: <requester> -> Requested for: <targetUser>"
84
- const requester = (_a = requestResp.data.request.request.requester) === null || _a === void 0 ? void 0 : _a.displayName;
85
- const targetUser = (_b = requestResp.data.request.request.targetUser) === null || _b === void 0 ? void 0 : _b.displayName;
97
+ const requester = (_b = request.requester) === null || _b === void 0 ? void 0 : _b.displayName;
98
+ const targetUser = (_c = request.targetUser) === null || _c === void 0 ? void 0 : _c.displayName;
86
99
  if (requester && targetUser) {
87
100
  cmd.log(`${chalk_1.default.bold("Requested by:")} ${requester} ${chalk_1.default.gray("->")} ${chalk_1.default.bold("Requested for:")} ${targetUser}`);
88
101
  }
89
- const durationInMinutes = requestResp.data.request.request.durationInMinutes;
102
+ const durationInMinutes = request.durationInMinutes;
90
103
  cmd.log(`${chalk_1.default.bold("Duration:")} ${durationInMinutes ? formatDuration(durationInMinutes) : "Permanent"}`);
91
- const reason = requestResp.data.request.request.reason;
104
+ const reason = request.reason;
92
105
  if (reason) {
93
106
  cmd.log(`${chalk_1.default.bold("Reason:")} "${chalk_1.default.italic(reason)}"`);
94
107
  }
95
108
  // Requested resources
96
- const requestedResources = (_d = (_c = requestResp.data.request.request.requestedResources) === null || _c === void 0 ? void 0 : _c.map((resource) => {
97
- var _a, _b, _c;
109
+ const requestedResources = (_e = (_d = request.requestedResources) === null || _d === void 0 ? void 0 : _d.map((resource) => {
110
+ var _a, _b;
98
111
  if (((_a = resource.resource) === null || _a === void 0 ? void 0 : _a.__typename) === "Resource") {
99
- return formatAssetName((_b = resource.resource) === null || _b === void 0 ? void 0 : _b.displayName, ((_c = resource.accessLevel) === null || _c === void 0 ? void 0 : _c.accessLevelName) || "");
112
+ const requestedResource = resource.resource;
113
+ return formatAssetName(requestedResource.displayName, ((_b = resource.accessLevel) === null || _b === void 0 ? void 0 : _b.accessLevelName) || "");
100
114
  }
101
- })) !== null && _d !== void 0 ? _d : [];
102
- const requestedGroups = (_f = (_e = requestResp.data.request.request.requestedGroups) === null || _e === void 0 ? void 0 : _e.map((group) => {
103
- var _a, _b, _c;
115
+ })) !== null && _e !== void 0 ? _e : [];
116
+ const requestedGroups = (_g = (_f = request.requestedGroups) === null || _f === void 0 ? void 0 : _f.map((group) => {
117
+ var _a, _b;
104
118
  if (((_a = group.group) === null || _a === void 0 ? void 0 : _a.__typename) === "Group") {
105
- return formatAssetName((_b = group.group) === null || _b === void 0 ? void 0 : _b.name, ((_c = group.accessLevel) === null || _c === void 0 ? void 0 : _c.accessLevelName) || "");
119
+ const requestedGroup = group.group;
120
+ return formatAssetName(requestedGroup.name, ((_b = group.accessLevel) === null || _b === void 0 ? void 0 : _b.accessLevelName) || "");
106
121
  }
107
- })) !== null && _f !== void 0 ? _f : [];
122
+ })) !== null && _g !== void 0 ? _g : [];
108
123
  const requestedItems = [...requestedResources, ...requestedGroups].join(", ");
109
124
  if (requestedItems) {
110
125
  cmd.log(`${chalk_1.default.bold("Requested Items:")} ${chalk_1.default.cyan(requestedItems)}`);
@@ -113,8 +128,8 @@ function displayRequestDetails(cmd, requestResp) {
113
128
  }
114
129
  }
115
130
  function displayRequestListTable(cmd, requestResp) {
116
- var _a, _b, _c, _d, _e;
117
- switch (requestResp.data.requests.__typename) {
131
+ var _a, _b, _c, _d, _e, _f;
132
+ switch ((_a = requestResp.data) === null || _a === void 0 ? void 0 : _a.requests.__typename) {
118
133
  case "RequestsResult": {
119
134
  const requests = requestResp.data.requests.requests;
120
135
  if (requests && requests.length > 0) {
@@ -131,25 +146,28 @@ function displayRequestListTable(cmd, requestResp) {
131
146
  wordWrap: true,
132
147
  wrapOnWordBoundary: false,
133
148
  });
134
- for (const request of requests) {
135
- const targetUser = (_a = request.targetUser) === null || _a === void 0 ? void 0 : _a.displayName;
149
+ for (const req of requests) {
150
+ const request = req;
151
+ const targetUser = (_b = request.targetUser) === null || _b === void 0 ? void 0 : _b.displayName;
136
152
  const reason = request.reason;
137
153
  const status = request.status;
138
154
  const formattedDuration = request.durationInMinutes
139
155
  ? formatDuration(request.durationInMinutes)
140
156
  : "Permanent";
141
- const requestedResources = (_c = (_b = request.requestedResources) === null || _b === void 0 ? void 0 : _b.map((resource) => {
142
- var _a, _b, _c;
157
+ const requestedResources = (_d = (_c = request.requestedResources) === null || _c === void 0 ? void 0 : _c.map((resource) => {
158
+ var _a, _b;
143
159
  if (((_a = resource.resource) === null || _a === void 0 ? void 0 : _a.__typename) === "Resource") {
144
- return formatAssetName((_b = resource.resource) === null || _b === void 0 ? void 0 : _b.displayName, ((_c = resource.accessLevel) === null || _c === void 0 ? void 0 : _c.accessLevelName) || "");
160
+ const requestedResource = resource.resource;
161
+ return formatAssetName(requestedResource.displayName, ((_b = resource.accessLevel) === null || _b === void 0 ? void 0 : _b.accessLevelName) || "");
145
162
  }
146
- })) !== null && _c !== void 0 ? _c : [];
147
- const requestedGroups = (_e = (_d = request.requestedGroups) === null || _d === void 0 ? void 0 : _d.map((group) => {
148
- var _a, _b, _c;
163
+ })) !== null && _d !== void 0 ? _d : [];
164
+ const requestedGroups = (_f = (_e = request.requestedGroups) === null || _e === void 0 ? void 0 : _e.map((group) => {
165
+ var _a, _b;
149
166
  if (((_a = group.group) === null || _a === void 0 ? void 0 : _a.__typename) === "Group") {
150
- 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
+ const requestedGroup = group.group;
168
+ return formatAssetName(requestedGroup.name, ((_b = group.accessLevel) === null || _b === void 0 ? void 0 : _b.accessLevelName) || "");
151
169
  }
152
- })) !== null && _e !== void 0 ? _e : [];
170
+ })) !== null && _f !== void 0 ? _f : [];
153
171
  const requestedItems = [
154
172
  ...requestedResources,
155
173
  ...requestedGroups,
@@ -199,3 +217,7 @@ function formatAssetName(assetName, roleName) {
199
217
  }
200
218
  return str;
201
219
  }
220
+ function displayRequestAgain(cmd, id) {
221
+ cmd.log(chalk_1.default.bold("\nTo request this again, run:"));
222
+ cmd.log(chalk_1.default.italic(` opal request create --template ${id}\n`));
223
+ }
@@ -0,0 +1,4 @@
1
+ import type { ApolloClient } from "@apollo/client";
2
+ import type { Command } from "@oclif/core";
3
+ import type { RequestMap } from "../types";
4
+ export declare function selectRequestableItems(cmd: Command, client: ApolloClient, requestMap: RequestMap): Promise<void>;