opal-security 2.0.8 → 2.0.11
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 +13 -13
- package/lib/commands/curl-example.js +3 -1
- package/lib/commands/login.js +98 -3
- package/lib/handler.d.ts +4 -4
- package/lib/lib/apollo.js +11 -10
- package/lib/lib/credentials.d.ts +4 -2
- package/lib/lib/credentials.js +42 -1
- package/lib/types.d.ts +2727 -484
- package/lib/types.js +265 -69
- package/oclif.manifest.json +1 -1
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ $ npm install -g opal-security
|
|
|
22
22
|
$ opal COMMAND
|
|
23
23
|
running command...
|
|
24
24
|
$ opal (-v|--version|version)
|
|
25
|
-
opal-security/2.0.
|
|
25
|
+
opal-security/2.0.11 darwin-x64 node-v14.16.1
|
|
26
26
|
$ opal --help [COMMAND]
|
|
27
27
|
USAGE
|
|
28
28
|
$ opal COMMAND
|
|
@@ -86,7 +86,7 @@ EXAMPLE
|
|
|
86
86
|
opal aws:identity
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
_See code: [src/commands/aws/identity.ts](https://github.com/
|
|
89
|
+
_See code: [src/commands/aws/identity.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/aws/identity.ts)_
|
|
90
90
|
|
|
91
91
|
## `opal curl-example`
|
|
92
92
|
|
|
@@ -100,7 +100,7 @@ OPTIONS
|
|
|
100
100
|
-h, --help show CLI help
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
_See code: [src/commands/curl-example.ts](https://github.com/
|
|
103
|
+
_See code: [src/commands/curl-example.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/curl-example.ts)_
|
|
104
104
|
|
|
105
105
|
## `opal help [COMMAND]`
|
|
106
106
|
|
|
@@ -136,7 +136,7 @@ EXAMPLES
|
|
|
136
136
|
opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
_See code: [src/commands/iam-roles/start.ts](https://github.com/
|
|
139
|
+
_See code: [src/commands/iam-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/iam-roles/start.ts)_
|
|
140
140
|
|
|
141
141
|
## `opal kube-roles:start`
|
|
142
142
|
|
|
@@ -158,7 +158,7 @@ EXAMPLES
|
|
|
158
158
|
"arn:aws:iam::712234975475:role/acme-eks-cluster-admin-role"
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
-
_See code: [src/commands/kube-roles/start.ts](https://github.com/
|
|
161
|
+
_See code: [src/commands/kube-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/kube-roles/start.ts)_
|
|
162
162
|
|
|
163
163
|
## `opal login`
|
|
164
164
|
|
|
@@ -175,7 +175,7 @@ EXAMPLE
|
|
|
175
175
|
$ opal login
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
_See code: [src/commands/login.ts](https://github.com/
|
|
178
|
+
_See code: [src/commands/login.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/login.ts)_
|
|
179
179
|
|
|
180
180
|
## `opal logout`
|
|
181
181
|
|
|
@@ -192,7 +192,7 @@ EXAMPLE
|
|
|
192
192
|
$ opal logout
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
_See code: [src/commands/logout.ts](https://github.com/
|
|
195
|
+
_See code: [src/commands/logout.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/logout.ts)_
|
|
196
196
|
|
|
197
197
|
## `opal postgres-instances:start`
|
|
198
198
|
|
|
@@ -213,7 +213,7 @@ EXAMPLES
|
|
|
213
213
|
opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId "fullaccess"
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
-
_See code: [src/commands/postgres-instances/start.ts](https://github.com/
|
|
216
|
+
_See code: [src/commands/postgres-instances/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/postgres-instances/start.ts)_
|
|
217
217
|
|
|
218
218
|
## `opal resources:get`
|
|
219
219
|
|
|
@@ -231,7 +231,7 @@ EXAMPLE
|
|
|
231
231
|
opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
_See code: [src/commands/resources/get.ts](https://github.com/
|
|
234
|
+
_See code: [src/commands/resources/get.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/resources/get.ts)_
|
|
235
235
|
|
|
236
236
|
## `opal set-url`
|
|
237
237
|
|
|
@@ -254,7 +254,7 @@ EXAMPLE
|
|
|
254
254
|
$ opal set-host
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
-
_See code: [src/commands/set-url.ts](https://github.com/
|
|
257
|
+
_See code: [src/commands/set-url.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/set-url.ts)_
|
|
258
258
|
|
|
259
259
|
## `opal ssh:copyFrom`
|
|
260
260
|
|
|
@@ -280,7 +280,7 @@ EXAMPLES
|
|
|
280
280
|
opal ssh:copyFrom --src instance/dir --dest my/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
281
281
|
```
|
|
282
282
|
|
|
283
|
-
_See code: [src/commands/ssh/copyFrom.ts](https://github.com/
|
|
283
|
+
_See code: [src/commands/ssh/copyFrom.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/ssh/copyFrom.ts)_
|
|
284
284
|
|
|
285
285
|
## `opal ssh:copyTo`
|
|
286
286
|
|
|
@@ -306,7 +306,7 @@ EXAMPLES
|
|
|
306
306
|
opal ssh:copyTo --src my/dir --dest instance/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
307
307
|
```
|
|
308
308
|
|
|
309
|
-
_See code: [src/commands/ssh/copyTo.ts](https://github.com/
|
|
309
|
+
_See code: [src/commands/ssh/copyTo.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/ssh/copyTo.ts)_
|
|
310
310
|
|
|
311
311
|
## `opal ssh:start`
|
|
312
312
|
|
|
@@ -325,5 +325,5 @@ EXAMPLES
|
|
|
325
325
|
opal ssh:start --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
326
326
|
```
|
|
327
327
|
|
|
328
|
-
_See code: [src/commands/ssh/start.ts](https://github.com/
|
|
328
|
+
_See code: [src/commands/ssh/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.11/src/commands/ssh/start.ts)_
|
|
329
329
|
<!-- commandsstop -->
|
|
@@ -6,13 +6,15 @@ const credentials_1 = require("../lib/credentials");
|
|
|
6
6
|
class CurlExample extends command_1.Command {
|
|
7
7
|
async run() {
|
|
8
8
|
const accessToken = await credentials_1.cred.accessToken;
|
|
9
|
+
const organizationID = await credentials_1.cred.organizationID;
|
|
9
10
|
const configData = config_1.getOrCreateConfigData(this.config.configDir);
|
|
10
11
|
const url = configData[config_1.urlKey];
|
|
11
12
|
this.log(`
|
|
12
13
|
curl -v ${url}/query \\
|
|
13
14
|
--data-binary '{"query":"query ListSSHSessions {resources(input: {serviceType: SSH, onlyMine: true}) {... on ResourcesResult { resources { name } } } }"}' \\
|
|
14
15
|
--header "Content-Type: application/json" \\
|
|
15
|
-
--header "Authorization: Bearer ${accessToken}"
|
|
16
|
+
--header "Authorization: Bearer ${accessToken}" \\
|
|
17
|
+
--header "X-Opal-Organization-ID: ${organizationID}"
|
|
16
18
|
`);
|
|
17
19
|
}
|
|
18
20
|
}
|
package/lib/commands/login.js
CHANGED
|
@@ -6,12 +6,91 @@ const open = require("open");
|
|
|
6
6
|
const openid_client_1 = require("openid-client");
|
|
7
7
|
const apollo_1 = require("../lib/apollo");
|
|
8
8
|
const credentials_1 = require("../lib/credentials");
|
|
9
|
+
const inquirer = require("inquirer");
|
|
10
|
+
const handler_1 = require("../handler");
|
|
11
|
+
const credentials_2 = require("../lib/credentials");
|
|
12
|
+
const config_1 = require("../lib/config");
|
|
9
13
|
const ISSUER = 'https://auth.opal.dev';
|
|
10
14
|
const GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
11
15
|
const CLIENT_ID = '42rm6E5v7o67LBpRfjdT9KhnjrQHr9UF';
|
|
16
|
+
const CLISignInMethodDocument = `
|
|
17
|
+
query CLISignInMethod($input: SignInMethodInput!) {
|
|
18
|
+
signInMethod(input: $input) {
|
|
19
|
+
__typename
|
|
20
|
+
... on SignInMethodResult {
|
|
21
|
+
signInOrganizations {
|
|
22
|
+
organizationId
|
|
23
|
+
organizationName
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}`;
|
|
28
|
+
const CLIAuthSessionCheckDocument = `
|
|
29
|
+
query CLIAuthSessionCheck {
|
|
30
|
+
organizationSettings {
|
|
31
|
+
... on OrganizationSettingsResult {
|
|
32
|
+
settings {
|
|
33
|
+
id
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
12
39
|
class Login extends command_1.Command {
|
|
13
40
|
async run() {
|
|
41
|
+
var _a, _b, _c, _d, _e;
|
|
14
42
|
try {
|
|
43
|
+
await apollo_1.initClient(this);
|
|
44
|
+
let email;
|
|
45
|
+
let organizationID;
|
|
46
|
+
if (await credentials_2.cred.accessToken) {
|
|
47
|
+
email = await credentials_2.cred.email;
|
|
48
|
+
organizationID = await credentials_2.cred.organizationID;
|
|
49
|
+
await credentials_2.cred.removeCredentials(-1);
|
|
50
|
+
}
|
|
51
|
+
const configDir = this.config.configDir;
|
|
52
|
+
const configData = config_1.getOrCreateConfigData(configDir);
|
|
53
|
+
if (email && organizationID) {
|
|
54
|
+
console.log('Signing in as ' + email + ' - to use a different account, run `opal logout`');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.log('Welcome to Opal! ⚡️\n');
|
|
58
|
+
this.log('Please confirm your Opal instance URL:', configData[config_1.urlKey]);
|
|
59
|
+
this.log('If this is not correct, please first use `opal set-url --help`\n');
|
|
60
|
+
const { email: promptEmail } = await inquirer.prompt([{
|
|
61
|
+
name: 'email',
|
|
62
|
+
message: 'Enter your email:',
|
|
63
|
+
type: 'input',
|
|
64
|
+
validate: email => Boolean(email),
|
|
65
|
+
}]);
|
|
66
|
+
email = promptEmail;
|
|
67
|
+
const { resp: signInOrganizationsResponse, error } = await handler_1.runQuery({
|
|
68
|
+
command: this,
|
|
69
|
+
query: CLISignInMethodDocument,
|
|
70
|
+
variables: { input: { email } },
|
|
71
|
+
});
|
|
72
|
+
if (error) {
|
|
73
|
+
this.log('Could not connect to Opal. Did you set the right URL? (`opal set-url --help`)');
|
|
74
|
+
}
|
|
75
|
+
const signInOrganizations = (_b = (_a = signInOrganizationsResponse === null || signInOrganizationsResponse === void 0 ? void 0 : signInOrganizationsResponse.data) === null || _a === void 0 ? void 0 : _a.signInMethod) === null || _b === void 0 ? void 0 : _b.signInOrganizations;
|
|
76
|
+
if (signInOrganizations) {
|
|
77
|
+
if (signInOrganizations.length === 1) {
|
|
78
|
+
organizationID = signInOrganizations[0].organizationId;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const responses = await inquirer.prompt([{
|
|
82
|
+
name: 'organizationID',
|
|
83
|
+
message: 'Select an organization:',
|
|
84
|
+
type: 'list',
|
|
85
|
+
choices: signInOrganizations.map(signInOrganization => ({
|
|
86
|
+
name: signInOrganization.organizationName,
|
|
87
|
+
value: signInOrganization.organizationId,
|
|
88
|
+
})),
|
|
89
|
+
}]);
|
|
90
|
+
organizationID = responses.organizationID;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
15
94
|
const issuer = await openid_client_1.Issuer.discover(ISSUER);
|
|
16
95
|
const client = new issuer.Client({
|
|
17
96
|
grant_types: [GRANT_TYPE],
|
|
@@ -25,13 +104,29 @@ class Login extends command_1.Command {
|
|
|
25
104
|
audience: 'https://opal.dev',
|
|
26
105
|
scope: 'openid email profile',
|
|
27
106
|
});
|
|
28
|
-
this.log('
|
|
107
|
+
this.log('\nYou are being redirected to your browser to authenticate.\n');
|
|
29
108
|
this.log(` User Code: ${handle.user_code}\n`);
|
|
109
|
+
// Wait 2 seconds to show the user code clearly
|
|
110
|
+
const sleep = (ms) => {
|
|
111
|
+
return new Promise(resolve => {
|
|
112
|
+
setTimeout(resolve, ms);
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
await sleep(2000);
|
|
30
116
|
await open(handle.verification_uri_complete, { wait: false });
|
|
31
117
|
const tokenSet = await handle.poll();
|
|
32
118
|
const userInfo = await client.userinfo(tokenSet);
|
|
33
|
-
await keytar.setPassword(credentials_1.OPAL_CREDS_KEY, userInfo.email || 'unset-email', (tokenSet === null || tokenSet === void 0 ? void 0 : tokenSet.access_token) || '');
|
|
34
|
-
|
|
119
|
+
await keytar.setPassword(credentials_1.OPAL_CREDS_KEY, (userInfo.email || 'unset-email') + '|' + organizationID, (tokenSet === null || tokenSet === void 0 ? void 0 : tokenSet.access_token) || '');
|
|
120
|
+
// "Representative" authenticated call to check the log-in worked as expected.
|
|
121
|
+
const { resp: authCheckResp, error: authCheckErr } = await handler_1.runQuery({
|
|
122
|
+
command: this,
|
|
123
|
+
query: CLIAuthSessionCheckDocument,
|
|
124
|
+
variables: {},
|
|
125
|
+
});
|
|
126
|
+
if (authCheckErr || !((_e = (_d = (_c = authCheckResp === null || authCheckResp === void 0 ? void 0 : authCheckResp.data) === null || _c === void 0 ? void 0 : _c.organizationSettings) === null || _d === void 0 ? void 0 : _d.settings) === null || _e === void 0 ? void 0 : _e.id)) {
|
|
127
|
+
this.log('Error verifying log in. Authenticated commands may fail. Please double check your URL and use `opal logout; opal login` to try again.\n');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
35
130
|
this.log('🎉 You have successfully authenticated with Opal! You can now run authenticated commands.\n');
|
|
36
131
|
}
|
|
37
132
|
catch (error) {
|
package/lib/handler.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Command } from '@oclif/command';
|
|
2
|
-
interface QueryHandlerProps {
|
|
2
|
+
interface QueryHandlerProps<TVar = Record<string, any>> {
|
|
3
3
|
command: Command;
|
|
4
4
|
query: string;
|
|
5
|
-
variables?:
|
|
5
|
+
variables?: TVar;
|
|
6
6
|
}
|
|
7
7
|
export declare const runMutation: ({ command, query, variables, }: QueryHandlerProps) => Promise<{
|
|
8
8
|
resp: import("@apollo/client/core").FetchResult<any, Record<string, any>, Record<string, any>> | null;
|
|
9
9
|
error: any;
|
|
10
10
|
}>;
|
|
11
|
-
export declare const runQuery: ({ command, query, variables, }: QueryHandlerProps) => Promise<{
|
|
12
|
-
resp: import("@apollo/client/core").ApolloQueryResult<
|
|
11
|
+
export declare const runQuery: <TResponse = any, TVar = Record<string, any>>({ command, query, variables, }: QueryHandlerProps<TVar>) => Promise<{
|
|
12
|
+
resp: import("@apollo/client/core").ApolloQueryResult<TResponse> | null;
|
|
13
13
|
error: any;
|
|
14
14
|
}>;
|
|
15
15
|
declare const handler: ({ command, query, variables }: QueryHandlerProps) => void;
|
package/lib/lib/apollo.js
CHANGED
|
@@ -21,6 +21,7 @@ exports.initClient = async (command) => {
|
|
|
21
21
|
const currentCLIVersion = command.config.version;
|
|
22
22
|
const configData = config_1.getOrCreateConfigData(configDir);
|
|
23
23
|
const accessToken = await credentials_1.cred.accessToken;
|
|
24
|
+
const organizationID = await credentials_1.cred.organizationID;
|
|
24
25
|
const httpsAgent = new https.Agent({
|
|
25
26
|
rejectUnauthorized: !configData[config_1.allowSelfSignedCertsKey],
|
|
26
27
|
});
|
|
@@ -36,7 +37,7 @@ exports.initClient = async (command) => {
|
|
|
36
37
|
});
|
|
37
38
|
const authLink = context_1.setContext((_, { headers }) => {
|
|
38
39
|
return {
|
|
39
|
-
headers: Object.assign(Object.assign({}, headers), { authorization: `Bearer ${accessToken}
|
|
40
|
+
headers: Object.assign(Object.assign({}, headers), { authorization: `Bearer ${accessToken}`, 'X-Opal-Organization-ID': organizationID }),
|
|
40
41
|
};
|
|
41
42
|
});
|
|
42
43
|
const checkCLIVersion = (operation) => {
|
|
@@ -44,15 +45,15 @@ exports.initClient = async (command) => {
|
|
|
44
45
|
const headers = (_a = operation.getContext().response) === null || _a === void 0 ? void 0 : _a.headers;
|
|
45
46
|
if (headers) {
|
|
46
47
|
const expectedCLIMajorVersion = headers.get('Opal-CLI-Expected-Major-Version');
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
if (expectedCLIMajorVersion) {
|
|
49
|
+
const semvarExpectedMinCLIVersion = `${expectedCLIMajorVersion}.0.0`;
|
|
50
|
+
if (semver_1.major(currentCLIVersion) < semver_1.major(semvarExpectedMinCLIVersion)) {
|
|
51
|
+
command.warn(chalk_1.default.yellow(`❗️ Update your CLI to match the compatible version. Expected major version ${chalk_1.default.blueBright(semvarExpectedMinCLIVersion)}, but version ${chalk_1.default.blueBright(currentCLIVersion)} is installed.
|
|
52
|
+
Upgrade using the following command: ${chalk_1.default.blueBright('brew upgrade opalsecurity/brew/opal-security')}`));
|
|
53
|
+
}
|
|
54
|
+
else if (semver_1.major(currentCLIVersion) > semver_1.major(semvarExpectedMinCLIVersion)) {
|
|
55
|
+
command.warn(chalk_1.default.yellow('❗️ Uh oh! The currently installed Opal server is outdated. Please contact your Opal admins to let them know they need to upgrade their deployment.'));
|
|
56
|
+
}
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
};
|
package/lib/lib/credentials.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const OPAL_CREDS_KEY = "opal";
|
|
2
2
|
export declare const cred: {
|
|
3
3
|
removeCredentials(after: number): Promise<void>;
|
|
4
|
-
readonly accountId: Promise<string>;
|
|
5
|
-
readonly
|
|
4
|
+
readonly accountId: Promise<string | undefined>;
|
|
5
|
+
readonly organizationID: Promise<string | undefined>;
|
|
6
|
+
readonly email: Promise<string | undefined>;
|
|
7
|
+
readonly accessToken: Promise<string | undefined>;
|
|
6
8
|
};
|
package/lib/lib/credentials.js
CHANGED
|
@@ -20,6 +20,9 @@ exports.cred = {
|
|
|
20
20
|
return (async () => {
|
|
21
21
|
try {
|
|
22
22
|
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
23
|
+
if (!keyContents[0]) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
23
26
|
const { account } = keyContents[0];
|
|
24
27
|
return account;
|
|
25
28
|
}
|
|
@@ -28,12 +31,50 @@ exports.cred = {
|
|
|
28
31
|
}
|
|
29
32
|
})();
|
|
30
33
|
},
|
|
34
|
+
get organizationID() {
|
|
35
|
+
return (async () => {
|
|
36
|
+
try {
|
|
37
|
+
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
38
|
+
if (!keyContents[0]) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const { account } = keyContents[0];
|
|
42
|
+
const parts = account.split('|');
|
|
43
|
+
if (!parts || parts.length <= 1) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
return parts.pop();
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
})();
|
|
52
|
+
},
|
|
53
|
+
get email() {
|
|
54
|
+
return (async () => {
|
|
55
|
+
try {
|
|
56
|
+
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
57
|
+
if (!keyContents[0]) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const { account } = keyContents[0];
|
|
61
|
+
const parts = account.split('|');
|
|
62
|
+
if (!parts || parts.length <= 1) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
return parts[0];
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
})();
|
|
71
|
+
},
|
|
31
72
|
get accessToken() {
|
|
32
73
|
return (async () => {
|
|
33
74
|
try {
|
|
34
75
|
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
35
76
|
if (!keyContents[0]) {
|
|
36
|
-
return
|
|
77
|
+
return undefined;
|
|
37
78
|
}
|
|
38
79
|
const { password } = keyContents[0];
|
|
39
80
|
return password;
|