opal-security 2.3.4 → 3.0.1-beta.4262451

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 (69) hide show
  1. package/README.md +67 -38
  2. package/lib/commands/aws/identity.d.ts +1 -1
  3. package/lib/commands/aws/identity.js +2 -2
  4. package/lib/commands/{migrate-creds.d.ts → clear-auth-provider.d.ts} +3 -2
  5. package/lib/commands/clear-auth-provider.js +28 -0
  6. package/lib/commands/curl-example.d.ts +1 -1
  7. package/lib/commands/curl-example.js +10 -3
  8. package/lib/commands/iam-roles/start.d.ts +1 -1
  9. package/lib/commands/iam-roles/start.js +14 -14
  10. package/lib/commands/kube-roles/start.d.ts +1 -1
  11. package/lib/commands/kube-roles/start.js +10 -10
  12. package/lib/commands/login.d.ts +2 -1
  13. package/lib/commands/login.js +134 -74
  14. package/lib/commands/logout.d.ts +1 -1
  15. package/lib/commands/logout.js +3 -3
  16. package/lib/commands/postgres-instances/start.d.ts +1 -1
  17. package/lib/commands/postgres-instances/start.js +35 -34
  18. package/lib/commands/resources/get.d.ts +1 -1
  19. package/lib/commands/resources/get.js +6 -4
  20. package/lib/commands/set-auth-provider.d.ts +11 -0
  21. package/lib/commands/set-auth-provider.js +44 -0
  22. package/lib/commands/set-custom-header.d.ts +1 -1
  23. package/lib/commands/set-custom-header.js +5 -3
  24. package/lib/commands/set-token.d.ts +1 -1
  25. package/lib/commands/set-token.js +26 -19
  26. package/lib/commands/set-url.d.ts +1 -1
  27. package/lib/commands/set-url.js +13 -12
  28. package/lib/commands/ssh/copyFrom.d.ts +1 -1
  29. package/lib/commands/ssh/copyFrom.js +13 -13
  30. package/lib/commands/ssh/copyTo.d.ts +1 -1
  31. package/lib/commands/ssh/copyTo.js +13 -13
  32. package/lib/commands/ssh/start.d.ts +1 -1
  33. package/lib/commands/ssh/start.js +14 -15
  34. package/lib/graphql/fragment-masking.d.ts +19 -0
  35. package/lib/graphql/fragment-masking.js +21 -0
  36. package/lib/graphql/gql.d.ts +36 -0
  37. package/lib/graphql/gql.js +12 -0
  38. package/lib/graphql/graphql.d.ts +11413 -0
  39. package/lib/graphql/graphql.js +1491 -0
  40. package/lib/graphql/index.d.ts +2 -0
  41. package/lib/graphql/index.js +5 -0
  42. package/lib/handler.d.ts +5 -5
  43. package/lib/handler.js +7 -7
  44. package/lib/index.d.ts +1 -1
  45. package/lib/lib/apollo.d.ts +4 -2
  46. package/lib/lib/apollo.js +107 -55
  47. package/lib/lib/aws.js +15 -12
  48. package/lib/lib/cmd.d.ts +4 -6
  49. package/lib/lib/cmd.js +11 -11
  50. package/lib/lib/config.js +14 -15
  51. package/lib/lib/credentials/index.d.ts +9 -4
  52. package/lib/lib/credentials/index.js +26 -15
  53. package/lib/lib/credentials/keychain.d.ts +3 -3
  54. package/lib/lib/credentials/keychain.js +12 -12
  55. package/lib/lib/credentials/localEncryption.d.ts +3 -3
  56. package/lib/lib/credentials/localEncryption.js +40 -31
  57. package/lib/lib/flags.js +9 -9
  58. package/lib/lib/resources.d.ts +2 -2
  59. package/lib/lib/resources.js +29 -23
  60. package/lib/lib/sessions.d.ts +2 -2
  61. package/lib/lib/sessions.js +18 -17
  62. package/lib/lib/ssh.d.ts +1 -1
  63. package/lib/lib/ssh.js +8 -8
  64. package/lib/lib/util.d.ts +0 -1
  65. package/lib/lib/util.js +13 -13
  66. package/lib/types.d.ts +1787 -1787
  67. package/oclif.manifest.json +56 -7
  68. package/package.json +23 -29
  69. package/lib/commands/migrate-creds.js +0 -48
@@ -1,21 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CLIAuthSessionCheckDocument = exports.CLIAuthSessionCheckName = exports.CLISignInMethodName = void 0;
3
+ exports.CLITokenExchangeName = exports.CLIAuthSessionCheckDocument = exports.CLIAuthSessionCheckName = exports.CLISignInMethodName = void 0;
4
4
  const core_1 = require("@oclif/core");
