opal-security 3.2.4 → 4.0.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/README.md +46 -61
- package/bin/dev +5 -5
- package/bin/run +2 -4
- package/build/commands/aws/identity.js +16 -0
- package/build/commands/clear-auth-config.d.ts +6 -0
- package/build/commands/clear-auth-config.js +22 -0
- package/{lib → build}/commands/groups/get.js +14 -16
- package/{lib → build}/commands/iam-roles/start.js +28 -30
- package/build/commands/kube-roles/start.js +71 -0
- package/{lib → build}/commands/login.d.ts +1 -0
- package/build/commands/login.js +379 -0
- package/build/commands/logout.js +22 -0
- package/{lib → build}/commands/postgres-instances/start.js +25 -27
- package/{lib → build}/commands/request/create.js +34 -36
- package/{lib → build}/commands/request/get.js +22 -24
- package/{lib → build}/commands/request/list.js +17 -19
- package/{lib → build}/commands/resources/get.js +15 -18
- package/build/commands/set-auth-config.d.ts +11 -0
- package/build/commands/set-auth-config.js +59 -0
- package/build/commands/set-custom-header.js +35 -0
- package/{lib → build}/commands/set-token.js +15 -17
- package/{lib → build}/commands/set-url.js +26 -28
- package/{lib → build}/commands/ssh/copyFrom.js +22 -24
- package/{lib → build}/commands/ssh/copyTo.js +22 -24
- package/{lib → build}/commands/ssh/start.js +30 -33
- package/build/commands/whoami.js +27 -0
- package/{lib → build}/graphql/fragment-masking.d.ts +1 -1
- package/{lib → build}/graphql/fragment-masking.js +3 -8
- package/{lib → build}/graphql/gql.d.ts +1 -1
- package/{lib → build}/graphql/gql.js +2 -5
- package/{lib → build}/graphql/graphql.js +256 -261
- package/build/graphql/index.d.ts +2 -0
- package/build/graphql/index.js +2 -0
- package/{lib → build}/handler.d.ts +1 -1
- package/build/handler.js +36 -0
- package/build/index.js +1 -0
- package/{lib → build}/labels.d.ts +1 -1
- package/build/labels.js +37 -0
- package/{lib → build}/lib/apollo.d.ts +2 -2
- package/{lib → build}/lib/apollo.js +62 -69
- package/build/lib/auth-success-template.d.ts +3 -0
- package/build/lib/auth-success-template.js +149 -0
- package/{lib → build}/lib/aws.js +2 -7
- package/{lib → build}/lib/cmd.d.ts +4 -4
- package/{lib → build}/lib/cmd.js +16 -20
- package/build/lib/config.js +46 -0
- package/{lib → build}/lib/credentials/index.d.ts +3 -2
- package/build/lib/credentials/index.js +85 -0
- package/{lib → build}/lib/credentials/keychain.js +4 -10
- package/{lib → build}/lib/credentials/localEncryption.js +12 -17
- package/{lib → build}/lib/flags.js +7 -10
- package/build/lib/local-auth-server.d.ts +5 -0
- package/build/lib/local-auth-server.js +69 -0
- package/build/lib/request/api/index.d.ts +6 -0
- package/build/lib/request/api/index.js +8 -0
- package/{lib → build}/lib/request/api/mutations/create-request.d.ts +2 -2
- package/{lib → build}/lib/request/api/mutations/create-request.js +3 -6
- package/{lib → build}/lib/request/api/queries/apps.d.ts +1 -1
- package/{lib → build}/lib/request/api/queries/apps.js +3 -6
- package/{lib → build}/lib/request/api/queries/assets.d.ts +2 -2
- package/{lib → build}/lib/request/api/queries/assets.js +7 -11
- package/{lib → build}/lib/request/api/queries/request-defaults.d.ts +2 -2
- package/{lib → build}/lib/request/api/queries/request-defaults.js +3 -6
- package/{lib → build}/lib/request/api/queries/requests.d.ts +3 -3
- package/{lib → build}/lib/request/api/queries/requests.js +10 -16
- package/{lib → build}/lib/request/api/queries/roles.d.ts +1 -1
- package/{lib → build}/lib/request/api/queries/roles.js +14 -18
- package/{lib → build}/lib/request/displays.d.ts +2 -2
- package/{lib → build}/lib/request/displays.js +27 -37
- package/{lib → build}/lib/request/prompts/apps-prompt.d.ts +1 -1
- package/build/lib/request/prompts/apps-prompt.js +33 -0
- package/{lib → build}/lib/request/prompts/asset-prompt.d.ts +1 -1
- package/build/lib/request/prompts/asset-prompt.js +61 -0
- package/{lib → build}/lib/request/prompts/duration-prompt.d.ts +1 -1
- package/{lib → build}/lib/request/prompts/duration-prompt.js +6 -10
- package/build/lib/request/prompts/index.d.ts +7 -0
- package/build/lib/request/prompts/index.js +8 -0
- package/{lib → build}/lib/request/prompts/reason-prompt.d.ts +1 -1
- package/{lib → build}/lib/request/prompts/reason-prompt.js +3 -6
- package/{lib → build}/lib/request/prompts/role-prompt.d.ts +1 -1
- package/{lib → build}/lib/request/prompts/role-prompt.js +9 -11
- package/{lib → build}/lib/request/prompts/validate-prompt.d.ts +1 -1
- package/{lib → build}/lib/request/prompts/validate-prompt.js +9 -13
- package/{lib → build}/lib/request/request-utils.d.ts +2 -2
- package/{lib → build}/lib/request/request-utils.js +50 -62
- package/{lib → build}/lib/request/types.d.ts +1 -1
- package/build/lib/request/types.js +12 -0
- package/{lib → build}/lib/resources.d.ts +1 -1
- package/{lib → build}/lib/resources.js +18 -23
- package/{lib → build}/lib/sessions.d.ts +1 -1
- package/{lib → build}/lib/sessions.js +57 -32
- package/{lib → build}/lib/ssh.d.ts +1 -1
- package/{lib → build}/lib/ssh.js +6 -11
- package/{lib → build}/lib/util.js +7 -14
- package/{lib → build}/types.js +98 -101
- package/oclif.manifest.json +77 -98
- package/package.json +24 -14
- package/lib/commands/aws/identity.js +0 -18
- package/lib/commands/clear-auth-provider.d.ts +0 -9
- package/lib/commands/clear-auth-provider.js +0 -28
- package/lib/commands/curl-example.d.ts +0 -8
- package/lib/commands/curl-example.js +0 -34
- package/lib/commands/kube-roles/start.js +0 -73
- package/lib/commands/login.js +0 -286
- package/lib/commands/logout.js +0 -23
- package/lib/commands/set-auth-provider.d.ts +0 -11
- package/lib/commands/set-auth-provider.js +0 -44
- package/lib/commands/set-custom-header.js +0 -37
- package/lib/commands/whoami.js +0 -34
- package/lib/graphql/index.d.ts +0 -2
- package/lib/graphql/index.js +0 -5
- package/lib/handler.js +0 -41
- package/lib/index.js +0 -5
- package/lib/labels.js +0 -40
- package/lib/lib/config.js +0 -54
- package/lib/lib/credentials/index.js +0 -67
- package/lib/lib/request/api/index.d.ts +0 -6
- package/lib/lib/request/api/index.js +0 -20
- package/lib/lib/request/prompts/apps-prompt.js +0 -35
- package/lib/lib/request/prompts/asset-prompt.js +0 -65
- package/lib/lib/request/prompts/index.d.ts +0 -7
- package/lib/lib/request/prompts/index.js +0 -19
- package/lib/lib/request/types.js +0 -15
- /package/{lib → build}/commands/aws/identity.d.ts +0 -0
- /package/{lib → build}/commands/groups/get.d.ts +0 -0
- /package/{lib → build}/commands/iam-roles/start.d.ts +0 -0
- /package/{lib → build}/commands/kube-roles/start.d.ts +0 -0
- /package/{lib → build}/commands/logout.d.ts +0 -0
- /package/{lib → build}/commands/postgres-instances/start.d.ts +0 -0
- /package/{lib → build}/commands/request/create.d.ts +0 -0
- /package/{lib → build}/commands/request/get.d.ts +0 -0
- /package/{lib → build}/commands/request/list.d.ts +0 -0
- /package/{lib → build}/commands/resources/get.d.ts +0 -0
- /package/{lib → build}/commands/set-custom-header.d.ts +0 -0
- /package/{lib → build}/commands/set-token.d.ts +0 -0
- /package/{lib → build}/commands/set-url.d.ts +0 -0
- /package/{lib → build}/commands/ssh/copyFrom.d.ts +0 -0
- /package/{lib → build}/commands/ssh/copyTo.d.ts +0 -0
- /package/{lib → build}/commands/ssh/start.d.ts +0 -0
- /package/{lib → build}/commands/whoami.d.ts +0 -0
- /package/{lib → build}/graphql/graphql.d.ts +0 -0
- /package/{lib → build}/index.d.ts +0 -0
- /package/{lib → build}/lib/aws.d.ts +0 -0
- /package/{lib → build}/lib/config.d.ts +0 -0
- /package/{lib → build}/lib/credentials/keychain.d.ts +0 -0
- /package/{lib → build}/lib/credentials/localEncryption.d.ts +0 -0
- /package/{lib → build}/lib/flags.d.ts +0 -0
- /package/{lib → build}/lib/util.d.ts +0 -0
- /package/{lib → build}/types.d.ts +0 -0
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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)(`
|
|
1
|
+
import { graphql } from "../../../../graphql/index.js";
|
|
2
|
+
import { EntityType, } from "../../../../graphql/graphql.js";
|
|
3
|
+
import { DisplayLabels } from "../../../../labels.js";
|
|
4
|
+
const RESOURCE_ROLES_QUERY = graphql(`
|
|
9
5
|
query ResourceAccessLevels($resourceId: ResourceId!) {
|
|
10
6
|
accessLevels(input: {
|
|
11
7
|
resourceId: $resourceId,
|
|
@@ -26,7 +22,7 @@ const RESOURCE_ROLES_QUERY = (0, graphql_1.graphql)(`
|
|
|
26
22
|
}
|
|
27
23
|
}
|
|
28
24
|
`);
|
|
29
|
-
const GROUP_ROLES_QUERY =
|
|
25
|
+
const GROUP_ROLES_QUERY = graphql(`
|
|
30
26
|
query GroupAccessLevels($groupId: GroupId!) {
|
|
31
27
|
groupAccessLevels(
|
|
32
28
|
input: { groupId: $groupId }
|
|
@@ -43,11 +39,11 @@ query GroupAccessLevels($groupId: GroupId!) {
|
|
|
43
39
|
}
|
|
44
40
|
}
|
|
45
41
|
`);
|
|
46
|
-
async function queryAssetRoles(cmd, client, assetType, assetId) {
|
|
42
|
+
export async function queryAssetRoles(cmd, client, assetType, assetId) {
|
|
47
43
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
48
44
|
try {
|
|
49
45
|
switch (assetType) {
|
|
50
|
-
case
|
|
46
|
+
case EntityType.Resource: {
|
|
51
47
|
const resp = await client.query({
|
|
52
48
|
query: RESOURCE_ROLES_QUERY,
|
|
53
49
|
variables: {
|
|
@@ -76,7 +72,7 @@ async function queryAssetRoles(cmd, client, assetType, assetId) {
|
|
|
76
72
|
}
|
|
77
73
|
return;
|
|
78
74
|
}
|
|
79
|
-
case
|
|
75
|
+
case EntityType.Group: {
|
|
80
76
|
const resp = await client.query({
|
|
81
77
|
query: GROUP_ROLES_QUERY,
|
|
82
78
|
variables: {
|
|
@@ -110,7 +106,7 @@ async function queryAssetRoles(cmd, client, assetType, assetId) {
|
|
|
110
106
|
}
|
|
111
107
|
}
|
|
112
108
|
}
|
|
113
|
-
const ASSOCIATED_ITEMS_QUERY =
|
|
109
|
+
const ASSOCIATED_ITEMS_QUERY = graphql(`
|
|
114
110
|
query GetAssociatedItems($resourceId: ResourceId!, $searchQuery: String) {
|
|
115
111
|
resource(input: {
|
|
116
112
|
id: $resourceId
|
|
@@ -173,7 +169,7 @@ function appRolesFromEdge(edge) {
|
|
|
173
169
|
value: {
|
|
174
170
|
id: edge.node.id + accessLevel.accessLevelRemoteId,
|
|
175
171
|
name: accessLevel.accessLevelName,
|
|
176
|
-
type:
|
|
172
|
+
type: DisplayLabels[EntityType.Resource],
|
|
177
173
|
toString: () => accessLevel.accessLevelName,
|
|
178
174
|
},
|
|
179
175
|
}));
|
|
@@ -184,7 +180,7 @@ function appRolesFromEdge(edge) {
|
|
|
184
180
|
value: {
|
|
185
181
|
id: edge.node.id,
|
|
186
182
|
name: (_b = edge.alias) !== null && _b !== void 0 ? _b : edge.node.name,
|
|
187
|
-
type:
|
|
183
|
+
type: DisplayLabels[EntityType.Resource],
|
|
188
184
|
toString: () => { var _a; return (_a = edge.alias) !== null && _a !== void 0 ? _a : edge.node.name; },
|
|
189
185
|
},
|
|
190
186
|
},
|
|
@@ -193,18 +189,18 @@ function appRolesFromEdge(edge) {
|
|
|
193
189
|
case "Group":
|
|
194
190
|
return [
|
|
195
191
|
{
|
|
196
|
-
message: `${(_c = edge.alias) !== null && _c !== void 0 ? _c : edge.node.name} ${
|
|
192
|
+
message: `${(_c = edge.alias) !== null && _c !== void 0 ? _c : edge.node.name} ${EntityType.Group}`,
|
|
197
193
|
value: {
|
|
198
194
|
id: edge.node.id,
|
|
199
195
|
name: (_d = edge.alias) !== null && _d !== void 0 ? _d : edge.node.name,
|
|
200
|
-
type:
|
|
196
|
+
type: DisplayLabels[EntityType.Group],
|
|
201
197
|
toString: () => { var _a; return (_a = edge.alias) !== null && _a !== void 0 ? _a : edge.node.name; },
|
|
202
198
|
},
|
|
203
199
|
},
|
|
204
200
|
];
|
|
205
201
|
}
|
|
206
202
|
}
|
|
207
|
-
async function queryAssociatedItems(cmd, client, id, input) {
|
|
203
|
+
export async function queryAssociatedItems(cmd, client, id, input) {
|
|
208
204
|
var _a, _b, _c;
|
|
209
205
|
try {
|
|
210
206
|
const resp = await client.query({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
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, RequestMetadata } from "./types";
|
|
3
|
+
import type { GetRequestQuery, GetRequestsQuery } from "../../graphql/graphql.js";
|
|
4
|
+
import type { RequestMap, RequestMetadata } from "./types.js";
|
|
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;
|
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
exports.displayFinalRequestSummary = displayFinalRequestSummary;
|
|
6
|
-
exports.getStyledStatus = getStyledStatus;
|
|
7
|
-
exports.displayRequestDetails = displayRequestDetails;
|
|
8
|
-
exports.displayRequestListTable = displayRequestListTable;
|
|
9
|
-
exports.formatDuration = formatDuration;
|
|
10
|
-
exports.displayRequestAgain = displayRequestAgain;
|
|
11
|
-
const chalk_1 = require("chalk");
|
|
12
|
-
const labels_1 = require("../../labels");
|
|
13
|
-
const Table = require("cli-table3");
|
|
14
|
-
function headerMessage(cmd) {
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import Table from "cli-table3";
|
|
3
|
+
import { DisplayLabels } from "../../labels.js";
|
|
4
|
+
export function headerMessage(cmd) {
|
|
15
5
|
console.clear();
|
|
16
6
|
cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
17
7
|
cmd.log("Opal Access Request ✏️");
|
|
@@ -27,19 +17,19 @@ MongoDB Atlas Test [App]
|
|
|
27
17
|
└── my-mongo-db-atlas [Resource]
|
|
28
18
|
└── admin:test [Role]
|
|
29
19
|
*/
|
|
30
|
-
function treeifyRequestMap(cmd, requestMap) {
|
|
20
|
+
export function treeifyRequestMap(cmd, requestMap) {
|
|
31
21
|
for (const [_appId, appNode] of Object.entries(requestMap)) {
|
|
32
22
|
// Print App title first (without tree lines)
|
|
33
|
-
cmd.log(`${
|
|
23
|
+
cmd.log(`${chalk.bold(appNode.appName)} ${chalk.dim("[App]")}`);
|
|
34
24
|
for (const [_assetId, assetNode] of Object.entries(appNode.assets)) {
|
|
35
25
|
// If okta/azure asset with no role, change asset name
|
|
36
26
|
const assetName = assetNode.assetName || "No Role (Direct access)";
|
|
37
|
-
cmd.log(`└── ${assetName} ${
|
|
27
|
+
cmd.log(`└── ${assetName} ${chalk.dim(`[${DisplayLabels[assetNode.type]}]`)}`);
|
|
38
28
|
if (assetNode.roles !== undefined) {
|
|
39
29
|
for (const [_roleId, roleNode] of Object.entries(assetNode.roles)) {
|
|
40
30
|
const roleName = roleNode.roleName;
|
|
41
31
|
if (roleName !== "") {
|
|
42
|
-
const roleKey = `${roleName} ${
|
|
32
|
+
const roleKey = `${roleName} ${chalk.dim("[Role]")}`;
|
|
43
33
|
cmd.log(` └── ${roleKey}`);
|
|
44
34
|
}
|
|
45
35
|
}
|
|
@@ -49,7 +39,7 @@ function treeifyRequestMap(cmd, requestMap) {
|
|
|
49
39
|
}
|
|
50
40
|
cmd.log();
|
|
51
41
|
}
|
|
52
|
-
function displayFinalRequestSummary(cmd, metadata) {
|
|
42
|
+
export function displayFinalRequestSummary(cmd, metadata) {
|
|
53
43
|
console.clear();
|
|
54
44
|
cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
55
45
|
cmd.log("Final Summary of Request ✏️");
|
|
@@ -60,36 +50,36 @@ function displayFinalRequestSummary(cmd, metadata) {
|
|
|
60
50
|
cmd.log(`Duration: ${durationInMinutes ? formatDuration(durationInMinutes) : "Permanent"}`);
|
|
61
51
|
const reason = metadata.reason;
|
|
62
52
|
if (reason) {
|
|
63
|
-
cmd.log(`Reason: "${
|
|
53
|
+
cmd.log(`Reason: "${chalk.italic(reason)}"`);
|
|
64
54
|
}
|
|
65
55
|
cmd.log();
|
|
66
56
|
}
|
|
67
|
-
function getStyledStatus(status) {
|
|
57
|
+
export function getStyledStatus(status) {
|
|
68
58
|
switch (status) {
|
|
69
59
|
case "PENDING": {
|
|
70
|
-
return `${
|
|
60
|
+
return `${chalk.bold("Status:")} ${chalk.blueBright(status)}`;
|
|
71
61
|
}
|
|
72
62
|
case "APPROVED": {
|
|
73
|
-
return `${
|
|
63
|
+
return `${chalk.bold("Status:")} ${chalk.greenBright(status)}`;
|
|
74
64
|
}
|
|
75
65
|
case "DENIED": {
|
|
76
|
-
return `${
|
|
66
|
+
return `${chalk.bold("Status:")} ${chalk.redBright(status)}`;
|
|
77
67
|
}
|
|
78
68
|
case "CANCELED": {
|
|
79
|
-
return `${
|
|
69
|
+
return `${chalk.bold("Status:")} ${chalk.redBright(status)}`;
|
|
80
70
|
}
|
|
81
71
|
default: {
|
|
82
|
-
return `${
|
|
72
|
+
return `${chalk.bold("Status:")} ${chalk.gray(status)}`;
|
|
83
73
|
}
|
|
84
74
|
}
|
|
85
75
|
}
|
|
86
|
-
function displayRequestDetails(cmd, requestResp) {
|
|
76
|
+
export function displayRequestDetails(cmd, requestResp) {
|
|
87
77
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
88
78
|
switch ((_a = requestResp.data) === null || _a === void 0 ? void 0 : _a.request.__typename) {
|
|
89
79
|
case "RequestResult": {
|
|
90
80
|
const request = requestResp.data.request.request;
|
|
91
81
|
cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
92
|
-
cmd.log(`Request Details ${
|
|
82
|
+
cmd.log(`Request Details ${chalk.cyan(request.id)}`);
|
|
93
83
|
cmd.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
94
84
|
const status = request.status;
|
|
95
85
|
cmd.log(getStyledStatus(status));
|
|
@@ -97,13 +87,13 @@ function displayRequestDetails(cmd, requestResp) {
|
|
|
97
87
|
const requester = (_b = request.requester) === null || _b === void 0 ? void 0 : _b.displayName;
|
|
98
88
|
const targetUser = (_c = request.targetUser) === null || _c === void 0 ? void 0 : _c.displayName;
|
|
99
89
|
if (requester && targetUser) {
|
|
100
|
-
cmd.log(`${
|
|
90
|
+
cmd.log(`${chalk.bold("Requested by:")} ${requester} ${chalk.gray("->")} ${chalk.bold("Requested for:")} ${targetUser}`);
|
|
101
91
|
}
|
|
102
92
|
const durationInMinutes = request.durationInMinutes;
|
|
103
|
-
cmd.log(`${
|
|
93
|
+
cmd.log(`${chalk.bold("Duration:")} ${durationInMinutes ? formatDuration(durationInMinutes) : "Permanent"}`);
|
|
104
94
|
const reason = request.reason;
|
|
105
95
|
if (reason) {
|
|
106
|
-
cmd.log(`${
|
|
96
|
+
cmd.log(`${chalk.bold("Reason:")} "${chalk.italic(reason)}"`);
|
|
107
97
|
}
|
|
108
98
|
// Requested resources
|
|
109
99
|
const requestedResources = (_e = (_d = request.requestedResources) === null || _d === void 0 ? void 0 : _d.map((resource) => {
|
|
@@ -122,12 +112,12 @@ function displayRequestDetails(cmd, requestResp) {
|
|
|
122
112
|
})) !== null && _g !== void 0 ? _g : [];
|
|
123
113
|
const requestedItems = [...requestedResources, ...requestedGroups].join(", ");
|
|
124
114
|
if (requestedItems) {
|
|
125
|
-
cmd.log(`${
|
|
115
|
+
cmd.log(`${chalk.bold("Requested Items:")} ${chalk.cyan(requestedItems)}`);
|
|
126
116
|
}
|
|
127
117
|
}
|
|
128
118
|
}
|
|
129
119
|
}
|
|
130
|
-
function displayRequestListTable(cmd, requestResp) {
|
|
120
|
+
export function displayRequestListTable(cmd, requestResp) {
|
|
131
121
|
var _a, _b, _c, _d, _e, _f;
|
|
132
122
|
switch ((_a = requestResp.data) === null || _a === void 0 ? void 0 : _a.requests.__typename) {
|
|
133
123
|
case "RequestsResult": {
|
|
@@ -193,7 +183,7 @@ function displayRequestListTable(cmd, requestResp) {
|
|
|
193
183
|
}
|
|
194
184
|
}
|
|
195
185
|
}
|
|
196
|
-
function formatDuration(durationInMinutes) {
|
|
186
|
+
export function formatDuration(durationInMinutes) {
|
|
197
187
|
const days = Math.floor(durationInMinutes / 1440);
|
|
198
188
|
const remainingMinutes = durationInMinutes % 1440;
|
|
199
189
|
const hours = Math.floor(remainingMinutes / 60);
|
|
@@ -217,7 +207,7 @@ function formatAssetName(assetName, roleName) {
|
|
|
217
207
|
}
|
|
218
208
|
return str;
|
|
219
209
|
}
|
|
220
|
-
function displayRequestAgain(cmd, id) {
|
|
221
|
-
cmd.log(
|
|
222
|
-
cmd.log(
|
|
210
|
+
export function displayRequestAgain(cmd, id) {
|
|
211
|
+
cmd.log(chalk.bold("\nTo request this again, run:"));
|
|
212
|
+
cmd.log(chalk.italic(` opal request create --template ${id}\n`));
|
|
223
213
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ApolloClient } from "@apollo/client";
|
|
2
2
|
import type { Command } from "@oclif/core";
|
|
3
|
-
import type { RequestMap } from "../types";
|
|
3
|
+
import type { RequestMap } from "../types.js";
|
|
4
4
|
export declare function selectRequestableItems(cmd: Command, client: ApolloClient, requestMap: RequestMap): Promise<void>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import enquirer from "enquirer-esm";
|
|
2
|
+
import { chooseAssets, chooseOktaAzureRoles, selectInstructions } from "./index.js";
|
|
3
|
+
import { queryRequestableApps } from "../api/index.js";
|
|
4
|
+
// @ts-expect-error - enquirer-esm doesn't export autocomplete in types but it exists at runtime
|
|
5
|
+
const { autocomplete } = enquirer;
|
|
6
|
+
export async function selectRequestableItems(cmd, client, requestMap) {
|
|
7
|
+
const initial = (await queryRequestableApps(cmd, client, "")) || [];
|
|
8
|
+
const app = await autocomplete({
|
|
9
|
+
name: "App",
|
|
10
|
+
message: "Select an app",
|
|
11
|
+
hint: selectInstructions,
|
|
12
|
+
limit: 15,
|
|
13
|
+
choices: initial,
|
|
14
|
+
async suggest(input) {
|
|
15
|
+
const filteredChoices = await queryRequestableApps(cmd, client, input || "");
|
|
16
|
+
return filteredChoices || initial;
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
// Set the app in the requestMap and call choose assets step
|
|
20
|
+
if (!(app.id in requestMap)) {
|
|
21
|
+
requestMap[app.id] = {
|
|
22
|
+
appId: app.id,
|
|
23
|
+
appType: app.type,
|
|
24
|
+
appName: app.name,
|
|
25
|
+
assets: {},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (app.type === "OKTA_APP" || app.type === "AZURE_ENTERPRISE_APP") {
|
|
29
|
+
await chooseOktaAzureRoles(cmd, client, app, requestMap);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
await chooseAssets(cmd, client, app.id, requestMap);
|
|
33
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ApolloClient } from "@apollo/client";
|
|
2
2
|
import type { Command } from "@oclif/core";
|
|
3
|
-
import { type EntityValue, type RequestMap } from "../types";
|
|
3
|
+
import { type EntityValue, type RequestMap } from "../types.js";
|
|
4
4
|
export declare function chooseOktaAzureRoles(cmd: Command, client: ApolloClient, app: EntityValue, requestMap: RequestMap): Promise<void>;
|
|
5
5
|
export declare function chooseAssets(cmd: Command, client: ApolloClient, appId: string, requestMap: RequestMap): Promise<void>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { chooseRoles, selectInstructions } from "./index.js";
|
|
2
|
+
import { queryAssociatedItems, queryRequestableAssets } from "../api/index.js";
|
|
3
|
+
import { entityTypeFromString, } from "../types.js";
|
|
4
|
+
import enquirer from "enquirer-esm";
|
|
5
|
+
// @ts-expect-error - enquirer-esm doesn't export autocomplete in types but it exists at runtime
|
|
6
|
+
const { autocomplete } = enquirer;
|
|
7
|
+
export async function chooseOktaAzureRoles(cmd, client, app, requestMap) {
|
|
8
|
+
const associatedItems = (await queryAssociatedItems(cmd, client, app.id, "")) || [];
|
|
9
|
+
const selectedRole = await autocomplete({
|
|
10
|
+
name: "Roles",
|
|
11
|
+
message: `Select a role for ${app.name}:`,
|
|
12
|
+
hint: selectInstructions,
|
|
13
|
+
limit: 15,
|
|
14
|
+
choices: associatedItems,
|
|
15
|
+
async suggest(input) {
|
|
16
|
+
if (!input)
|
|
17
|
+
return associatedItems;
|
|
18
|
+
const filteredChoices = await queryAssociatedItems(cmd, client, app.id, input);
|
|
19
|
+
return filteredChoices || associatedItems;
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
const entry = requestMap[app.id];
|
|
23
|
+
if (!(selectedRole.id in entry.assets)) {
|
|
24
|
+
entry.assets[selectedRole.id] = {
|
|
25
|
+
assetId: selectedRole.id,
|
|
26
|
+
assetName: selectedRole.name,
|
|
27
|
+
type: entityTypeFromString(selectedRole.type),
|
|
28
|
+
roles: {},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function chooseAssets(cmd, client, appId, requestMap) {
|
|
33
|
+
const initial = (await queryRequestableAssets(cmd, client, appId, "")) || [];
|
|
34
|
+
const selectedAsset = await autocomplete({
|
|
35
|
+
name: "Assets",
|
|
36
|
+
message: "Select an asset to request:",
|
|
37
|
+
hint: selectInstructions,
|
|
38
|
+
limit: 15,
|
|
39
|
+
async suggest(input) {
|
|
40
|
+
if (!input) {
|
|
41
|
+
return initial;
|
|
42
|
+
}
|
|
43
|
+
const filteredChoices = await queryRequestableAssets(cmd, client, appId, input);
|
|
44
|
+
return filteredChoices || initial;
|
|
45
|
+
},
|
|
46
|
+
choices: initial,
|
|
47
|
+
});
|
|
48
|
+
const entry = requestMap[appId];
|
|
49
|
+
if (entry === undefined) {
|
|
50
|
+
throw new Error(`Error formatting app ${appId} in request`);
|
|
51
|
+
}
|
|
52
|
+
if (!(selectedAsset.id in entry.assets)) {
|
|
53
|
+
entry.assets[selectedAsset.id] = {
|
|
54
|
+
assetId: selectedAsset.id,
|
|
55
|
+
assetName: selectedAsset.name,
|
|
56
|
+
type: selectedAsset.type,
|
|
57
|
+
roles: {},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
await chooseRoles(cmd, client, appId, selectedAsset.id, requestMap);
|
|
61
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { RequestMetadata } from "../types";
|
|
1
|
+
import type { RequestMetadata } from "../types.js";
|
|
2
2
|
export declare function promptForDuration(metadata: RequestMetadata): Promise<void>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
async function promptForDuration(metadata) {
|
|
1
|
+
import enquirer from "enquirer-esm";
|
|
2
|
+
// @ts-expect-error - enquirer-esm doesn't export list and form in types but they exist at runtime
|
|
3
|
+
const { autocomplete, form } = enquirer;
|
|
4
|
+
export async function promptForDuration(metadata) {
|
|
6
5
|
var _a, _b;
|
|
7
6
|
const durations = ((_b = (_a = metadata.requestDefaults) === null || _a === void 0 ? void 0 : _a.durationOptions) === null || _b === void 0 ? void 0 : _b.map((option) => {
|
|
8
7
|
var _a;
|
|
@@ -33,15 +32,13 @@ async function promptForDuration(metadata) {
|
|
|
33
32
|
return -1;
|
|
34
33
|
return a.value.durationInMinutes - b.value.durationInMinutes;
|
|
35
34
|
});
|
|
36
|
-
|
|
35
|
+
let selected = await autocomplete({
|
|
37
36
|
name: "expiration",
|
|
38
37
|
message: "When should access expire?",
|
|
39
38
|
hint: "Type to filter",
|
|
40
|
-
type: "list",
|
|
41
39
|
choices: durations,
|
|
42
40
|
pageSize: 15,
|
|
43
41
|
});
|
|
44
|
-
let selected = await expirationSelect.run();
|
|
45
42
|
switch (selected.label) {
|
|
46
43
|
case "Custom": {
|
|
47
44
|
selected = await setCustomDuration(metadata);
|
|
@@ -85,7 +82,7 @@ function getDHMFromMinutes(minutes) {
|
|
|
85
82
|
return label.join(" ");
|
|
86
83
|
}
|
|
87
84
|
async function setCustomDuration(metadata) {
|
|
88
|
-
const
|
|
85
|
+
const durationResult = await form({
|
|
89
86
|
name: "user",
|
|
90
87
|
message: "Please set a custom access duration:",
|
|
91
88
|
choices: [
|
|
@@ -114,7 +111,6 @@ async function setCustomDuration(metadata) {
|
|
|
114
111
|
return getDurationInMinutes(answer);
|
|
115
112
|
},
|
|
116
113
|
});
|
|
117
|
-
const durationResult = await durationForm.run();
|
|
118
114
|
const { d, h, m } = getDurationNumbers(durationResult);
|
|
119
115
|
const durationInMinutes = getDurationInMinutes(durationResult);
|
|
120
116
|
const durationLabel = getDHMFromMinutes(durationInMinutes);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { selectRequestableItems } from "./apps-prompt.js";
|
|
2
|
+
export { chooseOktaAzureRoles, chooseAssets } from "./asset-prompt.js";
|
|
3
|
+
export { chooseRoles } from "./role-prompt.js";
|
|
4
|
+
export { promptForReason } from "./reason-prompt.js";
|
|
5
|
+
export { promptForDuration } from "./duration-prompt.js";
|
|
6
|
+
export { doneSelectingAssets, promptRequestSubmission, } from "./validate-prompt.js";
|
|
7
|
+
export declare const selectInstructions: string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
export { selectRequestableItems } from "./apps-prompt.js";
|
|
3
|
+
export { chooseOktaAzureRoles, chooseAssets } from "./asset-prompt.js";
|
|
4
|
+
export { chooseRoles } from "./role-prompt.js";
|
|
5
|
+
export { promptForReason } from "./reason-prompt.js";
|
|
6
|
+
export { promptForDuration } from "./duration-prompt.js";
|
|
7
|
+
export { doneSelectingAssets, promptRequestSubmission, } from "./validate-prompt.js";
|
|
8
|
+
export const selectInstructions = chalk.dim("[↑↓] Navigate · [Enter] Select · Type to filter");
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { RequestMetadata } from "../types";
|
|
1
|
+
import type { RequestMetadata } from "../types.js";
|
|
2
2
|
export declare function promptForReason(metadata: RequestMetadata): Promise<void>;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const { prompt } = require("enquirer");
|
|
5
|
-
async function promptForReason(metadata) {
|
|
6
|
-
const { reason } = await prompt([
|
|
1
|
+
import enquirer from "enquirer-esm";
|
|
2
|
+
export async function promptForReason(metadata) {
|
|
3
|
+
const { reason } = await enquirer.prompt([
|
|
7
4
|
{
|
|
8
5
|
name: "reason",
|
|
9
6
|
message: "Why do you need access?",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ApolloClient } from "@apollo/client";
|
|
2
2
|
import type { Command } from "@oclif/core";
|
|
3
|
-
import type { RequestMap } from "../types";
|
|
3
|
+
import type { RequestMap } from "../types.js";
|
|
4
4
|
export declare function chooseRoles(cmd: Command, client: ApolloClient, appId: string, assetId: string, requestMap: RequestMap): Promise<void>;
|
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
async function chooseRoles(cmd, client, appId, assetId, requestMap) {
|
|
1
|
+
import enquirer from "enquirer-esm";
|
|
2
|
+
import { selectInstructions } from "./index.js";
|
|
3
|
+
import { queryAssetRoles } from "../api/index.js";
|
|
4
|
+
// @ts-expect-error - enquirer-esm doesn't export autocomplete in types but it exists at runtime
|
|
5
|
+
const { autocomplete } = enquirer;
|
|
6
|
+
export async function chooseRoles(cmd, client, appId, assetId, requestMap) {
|
|
8
7
|
var _a;
|
|
9
8
|
const entry = requestMap[appId];
|
|
10
9
|
const assetEntry = entry === null || entry === void 0 ? void 0 : entry.assets[assetId];
|
|
11
10
|
if (entry === undefined || assetEntry === undefined) {
|
|
12
11
|
throw new Error(`App ${appId} or Asset ${assetId} not found in requestMap`);
|
|
13
12
|
}
|
|
14
|
-
const assetRoles = (_a = (await
|
|
13
|
+
const assetRoles = (_a = (await queryAssetRoles(cmd, client, assetEntry.type, assetId))) !== null && _a !== void 0 ? _a : [];
|
|
15
14
|
if (assetRoles !== undefined &&
|
|
16
15
|
(assetRoles.length === 0 ||
|
|
17
16
|
(assetRoles.length === 1 && assetRoles[0].value.name === ""))) {
|
|
18
17
|
return;
|
|
19
18
|
}
|
|
20
|
-
const
|
|
19
|
+
const selectedRole = await autocomplete({
|
|
21
20
|
name: "Roles",
|
|
22
21
|
message: `Select a role for ${assetEntry.assetName}:`,
|
|
23
|
-
hint:
|
|
22
|
+
hint: selectInstructions,
|
|
24
23
|
limit: 15,
|
|
25
24
|
choices: assetRoles,
|
|
26
25
|
});
|
|
27
|
-
const selectedRole = await rolePrompt.run();
|
|
28
26
|
if (!assetEntry.roles) {
|
|
29
27
|
assetEntry.roles = {};
|
|
30
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Command } from "@oclif/core";
|
|
2
|
-
import type { RequestMetadata } from "../types";
|
|
2
|
+
import type { RequestMetadata } from "../types.js";
|
|
3
3
|
export declare function doneSelectingAssets(): Promise<boolean>;
|
|
4
4
|
export declare function promptRequestSubmission(cmd: Command, metadata: RequestMetadata): Promise<boolean>;
|
|
@@ -1,29 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const { Select } = require("enquirer");
|
|
7
|
-
async function doneSelectingAssets() {
|
|
1
|
+
import { displayFinalRequestSummary } from "../displays.js";
|
|
2
|
+
import enquirer from "enquirer-esm";
|
|
3
|
+
// @ts-expect-error - enquirer-esm doesn't export select in types but it exists at runtime
|
|
4
|
+
const { select } = enquirer;
|
|
5
|
+
export async function doneSelectingAssets() {
|
|
8
6
|
const submitMessage = "✅ Yes, proceed with request";
|
|
9
7
|
const addMoreMessage = "❌ No, add more items";
|
|
10
|
-
const
|
|
8
|
+
const submitOrAdd = await select({
|
|
11
9
|
name: "submitOrAdd",
|
|
12
10
|
message: "Is this all you want to request?",
|
|
13
11
|
choices: [submitMessage, addMoreMessage],
|
|
14
12
|
});
|
|
15
|
-
const submitOrAdd = await prompt.run();
|
|
16
13
|
return submitOrAdd === submitMessage;
|
|
17
14
|
}
|
|
18
|
-
async function promptRequestSubmission(cmd, metadata) {
|
|
19
|
-
|
|
15
|
+
export async function promptRequestSubmission(cmd, metadata) {
|
|
16
|
+
displayFinalRequestSummary(cmd, metadata);
|
|
20
17
|
const submitMessage = "✅ Yes, submit request";
|
|
21
18
|
const cancelMessage = "❌ No, cancel request";
|
|
22
|
-
const
|
|
19
|
+
const submitOrCancel = await select({
|
|
23
20
|
name: "submitOrCancel",
|
|
24
21
|
message: "Is this all you want to request?",
|
|
25
22
|
choices: [submitMessage, cancelMessage],
|
|
26
23
|
});
|
|
27
|
-
const submitOrCancel = await prompt.run();
|
|
28
24
|
return submitOrCancel === submitMessage;
|
|
29
25
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ApolloClient } from "@apollo/client";
|
|
2
2
|
import type { Command } from "@oclif/core";
|
|
3
|
-
import { type ConnectionType, RequestMessageCode } from "../../graphql/graphql";
|
|
4
|
-
import { type RequestMap, type RequestMetadata } from "./types";
|
|
3
|
+
import { type ConnectionType, RequestMessageCode } from "../../graphql/graphql.js";
|
|
4
|
+
import { type RequestMap, type RequestMetadata } from "./types.js";
|
|
5
5
|
export declare function initEmptyRequestMetadata(): RequestMetadata;
|
|
6
6
|
export declare function setRequestDefaults(cmd: Command, client: ApolloClient, metadata: RequestMetadata): Promise<void>;
|
|
7
7
|
export declare function submitFinalRequest(cmd: Command, client: ApolloClient, metadata: RequestMetadata): Promise<void>;
|