diff --git a/addons/api/addon/models/session.js b/addons/api/addon/models/session.js
index 8c81b8a5a..7ec468630 100644
--- a/addons/api/addon/models/session.js
+++ b/addons/api/addon/models/session.js
@@ -2,14 +2,88 @@ import GeneratedSessionModel from '../generated/models/session';
import { computed } from '@ember/object';
import { equal } from '@ember/object/computed';
import { tracked } from '@glimmer/tracking';
+import { A } from '@ember/array';
+import { typeOf } from '@ember/utils';
+
+/**
+ *
+ */
+class SessionCredential {
+ // =classes
+
+ /**
+ *
+ */
+ static Library = class Library {
+ id;
+ name;
+ description;
+ type;
+
+ constructor(id, name, description, type) {
+ this.id = id;
+ this.name = name;
+ this.description = description;
+ this.type = type;
+ }
+ };
+
+ /**
+ *
+ */
+ static SecretItem = class SecretItem {
+ key;
+ value;
+
+ constructor(key, value) {
+ this.key = key;
+ this.value = value;
+ }
+ };
+
+ // =attributes
+ rawCredential;
+ library;
+ purpose;
+ #rawSecretValue;
+
+ /**
+ * The credential secret as an array of key/value objects.
+ * @type {SessionCredential.SecretItem[]}
+ */
+ get secrets() {
+ if (typeOf(this.#rawSecretValue) === 'object') {
+ return Object.keys(this.#rawSecretValue).map(
+ (key) =>
+ new SessionCredential.SecretItem(key, this.#rawSecretValue[key])
+ );
+ } else {
+ return [new SessionCredential.SecretItem('secret', this.#rawSecretValue)];
+ }
+ }
+
+ // =methods
+
+ constructor(cred) {
+ const { id, name, description, type } = cred.credential_library;
+ this.library = new SessionCredential.Library(id, name, description, type);
+ this.#rawSecretValue = cred.secret;
+ this.rawCredential = cred;
+ this.purpose = cred.purpose;
+ }
+}
export default class SessionModel extends GeneratedSessionModel {
// =attributes
+ // These transient attributes are used for values that come from the CLI
+ // `connect` command as triggered by Desktop. These attributes represent
+ // transient read-only values.
@tracked acknowledged;
@tracked started_desktop_client;
@tracked proxy_address;
@tracked proxy_port;
+ credentials = A();
@equal('status', 'active') isActive;
@equal('status', 'pending') isPending;
@@ -43,6 +117,13 @@ export default class SessionModel extends GeneratedSessionModel {
// =methods
+ /**
+ *
+ */
+ addCredential(cred) {
+ this.credentials.pushObject(new SessionCredential(cred));
+ }
+
/**
* Cancels the session via the `cancel` method.
* See serializer and adapter for more information.
diff --git a/addons/api/mirage/scenarios/ipc.js b/addons/api/mirage/scenarios/ipc.js
index f8fdf6fde..86ffbe83e 100644
--- a/addons/api/mirage/scenarios/ipc.js
+++ b/addons/api/mirage/scenarios/ipc.js
@@ -58,6 +58,60 @@ export default function initializeMockIPC(server) {
port: datatype.number(),
protocol: type,
session_id: newSession.id,
+ credentials: [
+ {
+ credential_library: {
+ id: 'clvlt_4cvscMTl0N',
+ name: 'Library Name',
+ description: 'Library Description',
+ credential_store_id: 'csvlt_Q1HFGt7Jpm',
+ type: 'vault',
+ },
+ purpose: 'application',
+ secret: 'just-a-random-string',
+ },
+ {
+ credential_library: {
+ id: 'clvlt_4cvscMTl0N',
+ name: 'Library Name',
+ description: 'Library Description',
+ credential_store_id: 'csvlt_Q1HFGt7Jpm',
+ type: 'vault',
+ },
+ purpose: 'ingress',
+ secret: {
+ key1: 'value 1',
+ key2: true,
+ key3: 'test',
+ },
+ },
+ {
+ credential_library: {
+ id: 'clvlt_9KWscxpcY7',
+ name: 'Library Name',
+ description: 'Library Description',
+ credential_store_id: 'csvlt_Q1HFGt7Jpm',
+ type: 'vault',
+ },
+ purpose: 'application',
+ secret: 'just-a-random-string',
+ },
+ {
+ credential_library: {
+ id: 'clvlt_9KWscxpcY7',
+ name: 'Library Name',
+ description: 'Library Description',
+ credential_store_id: 'csvlt_Q1HFGt7Jpm',
+ type: 'vault',
+ },
+ purpose: 'egress',
+ secret: {
+ key1: 'value 1',
+ key2: true,
+ key3: 'test',
+ },
+ },
+ ],
};
}
diff --git a/addons/core/translations/form/en-us.yaml b/addons/core/translations/form/en-us.yaml
index 5d2a58567..ba8252614 100644
--- a/addons/core/translations/form/en-us.yaml
+++ b/addons/core/translations/form/en-us.yaml
@@ -108,3 +108,7 @@ email:
label: Email
full_name:
label: Full Name
+key:
+ label: Key
+value:
+ label: Value
diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml
index 888cb980b..dd7ea9359 100644
--- a/addons/core/translations/resources/en-us.yaml
+++ b/addons/core/translations/resources/en-us.yaml
@@ -147,6 +147,17 @@ session:
description: No active sessions available to display yet.
actions:
connect: Connect
+ credential:
+ title: Credential
+ title_plural: Credentials
+ secret:
+ label: Secret
+ credential_library:
+ title: Credential Library
+ actions:
+ raw-api:
+ show: View raw API output
+ hide: Hide raw API output
org:
title: Org
title_plural: Orgs
@@ -256,3 +267,4 @@ target:
add:
title: Add Host Sets
description: Select host sets to assign to this target.
+ secret: ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
diff --git a/ui/desktop/app/components/hidden-secret/index.hbs b/ui/desktop/app/components/hidden-secret/index.hbs
index 4061f42e9..a28042fd6 100644
--- a/ui/desktop/app/components/hidden-secret/index.hbs
+++ b/ui/desktop/app/components/hidden-secret/index.hbs
@@ -1,5 +1,4 @@
- {{! TODO: The span wrap within a div because later we will add the toggle secret icon/button}}
session.addCredential(cred));
+ }
} catch(e) {
this.confirm.confirm(e.message, { isConnectError: true })
// Retry
diff --git a/ui/desktop/app/styles/app.scss b/ui/desktop/app/styles/app.scss
index d46233c9f..5e1042934 100644
--- a/ui/desktop/app/styles/app.scss
+++ b/ui/desktop/app/styles/app.scss
@@ -395,19 +395,30 @@ $chevron-down: url("data:image/svg+xml;utf-8,
<:body>
- {{t 'resources.target.messages.proxy_url.title'}}
- ({{t 'resources.target.types.tcp'}})
+
+ {{t 'resources.target.messages.proxy_url.title'}}
+ ({{t 'resources.target.types.tcp'}})
+
- {{session.proxy_address}}:{{session.proxy_port}}
+ {{session.proxy}}
- {{!--
+ {{#if session.credentials}}
+
- Credentials
+ {{t 'resources.session.credential.title_plural'}}
-
- <:header>
-
-
-
- <:body>
-
-
-
- Key
- Value
-
-
-
-
- foo
- Value
-
-
- ttl
- Test
-
-
-
-
- <:footer>
-
-
-
- {
- "auth": null,
- "lease_duration": 3600,
- "lease_id": "",
- "renewable": false
- }
-
-
-
-
- --}}
-
+ <:header>
+
+
+ <:key>{{t 'form.id.label'}}
+ <:value>
+
+ {{credential.library.id}}
+
+
+
+
+ <:key>{{t 'form.type.label'}}
+ <:value>{{credential.library.type}}
+
+ {{#if credential.library.name}}
+
+ <:key>{{t 'form.name.label'}}
+ <:value>{{credential.library.name}}
+
+ {{/if}}
+ {{#if credential.library.description}}
+
+ <:key>{{t 'form.description.label'}}
+ <:value>{{credential.library.description}}
+
+ {{/if}}
+
+
+ <:body>
+ {{#if credential.secrets}}
+
+
+
+ {{t
+ 'form.key.label'
+ }}
+ {{t
+ 'form.value.label'
+ }}
+
+
+
+ {{#each credential.secrets as |secret|}}
+
+ {{secret.key}}
+
+
+ {{secret.value}}
+
+
+
+ {{/each}}
+
+
+ {{/if}}
+
+ <:footer>
+
+ {{raw-json credential.rawCredential}}
+
+
+
+ {{/each}}
+ {{/if}}
<:footer>
@@ -93,15 +144,6 @@
{{t 'actions.close'}}
-
- {{!
-
- }}
-
{{/unless}}
diff --git a/ui/desktop/electron-app/config/cli.js b/ui/desktop/electron-app/config/cli.js
index 22092de64..9af356e9e 100644
--- a/ui/desktop/electron-app/config/cli.js
+++ b/ui/desktop/electron-app/config/cli.js
@@ -48,6 +48,10 @@ const extract = (artifactPath, destination) => {
module.exports = {
setup: async () => {
+ if (process.env.BYPASS_CLI_SETUP) {
+ console.warn('WARNING: Bypassing cli setup');
+ return;
+ }
const artifactPath = await downloadArtifact(artifactVersion);
await extract(artifactPath, artifactDestination);
}
diff --git a/ui/desktop/tests/integration/helpers/raw-json-test.js b/ui/desktop/tests/integration/helpers/raw-json-test.js
new file mode 100644
index 000000000..34574a8a5
--- /dev/null
+++ b/ui/desktop/tests/integration/helpers/raw-json-test.js
@@ -0,0 +1,19 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Helper | raw-json', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ this.set('inputValue', {});
+ await render(hbs`{{raw-json inputValue}}`);
+ assert.equal(this.element.textContent.trim(), '{}');
+ this.set('inputValue', { key: 'value', nestedKey: { key: 'value' } });
+ assert.equal(
+ this.element.textContent.trim(),
+ `{\n "key": "value",\n "nestedKey": {\n "key": "value"\n }\n}`
+ );
+ });
+});
diff --git a/yarn.lock b/yarn.lock
index ac5c10ef8..2c78436b9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3671,7 +3671,7 @@ agent-base@4, agent-base@^4.3.0:
dependencies:
es6-promisify "^5.0.0"
-agent-base@6:
+agent-base@6, agent-base@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
@@ -6360,9 +6360,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001219:
- version "1.0.30001235"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001235.tgz#ad5ca75bc5a1f7b12df79ad806d715a43a5ac4ed"
- integrity sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==
+ version "1.0.30001239"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001239.tgz#66e8669985bb2cb84ccb10f68c25ce6dd3e4d2b8"
+ integrity sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ==
capture-exit@^2.0.0:
version "2.0.0"
@@ -15671,7 +15671,16 @@ npm-package-arg@^7.0.0:
semver "^5.6.0"
validate-npm-package-name "^3.0.0"
-npm-package-arg@^8.0.0, npm-package-arg@^8.1.0:
+npm-package-arg@^8.0.0:
+ version "8.1.5"
+ resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44"
+ integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==
+ dependencies:
+ hosted-git-info "^4.0.1"
+ semver "^7.3.4"
+ validate-npm-package-name "^3.0.0"
+
+npm-package-arg@^8.1.0:
version "8.1.4"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.4.tgz#8001cdbc4363997b8ef6c6cf7aaf543c5805879d"
integrity sha512-xLokoCFqj/rPdr3LvcdDL6Kj6ipXGEDHD/QGpzwU6/pibYUOXmp5DBmg76yukFyx4ZDbrXNOTn+BPyd8TD4Jlw==
@@ -19098,11 +19107,11 @@ socks-proxy-agent@^4.0.0:
socks "~2.3.2"
socks-proxy-agent@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60"
- integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e"
+ integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==
dependencies:
- agent-base "6"
+ agent-base "^6.0.2"
debug "4"
socks "^2.3.3"
@@ -21634,9 +21643,9 @@ write@^0.2.1:
mkdirp "^0.5.1"
ws@^7.4.5, ws@^7.4.6, ws@~7.4.2:
- version "7.4.6"
- resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
- integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
+ version "7.5.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.0.tgz#0033bafea031fb9df041b2026fc72a571ca44691"
+ integrity sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==
x-is-string@^0.1.0:
version "0.1.0"
@@ -21744,9 +21753,9 @@ yaml@^1.10.0, yaml@^1.7.2:
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yargs-parser@20.2.4, yargs-parser@^15.0.1, yargs-parser@^18.1.2, yargs-parser@^20.0.0, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^7.0.0, yargs-parser@^9.0.2, yargs-parser@~20.2.7:
- version "20.2.7"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
- integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
+ version "20.2.9"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
+ integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
yargs-unparser@2.0.0:
version "2.0.0"