5
5
  const open = require("open");
6
6
  const openid_client_1 = require("openid-client");
7
- const apollo_1 = require("../lib/apollo");
8
- const credentials_1 = require("../lib/credentials");
9
7
  const inquirer = require("inquirer");
10
8
  const handler_1 = require("../handler");
9
+ const apollo_1 = require("../lib/apollo");
11
10
  const config_1 = require("../lib/config");
12
- const util_1 = require("../lib/util");
11
+ const credentials_1 = require("../lib/credentials");
13
12
  const flags_1 = require("../lib/flags");
14
- const ISSUER_PROD = 'https://auth.opal.dev';
15
- const ISSUER_DEV = 'https://authdev.opal.dev';
16
- const GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code';
17
- const CLIENT_ID_PROD = '42rm6E5v7o67LBpRfjdT9KhnjrQHr9UF';
18
- const CLIENT_ID_DEV = 'XYV8qoAvZG7dHnhRp2g5XMJ1zX9fBP6s';
13
+ const util_1 = require("../lib/util");
14
+ const ISSUER_PROD = "https://auth.opal.dev";
15
+ const ISSUER_DEV = "https://authdev.opal.dev";
16
+ const GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
17
+ const CLIENT_ID_PROD = "42rm6E5v7o67LBpRfjdT9KhnjrQHr9UF";
18
+ const CLIENT_ID_DEV = "XYV8qoAvZG7dHnhRp2g5XMJ1zX9fBP6s";
19
19
  const CLISignInMethodDocumentLegacy = `
20
20
  query CLISignInMethod($input: SignInMethodInput!) {
21
21
  signInMethod(input: $input) {
@@ -28,7 +28,7 @@ query CLISignInMethod($input: SignInMethodInput!) {
28
28
  }
29
29
  }
30
30
  }`;
31
- exports.CLISignInMethodName = 'CLISignInMethod';
31
+ exports.CLISignInMethodName = "CLISignInMethod";
32
32
  const CLISignInMethodDocument = `
33
33
  query CLISignInMethod($input: SignInMethodInput!) {
34
34
  signInMethod(input: $input) {
@@ -42,7 +42,7 @@ query CLISignInMethod($input: SignInMethodInput!) {
42
42
  }
43
43
  }
44
44
  }`;
45
- exports.CLIAuthSessionCheckName = 'CLIAuthSessionCheck';
45
+ exports.CLIAuthSessionCheckName = "CLIAuthSessionCheck";
46
46
  exports.CLIAuthSessionCheckDocument = `
47
47
  query CLIAuthSessionCheck {
48
48
  organizationSettings {
@@ -54,6 +54,30 @@ query CLIAuthSessionCheck {
54
54
  }
55
55
  }
56
56
  `;
57
+ const SignInDocument = `
58
+ mutation SignIn($input: SignInInput!) {
59
+ signIn(input: $input) {
60
+ __typename
61
+ ... on SignInResult {
62
+ state
63
+ forceExtraStep
64
+ authURL
65
+ __typename
66
+ }
67
+ }
68
+ }
69
+ `;
70
+ exports.CLITokenExchangeName = "CLITokenExchange";
71
+ const CLITokenExchangeDocument = `
72
+ mutation CLITokenExchange($input: CLITokenExchangeInput!) {
73
+ cliTokenExchange(input: $input) {
74
+ __typename
75
+ ... on CLITokenExchangeOutput {
76
+ sessionID
77
+ }
78
+ }
79
+ }
80
+ `;
57
81
  class Login extends core_1.Command {
58
82
  async run() {
59
83
  var _a, _b, _c, _d, _e, _f, _g;
@@ -63,75 +87,84 @@ class Login extends core_1.Command {
63
87
  const configDir = this.config.configDir;
64
88
  const configData = (0, config_1.getOrCreateConfigData)(configDir);
65
89
  let email = flags.email;
66
- let organizationID;
67
- let clientIdCandidate;
90
+ let organizationId;
91
+ let clientIDCandidate;
68
92
  const existingCreds = await (0, credentials_1.getOpalCredentials)(this, false);
69
93
  // Only use the previous email + organizationID if email isn't explicitly specified.
70
94
  if (!email) {
71
95
  email = existingCreds.email;
72
- organizationID = existingCreds.organizationID;
73
- clientIdCandidate = existingCreds.clientIDCandidate;
96
+ organizationId = existingCreds.organizationID;
97
+ clientIDCandidate = existingCreds.clientIDCandidate;
74
98
  }
75
99
  await (0, credentials_1.removeOpalCredentials)(this);
76
- this.log('Welcome to Opal! ⚡️\n');
77
- this.log('Connecting to Opal server URL:', configData[config_1.urlKey]);
78
- this.log('If this is incorrect, please run `opal set-url --help`\n');
100
+ this.log("Welcome to Opal! ⚡\n");
101
+ this.log("Connecting to Opal server URL:", configData[config_1.urlKey]);
102
+ this.log("If this is incorrect, please run `opal set-url --help`\n");
79
103
  if (email) {
80
- this.log('Signing in as: ' + email + ' - to use a different account, run `opal login --email [EMAIL]`');
104
+ this.log(`Signing in as: ${email} - to use a different account, run \`opal login --email [EMAIL]\``);
81
105
  }
82
106
  else {
83
- const { email: promptEmail } = await inquirer.prompt([{
84
- name: 'email',
85
- message: 'Enter your email:',
86
- type: 'input',
87
- validate: email => Boolean(email),
88
- }]);
107
+ const { email: promptEmail } = await inquirer.prompt([
108
+ {
109
+ name: "email",
110
+ message: "Enter your email:",
111
+ type: "input",
112
+ validate: (email) => Boolean(email),
113
+ },
114
+ ]);
89
115
  email = promptEmail;
90
116
  }
91
- if (!organizationID) {
117
+ if (!organizationId) {
92
118
  let signInOrganizationsLegacyResponse;
93
- const { resp: signInOrganizationsResponse, error } = await (0, handler_1.runQuery)({
119
+ const { resp: signInOrganizationsResponse, error } = await (0, handler_1.runQueryDeprecated)({
94
120
  command: this,
95
121
  query: CLISignInMethodDocument,
96
122
  variables: { input: { email } },
97
123
  });
98
- if (error && error.networkError) {
99
- if ('statusCode' in error.networkError && error.networkError.statusCode === 422) {
100
- const { resp, error: legacyError } = await (0, handler_1.runQuery)({
124
+ if (error === null || error === void 0 ? void 0 : error.networkError) {
125
+ if ("statusCode" in error.networkError &&
126
+ error.networkError.statusCode === 422) {
127
+ const { resp, error: legacyError } = await (0, handler_1.runQueryDeprecated)({
101
128
  command: this,
102
129
  query: CLISignInMethodDocumentLegacy,
103
130
  variables: { input: { email } },
104
131
  });
105
132
  signInOrganizationsLegacyResponse = resp;
106
133
  if (legacyError) {
107
- this.log(''); // Intentional newline
108
- return (0, apollo_1.handleError)(this, 'Could not connect to Opal. Did you set the right URL? (`opal set-url --help`)');
134
+ this.log(""); // Intentional newline
135
+ return (0, apollo_1.handleError)(this, "Could not connect to Opal. Did you set the right URL? (`opal set-url --help`)");
109
136
  }
110
137
  }
111
138
  else {
112
- this.log(''); // Intentional newline
113
- return (0, apollo_1.handleError)(this, 'Could not connect to Opal. Did you set the right URL? (`opal set-url --help`)');
139
+ this.log(""); // Intentional newline
140
+ return (0, apollo_1.handleError)(this, "Could not connect to Opal. Did you set the right URL? (`opal set-url --help`)");
114
141
  }
115
142
  }
116
- const signInOrganizations = signInOrganizationsResponse ? (_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 :
117
- (_d = (_c = signInOrganizationsLegacyResponse === null || signInOrganizationsLegacyResponse === void 0 ? void 0 : signInOrganizationsLegacyResponse.data) === null || _c === void 0 ? void 0 : _c.signInMethod) === null || _d === void 0 ? void 0 : _d.signInOrganizations;
143
+ const signInOrganizations = ((_a = signInOrganizationsResponse === null || signInOrganizationsResponse === void 0 ? void 0 : signInOrganizationsResponse.data.signInMethod) === null || _a === void 0 ? void 0 : _a.__typename) ===
144
+ "SignInMethodResult"
145
+ ? signInOrganizationsResponse.data.signInMethod.signInOrganizations
146
+ : ((_b = signInOrganizationsLegacyResponse === null || signInOrganizationsLegacyResponse === void 0 ? void 0 : signInOrganizationsLegacyResponse.data.signInMethod) === null || _b === void 0 ? void 0 : _b.__typename) === "SignInMethodResult"
147
+ ? (_c = signInOrganizationsLegacyResponse === null || signInOrganizationsLegacyResponse === void 0 ? void 0 : signInOrganizationsLegacyResponse.data.signInMethod) === null || _c === void 0 ? void 0 : _c.signInOrganizations
148
+ : undefined;
118
149
  if (signInOrganizations && signInOrganizations.length > 0) {
119
150
  if (signInOrganizations.length === 1) {
120
- organizationID = signInOrganizations[0].organizationId;
121
- clientIdCandidate = signInOrganizations[0].cliClientId;
151
+ organizationId = signInOrganizations[0].organizationId;
152
+ clientIDCandidate = signInOrganizations[0].cliClientId;
122
153
  }
123
154
  else {
124
- const responses = await inquirer.prompt([{
125
- name: 'signInOrganization',
126
- message: 'Select an organization:',
127
- type: 'list',
128
- choices: signInOrganizations.map(signInOrganization => ({
155
+ const responses = await inquirer.prompt([
156
+ {
157
+ name: "signInOrganization",
158
+ message: "Select an organization:",
159
+ type: "list",
160
+ choices: signInOrganizations.map((signInOrganization) => ({
129
161
  name: signInOrganization.organizationName,
130
162
  value: signInOrganization,
131
163
  })),
132
- }]);
133
- organizationID = responses.signInOrganization.organizationId;
134
- clientIdCandidate = responses.signInOrganization.cliClientId;
164
+ },
165
+ ]);
166
+ organizationId = responses.signInOrganization.organizationId;
167
+ clientIDCandidate = responses.signInOrganization.cliClientId;
135
168
  }
136
169
  }
137
170
  else {
@@ -139,76 +172,103 @@ class Login extends core_1.Command {
139
172
  // which is parity with our web app.
140
173
  }
141
174
  }
175
+ const { resp: signInResp } = await (0, handler_1.runMutation)({
176
+ command: this,
177
+ query: SignInDocument,
178
+ variables: {
179
+ input: { organizationId },
180
+ },
181
+ });
182
+ const state = (_d = signInResp === null || signInResp === void 0 ? void 0 : signInResp.data.signIn) === null || _d === void 0 ? void 0 : _d.state;
142
183
  let issuer;
143
- if ((0, config_1.isProduction)(this.config.configDir)) {
184
+ // issuerURL may come from configData if set by set-airgap-auth
185
+ if (configData.issuerURL) {
186
+ issuer = await openid_client_1.Issuer.discover(configData.issuerURL);
187
+ }
188
+ else if ((0, config_1.isProduction)(this.config.configDir)) {
144
189
  issuer = await openid_client_1.Issuer.discover(ISSUER_PROD);
145
190
  }
146
191
  else {
147
192
  issuer = await openid_client_1.Issuer.discover(ISSUER_DEV);
148
193
  }
149
- let clientId;
150
- if (clientIdCandidate) {
151
- clientId = clientIdCandidate;
194
+ let clientID;
195
+ if (clientIDCandidate) {
196
+ // clientIdCandidate gets stored in creds, and is mostly relevant for on-prem envs using Auth0 and SAML
197
+ clientID = clientIDCandidate;
198
+ }
199
+ else if (configData.clientID) {
200
+ // clientID may come from configData if set by set-airgap-auth
201
+ clientID = configData.clientID;
152
202
  }
153
203
  else if ((0, config_1.isProduction)(this.config.configDir)) {
154
- clientId = CLIENT_ID_PROD;
204
+ clientID = CLIENT_ID_PROD;
155
205
  }
156
206
  else {
157
- clientId = CLIENT_ID_DEV;
207
+ clientID = CLIENT_ID_DEV;
158
208
  }
159
- /* eslint-disable camelcase */
160
209
  const client = new issuer.Client({
161
210
  grant_types: [GRANT_TYPE],
162
- client_id: clientId,
211
+ client_id: clientID,
163
212
  response_types: [],
164
213
  redirect_uris: [],
165
- token_endpoint_auth_method: 'none',
166
- application_type: 'native',
214
+ token_endpoint_auth_method: "none",
215
+ application_type: "native",
167
216
  });
168
- /* eslint-enable camelcase */
169
217
  const handle = await client.deviceAuthorization({
170
- audience: 'https://opal.dev',
171
- scope: 'openid email profile',
218
+ audience: "https://opal.dev",
219
+ scope: "openid email profile",
172
220
  });
173
- this.log('\nYou are being redirected to your browser to authenticate.\n');
221
+ this.log("\nYou are being redirected to your browser to authenticate.\n");
174
222
  this.log(` User Code: ${handle.user_code}\n`);
175
223
  // Wait before opening the browser window to ensure the user has time to
176
224
  // see the User Code.
177
225
  await (0, util_1.sleep)(1000);
178
226
  await open(handle.verification_uri_complete, { wait: false });
179
227
  const tokenSet = await handle.poll();
180
- const userInfo = await client.userinfo(tokenSet);
181
- let account = (userInfo.email || 'unset-email') + '|' + organizationID;
182
- if (clientIdCandidate) {
183
- // Save the clientIdCandidate only when SAML is set up for the org.
184
- account = account + '|' + clientIdCandidate;
228
+ const { error: tokenExchangeError } = await (0, handler_1.runMutation)({
229
+ command: this,
230
+ query: CLITokenExchangeDocument,
231
+ variables: {
232
+ input: {
233
+ accessToken: tokenSet === null || tokenSet === void 0 ? void 0 : tokenSet.access_token,
234
+ state,
235
+ },
236
+ },
237
+ });
238
+ if (tokenExchangeError) {
239
+ this.log("WARN: Failed to exchange access token for session in Opal. Falling back to using access token for authenticating requests\n");
240
+ // TODO: consider adding a warn line recommending upgrading Opal to version XYZ, once accompanying PR is pushed to prod
241
+ await (0, credentials_1.setOpalCredentials)(this, email, organizationId !== null && organizationId !== void 0 ? organizationId : "", clientIDCandidate, (tokenSet === null || tokenSet === void 0 ? void 0 : tokenSet.access_token) || "", credentials_1.SecretType.ApiToken);
242
+ }
243
+ else {
244
+ await (0, credentials_1.setOpalCredentials)(this, email, organizationId !== null && organizationId !== void 0 ? organizationId : "", clientIDCandidate, apollo_1.cookieStr, credentials_1.SecretType.Cookie);
185
245
  }
186
- await (0, credentials_1.setOpalCredentials)(this, userInfo.email, organizationID, clientIdCandidate, (tokenSet === null || tokenSet === void 0 ? void 0 : tokenSet.access_token) || '');
187
246
  // "Representative" authenticated call to check the log-in worked as expected.
188
- const { resp: authCheckResp, error: authCheckErr } = await (0, handler_1.runQuery)({
247
+ const { resp: authCheckResp, error: authCheckErr } = await (0, handler_1.runQueryDeprecated)({
189
248
  command: this,
190
249
  query: exports.CLIAuthSessionCheckDocument,
191
250
  variables: {},
192
251
  });
193
- if (authCheckErr || !((_g = (_f = (_e = authCheckResp === null || authCheckResp === void 0 ? void 0 : authCheckResp.data) === null || _e === void 0 ? void 0 : _e.organizationSettings) === null || _f === void 0 ? void 0 : _f.settings) === null || _g === void 0 ? void 0 : _g.id)) {
194
- 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');
252
+ if (authCheckErr ||
253
+ !((_g = (_f = (_e = authCheckResp === null || authCheckResp === void 0 ? void 0 : authCheckResp.data) === null || _e === void 0 ? void 0 : _e.organizationSettings) === null || _f === void 0 ? void 0 : _f.settings) === null || _g === void 0 ? void 0 : _g.id)) {
254
+ 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");
195
255
  await (0, credentials_1.removeOpalCredentials)(this);
196
- (0, apollo_1.handleError)(this, authCheckErr);
256
+ process.exit(1);
197
257
  }
198
- this.log('🎉 You have successfully authenticated with Opal! You can now run authenticated commands.\n');
258
+ this.log("🎉 You have successfully authenticated with Opal! You can now run authenticated commands.\n");
199
259
  }
200
260
  catch (error) {
201
261
  this.error(error);
202
262
  }
203
263
  }
204
264
  }
205
- Login.description = 'Authenticates you with the Opal server.';
206
- Login.examples = ['$ opal login'];
265
+ Login.description = "Authenticates you with the Opal server.";
266
+ Login.examples = ["$ opal login"];
207
267
  Login.flags = {
208
268
  help: flags_1.SHARED_FLAGS.help,
209
269
  email: core_1.Flags.string({
210
270
  multiple: false,
211
- description: 'Email address to login with.',
271
+ description: "Email address to login with.",
212
272
  }),
213
273
  };
214
274
  Login.args = {};
@@ -1,4 +1,4 @@
1
- import { Command } from '@oclif/core';
1
+ import { Command } from "@oclif/core";
2
2
  export default class Logout extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
@@ -7,15 +7,15 @@ class Logout extends core_1.Command {
7
7
  async run() {
8
8
  try {
9
9
  await (0, credentials_1.removeOpalCredentials)(this);
10
- this.log('Successfully removed the saved Account ID and Auth Token from this computer');
10
+ this.log("Successfully removed the saved Account ID and Auth Token from this computer");
11
11
  }
12
12
  catch (error) {
13
13
  this.error(error);
14
14
  }
15
15
  }
16
16
  }
17
- Logout.description = 'Clears locally stored Opal server authentication credentials.';
18
- Logout.examples = ['$ opal logout'];
17
+ Logout.description = "Clears locally stored Opal server authentication credentials.";
18
+ Logout.examples = ["$ opal logout"];
19
19
  Logout.flags = {
20
20
  help: flags_1.SHARED_FLAGS.help,
21
21
  };
@@ -1,4 +1,4 @@
1
- import { Command } from '@oclif/core';
1
+ import { Command } from "@oclif/core";
2
2
  export default class StartPostgresInstanceSession extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
@@ -2,12 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const inquirer = require("inquirer");
5
- const cmd_1 = require("../../lib/cmd");
6
5
  const apollo_1 = require("../../lib/apollo");
6
+ const cmd_1 = require("../../lib/cmd");
7
+ const flags_1 = require("../../lib/flags");
7
8
  const resources_1 = require("../../lib/resources");
8
- const util_1 = require("../../lib/util");
9
9
  const sessions_1 = require("../../lib/sessions");
10
- const flags_1 = require("../../lib/flags");
10
+ const util_1 = require("../../lib/util");
11
11
  const RdsSessionMetadataFragment = `
12
12
  ... on AwsIamFederatedRdsSession {
13
13
  dbUser
@@ -18,18 +18,18 @@ const RdsSessionMetadataFragment = `
18
18
  }`;
19
19
  const methodChoices = [
20
20
  {
21
- name: 'Start psql session in shell',
22
- value: 'psql',
21
+ name: "Start psql session in shell",
22
+ value: "psql",
23
23
  },
24
24
  {
25
- name: 'View connection configuration details',
26
- value: 'view',
25
+ name: "View connection configuration details",
26
+ value: "view",
27
27
  },
28
28
  ];
29
- if (process.platform === 'darwin') {
29
+ if (process.platform === "darwin") {
30
30
  methodChoices.unshift({
31
- name: 'Open external database app',
32
- value: 'open',
31
+ name: "Open external database app",
32
+ value: "open",
33
33
  });
34
34
  }
35
35
  class StartPostgresInstanceSession extends core_1.Command {
@@ -37,21 +37,21 @@ class StartPostgresInstanceSession extends core_1.Command {
37
37
  (0, cmd_1.setMostRecentCommand)(this);
38
38
  const { flags } = await this.parse(StartPostgresInstanceSession);
39
39
  if (flags.sessionId && flags.refresh) {
40
- return (0, apollo_1.handleError)(this, 'Cannot use both --sessionId and --refresh');
40
+ return (0, apollo_1.handleError)(this, "Cannot use both --sessionId and --refresh");
41
41
  }
42
42
  let instanceId = flags.id;
43
43
  let instanceName = null;
44
44
  const sessionId = flags.sessionId;
45
45
  let action = flags.action;
46
46
  if (!instanceId) {
47
- const selectedInstance = await (0, resources_1.promptUserForResource)(this, 'AWS_RDS_POSTGRES_INSTANCE', 'Select an RDS Postgres instance to connect to');
47
+ const selectedInstance = await (0, resources_1.promptUserForResource)(this, "AWS_RDS_POSTGRES_INSTANCE", "Select an RDS Postgres instance to connect to");
48
48
  if (!selectedInstance) {
49
49
  return;
50
50
  }
51
51
  instanceId = selectedInstance.id;
52
52
  instanceName = selectedInstance.name;
53
53
  }
54
- const accessLevel = await (0, resources_1.promptUserForAccessLevels)(this, instanceId, 'Postgres database', flags.accessLevelRemoteId);
54
+ const accessLevel = await (0, resources_1.promptUserForAccessLevels)(this, instanceId, "Postgres database", flags.accessLevelRemoteId);
55
55
  if (!accessLevel) {
56
56
  return;
57
57
  }
@@ -61,29 +61,31 @@ class StartPostgresInstanceSession extends core_1.Command {
61
61
  }
62
62
  const metadata = session.metadata;
63
63
  switch (metadata === null || metadata === void 0 ? void 0 : metadata.__typename) {
64
- case 'AwsIamFederatedRdsSession': {
64
+ case "AwsIamFederatedRdsSession": {
65
65
  // Don't inform the user about RDS session expiration time, since RDS works differently.
66
66
  // Opal RDS sessions expire after 15min because after that time they can no longer be used to connect.
67
67
  // However, once connected, RDS sessions can be used for up to 12h.
68
68
  // Since there's many options for how the user can use RDS credentials, it's unclear which expiration
69
69
  // we want to show the user.
70
70
  if (!action) {
71
- const selectedMethodInfo = await inquirer.prompt([{
72
- name: 'method',
73
- message: 'Select how to access the database',
74
- type: 'list',
71
+ const selectedMethodInfo = await inquirer.prompt([
72
+ {
73
+ name: "method",
74
+ message: "Select how to access the database",
75
+ type: "list",
75
76
  choices: methodChoices,
76
- }]);
77
+ },
78
+ ]);
77
79
  action = selectedMethodInfo.method;
78
80
  }
79
81
  const dbUrl = `postgresql://${metadata.dbUser}:${encodeURIComponent(metadata.dbPassword)}@${metadata.dbHostname}:${metadata.dbPort}/${metadata.dbName}`;
80
82
  switch (action) {
81
- case 'open': {
82
- let startSessionCmd = `open ${dbUrl}`;
83
- (0, cmd_1.runCommandExec)(startSessionCmd, `Opened external app for ${instanceName ? `"${instanceName}" instance` : 'instance'}`, `Failed to open external app for ${instanceName ? `"${instanceName}" instance` : 'instance'}`);
83
+ case "open": {
84
+ const startSessionCmd = `open ${dbUrl}`;
85
+ (0, cmd_1.runCommandExec)(startSessionCmd, `Opened external app for ${instanceName ? `"${instanceName}" instance` : "instance"}`, `Failed to open external app for ${instanceName ? `"${instanceName}" instance` : "instance"}`);
84
86
  break;
85
87
  }
86
- case 'view': {
88
+ case "view": {
87
89
  const contentParts = [
88
90
  `[Connection URL]\n${dbUrl}`,
89
91
  `[Hostname]\n${metadata.dbHostname}`,
@@ -92,13 +94,13 @@ class StartPostgresInstanceSession extends core_1.Command {
92
94
  `[Password]\n${metadata.dbPassword}`,
93
95
  `[Database]\n${metadata.dbName}`,
94
96
  ];
95
- const content = contentParts.join('\n\n');
97
+ const content = contentParts.join("\n\n");
96
98
  (0, util_1.displayContent)(content);
97
99
  break;
98
100
  }
99
- case 'psql': {
101
+ case "psql": {
100
102
  const startSessionCmd = `psql ${dbUrl}`;
101
- (0, cmd_1.startInteractiveShell)(startSessionCmd, `shell with psql session for ${instanceName ? `"${instanceName}" instance` : 'instance'}`);
103
+ (0, cmd_1.startInteractiveShell)(startSessionCmd, `shell with psql session for ${instanceName ? `"${instanceName}" instance` : "instance"}`);
102
104
  break;
103
105
  }
104
106
  }
@@ -109,12 +111,12 @@ class StartPostgresInstanceSession extends core_1.Command {
109
111
  }
110
112
  }
111
113
  }
112
- StartPostgresInstanceSession.description = 'Starts a session to connect to a Postgres database.';
114
+ StartPostgresInstanceSession.description = "Starts a session to connect to a Postgres database.";
113
115
  StartPostgresInstanceSession.examples = [
114
- 'opal postgres-instances:start',
115
- 'opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398',
116
- 'opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId fullaccess',
117
- 'opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId fullaccess --action view',
116
+ "opal postgres-instances:start",
117
+ "opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398",
118
+ "opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId fullaccess",
119
+ "opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId fullaccess --action view",
118
120
  ];
119
121
  StartPostgresInstanceSession.flags = {
120
122
  help: flags_1.SHARED_FLAGS.help,
@@ -124,9 +126,8 @@ StartPostgresInstanceSession.flags = {
124
126
  refresh: flags_1.SHARED_FLAGS.refresh,
125
127
  action: core_1.Flags.string({
126
128
  multiple: false,
127
- description: 'Method of connecting to the database.\n' +
128
- methodChoices.map(c => `- ${c.value}: ${c.name}`).join('\n'),
129
- options: methodChoices.map(c => c.value),
129
+ description: `Method of connecting to the database.\n${methodChoices.map((c) => `- ${c.value}: ${c.name}`).join("\n")}`,
130
+ options: methodChoices.map((c) => c.value),
130
131
  }),
131
132
  };
132
133
  exports.default = StartPostgresInstanceSession;
@@ -1,4 +1,4 @@
1
- import { Command } from '@oclif/core';
1
+ import { Command } from "@oclif/core";
2
2
  export declare const GetResourceDocument = "\nquery GetResource($id: ResourceId!) {\n resource(input: {id: $id}) {\n __typename\n ... on ResourceResult {\n resource {\n name\n id\n description\n resourceType\n connection {\n name\n id\n connectionType\n }\n parentResource {\n name\n id\n resourceType\n }\n resourceUsers {\n user {\n fullName\n email\n id\n }\n }\n }\n }\n ... on ResourceNotFoundError {\n message\n }\n }\n}";
3
3
  export default class GetResource extends Command {
4
4
  static description: string;
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GetResourceDocument = void 0;
4
4
  const core_1 = require("@oclif/core");
5
5
  const handler_1 = require("../../handler");
6
- const cmd_1 = require("../../lib/cmd");
7
6
  const apollo_1 = require("../../lib/apollo");
7
+ const cmd_1 = require("../../lib/cmd");
8
8
  const flags_1 = require("../../lib/flags");
9
9
  exports.GetResourceDocument = `
10
10
  query GetResource($id: ResourceId!) {
@@ -44,7 +44,7 @@ class GetResource extends core_1.Command {
44
44
  async run() {
45
45
  (0, cmd_1.setMostRecentCommand)(this);
46
46
  const { flags } = await this.parse(GetResource);
47
- const { resp, error } = await (0, handler_1.runQuery)({
47
+ const { resp, error } = await (0, handler_1.runQueryDeprecated)({
48
48
  command: this,
49
49
  query: exports.GetResourceDocument,
50
50
  variables: flags,
@@ -55,8 +55,10 @@ class GetResource extends core_1.Command {
55
55
  (0, apollo_1.printResponse)(this, resp);
56
56
  }
57
57
  }
58
- GetResource.description = 'Get resource info for a particular resource.';
59
- GetResource.examples = ['opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4'];
58
+ GetResource.description = "Get resource info for a particular resource.";
59
+ GetResource.examples = [
60
+ "opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4",
61
+ ];
60
62
  GetResource.flags = {
61
63
  help: flags_1.SHARED_FLAGS.help,
62
64
  id: flags_1.SHARED_FLAGS.id,
@@ -0,0 +1,11 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class SetAuthProvider extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
7
+ clientID: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ issuerUrl: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const config_1 = require("../lib/config");
5
+ const credentials_1 = require("../lib/credentials");
6
+ const flags_1 = require("../lib/flags");
7
+ class SetAuthProvider extends core_1.Command {
8
+ async run() {
9
+ try {
10
+ const { flags, args } = await this.parse(SetAuthProvider);
11
+ const configData = (0, config_1.getOrCreateConfigData)(this.config.configDir);
12
+ configData.issuerURL = flags.issuerUrl;
13
+ configData.clientID = flags.clientID;
14
+ (0, config_1.writeConfigData)(this.config.configDir, configData);
15
+ await (0, credentials_1.removeOpalCredentials)(this);
16
+ this.log("Client ID and Issuer URL updated");
17
+ }
18
+ catch (error) {
19
+ this.error(error);
20
+ }
21
+ }
22
+ }
23
+ SetAuthProvider.description = `Sets the Issuer URL and Client ID of the Auth Provider that the CLI will authenticate with.
24
+ Only use this if you are running a self-hosted, air-gapped instance of Opal that uses a custom Auth Provider.
25
+
26
+ Note - you will need an OIDC provider that supports the device_code grant.
27
+ `;
28
+ SetAuthProvider.examples = [
29
+ "$ opal set-auth-provider --clientID 1234asdf --issuerUrl https://auth.example.com",
30
+ ];
31
+ SetAuthProvider.flags = {
32
+ help: flags_1.SHARED_FLAGS.help,
33
+ clientID: core_1.Flags.string({
34
+ multiple: false,
35
+ description: "Client ID of your Auth Provider",
36
+ required: true,
37
+ }),
38
+ issuerUrl: core_1.Flags.string({
39
+ multiple: false,
40
+ description: "Issuer URL of your Auth Provider",
41
+ required: true,
42
+ }),
43
+ };
44
+ exports.default = SetAuthProvider;
@@ -1,4 +1,4 @@
1
- import { Command } from '@oclif/core';
1
+ import { Command } from "@oclif/core";
2
2
  export default class SetCustomHeader extends Command {
3
3
  static description: string;
4
4
  static examples: string[];