diff --git a/frontend/app/components/encryptable/ccli-options.js b/frontend/app/components/encryptable/ccli-options.js new file mode 100644 index 000000000..d2cb81d80 --- /dev/null +++ b/frontend/app/components/encryptable/ccli-options.js @@ -0,0 +1,26 @@ +import { action } from "@ember/object"; +import { inject as service } from "@ember/service"; +import Component from "@glimmer/component"; + +export default class CcliOptions extends Component { + @service notify; + @service clipboardService; + @service intl; + + constructor() { + super(...arguments); + } + + @action + abort() { + if (this.args.onAbort) { + this.args.onAbort(); + } + } + + @action + copyCommand(command) { + this.clipboardService.copy(command); + this.notify.info(this.intl.t(`flashes.encryptables.ccli_command_copied`)); + } +} diff --git a/frontend/app/components/encryptable/show.js b/frontend/app/components/encryptable/show.js index 202b485e2..128586c74 100644 --- a/frontend/app/components/encryptable/show.js +++ b/frontend/app/components/encryptable/show.js @@ -19,6 +19,9 @@ export default class ShowComponent extends Component { @tracked isFileCreating = false; + @tracked + isCcliOptionsOpen = false; + @tracked isFile = this.args.encryptable.isFile; @@ -38,6 +41,11 @@ export default class ShowComponent extends Component { this.isFileCreating = !this.isFileCreating; } + @action + toggleCcliOptions() { + this.isCcliOptionsOpen = !this.isCcliOptionsOpen; + } + get downloadLink() { return `/api/encryptables/${this.args.encryptable.get("id")}`; } diff --git a/frontend/app/services/clipboard-service.js b/frontend/app/services/clipboard-service.js index c41030c5c..93973f4c1 100644 --- a/frontend/app/services/clipboard-service.js +++ b/frontend/app/services/clipboard-service.js @@ -2,16 +2,6 @@ import Service from "@ember/service"; export default class ClipboardService extends Service { copy(text) { - // Copying to clipboard is not possible in another way. Even libraries do it with a fake element. - // We don't use the addon ember-cli-clipboard, as we need to wait for a async call to finish. - const fakeEl = document.createElement("textarea"); - fakeEl.value = text; - fakeEl.setAttribute("readonly", ""); - fakeEl.style.position = "absolute"; - fakeEl.style.left = "-9999px"; - document.body.appendChild(fakeEl); - fakeEl.select(); - document.execCommand("copy"); - document.body.removeChild(fakeEl); + navigator.clipboard.writeText(text); } } diff --git a/frontend/app/templates/components/encryptable/ccli-options.hbs b/frontend/app/templates/components/encryptable/ccli-options.hbs new file mode 100644 index 000000000..5d61d1026 --- /dev/null +++ b/frontend/app/templates/components/encryptable/ccli-options.hbs @@ -0,0 +1,108 @@ + + + + + +
+ {{t "encryptable/credentials.ccli-options.ccli"}} +
+
+ + +
+ {{#if @encryptable.cleartextUsername}} +
+ {{t "encryptable/credentials.ccli-options.username"}} +
+
+ + +
+ {{/if}} + {{#if @encryptable.cleartextPassword}} +
+ {{t "encryptable/credentials.ccli-options.password"}} +
+
+ + +
+ {{/if}} + {{#if @encryptable.cleartextPin}} +
+ {{t "encryptable/credentials.ccli-options.pin"}} +
+
+ + +
+ {{/if}} + {{#if @encryptable.cleartextToken}} +
+ {{t "encryptable/credentials.ccli-options.token"}} +
+
+ + +
+ {{/if}} + {{#if @encryptable.cleartextEmail}} +
+ {{t "encryptable/credentials.ccli-options.email"}} +
+
+ + +
+ {{/if}} + {{#if @encryptable.cleartextCustomAttr}} +
+ {{t "encryptable/credentials.ccli-options.custom-attr"}} +
+
+ + +
+ {{/if}} +
+ {{t "encryptable/credentials.ccli-options.yaml"}} +
+
+ encryptable.yaml"}} /> + +
+
+ + + {{t "encryptable/credentials.ccli-options.help"}} + + + {{t "close"}} + + +
\ No newline at end of file diff --git a/frontend/app/templates/components/encryptable/show.hbs b/frontend/app/templates/components/encryptable/show.hbs index a29c8786f..4c5adcdfd 100644 --- a/frontend/app/templates/components/encryptable/show.hbs +++ b/frontend/app/templates/components/encryptable/show.hbs @@ -7,6 +7,9 @@ {{#if this.isCredentialSharing}} {{/if}} +{{#if this.isCcliOptionsOpen}} + +{{/if}} {{#if this.isFile}}
@@ -67,6 +70,9 @@
+ + ccli + share diff --git a/frontend/public/assets/images/ccli.svg b/frontend/public/assets/images/ccli.svg new file mode 100644 index 000000000..bc28e35e5 --- /dev/null +++ b/frontend/public/assets/images/ccli.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/tests/integration/components/encryptable/ccli-options-test.js b/frontend/tests/integration/components/encryptable/ccli-options-test.js new file mode 100644 index 000000000..ec3e29ec8 --- /dev/null +++ b/frontend/tests/integration/components/encryptable/ccli-options-test.js @@ -0,0 +1,402 @@ +import { module, test } from "qunit"; +import { setupRenderingTest } from "ember-qunit"; +import { render } from "@ember/test-helpers"; +import { hbs } from "ember-cli-htmlbars"; +import { setLocale } from "ember-intl/test-support"; + +module("Integration | Component | encryptable/ccli-options", function (hooks) { + setupRenderingTest(hooks); + + test("it renders without any set attribute", async function (assert) { + setLocale("en"); + this.set("encryptable", { + id: 1, + name: "Ninjas test encryptable" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-label").innerText, + "Get encryptable with CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-input").value, + "cry encryptable 1" + ); + assert + .dom(this.element.querySelector("#encryptable-ccli-username-label")) + .doesNotExist(); + assert + .dom(this.element.querySelector("#ccli-username-input")) + .doesNotExist(); + assert + .dom(this.element.querySelector("#encryptable-ccli-password-label")) + .doesNotExist(); + assert + .dom(this.element.querySelector("#ccli-password-input")) + .doesNotExist(); + assert + .dom(this.element.querySelector("#encryptable-ccli-pin-label")) + .doesNotExist(); + assert.dom(this.element.querySelector("#ccli-pin-input")).doesNotExist(); + assert + .dom(this.element.querySelector("#encryptable-ccli-token-label")) + .doesNotExist(); + assert.dom(this.element.querySelector("#ccli-token-input")).doesNotExist(); + assert + .dom(this.element.querySelector("#encryptable-ccli-email-label")) + .doesNotExist(); + assert.dom(this.element.querySelector("#ccli-email-input")).doesNotExist(); + assert + .dom(this.element.querySelector("#encryptable-ccli-custom-attr-label")) + .doesNotExist(); + assert + .dom(this.element.querySelector("#ccli-custom-attr-input")) + .doesNotExist(); + assert.equal( + this.element.querySelector("#encryptable-ccli-yaml-label").innerText, + "Get encryptable with CCLI as yaml" + ); + assert.equal( + this.element.querySelector("#ccli-yaml-input").value, + "cry encryptable 1 > encryptable.yaml" + ); + }); + + test("it renders with username and password commands", async function (assert) { + setLocale("en"); + this.set("encryptable", { + id: 9817, + name: "Ninjas test encryptable", + cleartextUsername: "yanickegli123", + cleartextPassword: "findableongithub" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-username-label").innerText, + "Get username with CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-username-input").value, + "cry encryptable 9817 --username" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-password-label").innerText, + "Get password with CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-password-input").value, + "cry encryptable 9817 --password" + ); + }); + + test("it renders with pin and email commands", async function (assert) { + setLocale("en"); + this.set("encryptable", { + id: 6110, + name: "Ninjas test encryptable", + cleartextPin: "123456", + cleartextEmail: "email@email.com" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-email-label").innerText, + "Get email with CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-email-input").value, + "cry encryptable 6110 --email" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-pin-label").innerText, + "Get pin with CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-pin-input").value, + "cry encryptable 6110 --pin" + ); + }); + + test("it renders with token and custom attribute commands", async function (assert) { + setLocale("en"); + this.set("encryptable", { + id: 6110, + name: "Ninjas test encryptable", + cleartextToken: "yoanXiTa", + cleartextCustomAttr: "wow" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-token-label").innerText, + "Get token with CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-token-input").value, + "cry encryptable 6110 --token" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-custom-attr-label") + .innerText, + "Get custom attribute with CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-custom-attr-input").value, + "cry encryptable 6110 --customAttribute" + ); + }); + + test("should render all english translations with every command", async function (assert) { + setLocale("en"); + this.set("encryptable", { + id: 1, + name: "Ninjas test encryptable", + cleartextUsername: "mail", + cleartextPassword: "e2jd2rh4g5io7", + cleartextToken: "token", + cleartextPin: "pin", + cleartextEmail: "email", + cleartextCustomAttr: "customAttr" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-label").innerText, + "Get encryptable with CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-username-label").innerText, + "Get username with CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-password-label").innerText, + "Get password with CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-email-label").innerText, + "Get email with CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-pin-label").innerText, + "Get pin with CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-token-label").innerText, + "Get token with CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-custom-attr-label") + .innerText, + "Get custom attribute with CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-yaml-label").innerText, + "Get encryptable with CCLI as yaml" + ); + assert.equal( + this.element.querySelector("#ccli-options-close-button").innerText, + "Close" + ); + assert.equal( + this.element.querySelector("#ccli-options-help").innerText, + "You need more information?" + ); + }); + + test("should render all german translations with every command", async function (assert) { + setLocale("de"); + this.set("encryptable", { + id: 1, + name: "Ninjas test encryptable", + cleartextUsername: "mail", + cleartextPassword: "e2jd2rh4g5io7", + cleartextToken: "token", + cleartextPin: "pin", + cleartextEmail: "email", + cleartextCustomAttr: "customAttr" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-label").innerText, + "Encryptable anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-username-label").innerText, + "Benutzername anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-password-label").innerText, + "Passwort anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-email-label").innerText, + "Email anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-pin-label").innerText, + "Pin anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-token-label").innerText, + "Token anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-custom-attr-label") + .innerText, + "Individuelles Attribut anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-yaml-label").innerText, + "Encryptable als yaml anzeigen mit CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-options-close-button").innerText, + "Schliessen" + ); + assert.equal( + this.element.querySelector("#ccli-options-help").innerText, + "Brauchst du mehr Informationen?" + ); + }); + + test("should render all swiss german translations with every command", async function (assert) { + setLocale("ch-be"); + this.set("encryptable", { + id: 1, + name: "Ninjas test encryptable", + cleartextUsername: "mail", + cleartextPassword: "e2jd2rh4g5io7", + cleartextToken: "token", + cleartextPin: "pin", + cleartextEmail: "email", + cleartextCustomAttr: "customAttr" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-label").innerText, + "Encryptable ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-username-label").innerText, + "Benutzername ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-password-label").innerText, + "Passwort ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-email-label").innerText, + "Email ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-pin-label").innerText, + "Pin ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-token-label").innerText, + "Token ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-custom-attr-label") + .innerText, + "Individuells Attribut ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-yaml-label").innerText, + "Encryptable als yaml ahzeigä mit CCLI" + ); + assert.equal( + this.element.querySelector("#ccli-options-close-button").innerText, + "Schliessä" + ); + assert.equal( + this.element.querySelector("#ccli-options-help").innerText, + "Bruchsch meh Informationä?" + ); + }); + + test("should render all french translations with every command", async function (assert) { + setLocale("fr"); + this.set("encryptable", { + id: 1, + name: "Ninjas test encryptable", + cleartextUsername: "mail", + cleartextPassword: "e2jd2rh4g5io7", + cleartextToken: "token", + cleartextPin: "pin", + cleartextEmail: "email", + cleartextCustomAttr: "customAttr" + }); + + await render( + hbs`` + ); + + assert.equal( + this.element.querySelector("#encryptable-ccli-label").innerText, + "Soyez cryptable avec CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-username-label").innerText, + "Obtenir le nom d'utilisateur avec ccli" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-password-label").innerText, + "Obtenir un mot de passe avec CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-email-label").innerText, + "Recevoir des e-mails avec CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-pin-label").innerText, + "Obtenez l'épingle avec CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-token-label").innerText, + "Obtenez un jeton avec CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-custom-attr-label") + .innerText, + "Obtenir un attribut personnalisé avec CCLI" + ); + assert.equal( + this.element.querySelector("#encryptable-ccli-yaml-label").innerText, + "Devenez cryptable avec CCLI en tant que yaml" + ); + assert.equal( + this.element.querySelector("#ccli-options-close-button").innerText, + "Fermer" + ); + assert.equal( + this.element.querySelector("#ccli-options-help").innerText, + "Avez-vous besoin de plus d'informations?" + ); + }); +}); diff --git a/frontend/translations/ch_be.yml b/frontend/translations/ch_be.yml index d39b95db2..6f71158b3 100644 --- a/frontend/translations/ch_be.yml +++ b/frontend/translations/ch_be.yml @@ -116,6 +116,25 @@ ch_be: clickToSeeAttrs: Klick wenn aui Attribut möchtisch gseh share: title: Datei teilä + ccli-options: + title: CCLI Commands kopierä + help: Bruchsch meh Informationä? + ccli: Encryptable ahzeigä mit CCLI + username: Benutzername ahzeigä mit CCLI + password: Passwort ahzeigä mit CCLI + pin: Pin ahzeigä mit CCLI + token: Token ahzeigä mit CCLI + email: Email ahzeigä mit CCLI + custom-attr: Individuells Attribut ahzeigä mit CCLI + yaml: Encryptable als yaml ahzeigä mit CCLI + copy-ccli: CCLI Command kopierä + copy-ccli-username: CCLI Command füre Benutzername kopierä + copy-ccli-password: CCLI Command fürs Passwort kopierä + copy-ccli-pin: CCLI Command füre Pin kopierä + copy-ccli-token: CCLI Command fürs Token kopierä + copy-ccli-email: CCLI Command für d Email kopierä + copy-ccli-custom-attr: CCLI Command fürs inidviduellä Attribut kopierä + copy-ccli-yaml: CCLI Yaml Command kopierä encryptable/transferring/file: new: @@ -325,6 +344,7 @@ ch_be: token_copied: Dr Token isch kopiert worde email_copied: D Email isch kopiert worde customAttr_copied: Z individuellä Attribut isch kopiert worde + ccli_command_copied: CCLI Command isch kopiert worde selectAdditionalField: Du muäsch es Fäld uswähle encryptable-credentials: diff --git a/frontend/translations/de.yml b/frontend/translations/de.yml index bd8d4ea85..2c88bad43 100644 --- a/frontend/translations/de.yml +++ b/frontend/translations/de.yml @@ -116,6 +116,25 @@ de: clickToSeeAttrs: Klicke um alle Attribute zu sehen share: title: Datei teilen + ccli-options: + title: CCLI Commands kopieren + help: Brauchst du mehr Informationen? + ccli: Encryptable anzeigen mit CCLI + username: Benutzername anzeigen mit CCLI + password: Passwort anzeigen mit CCLI + pin: Pin anzeigen mit CCLI + token: Token anzeigen mit CCLI + email: Email anzeigen mit CCLI + custom-attr: Individuelles Attribut anzeigen mit CCLI + yaml: Encryptable als yaml anzeigen mit CCLI + copy-ccli: CCLI Command kopieren + copy-ccli-username: CCLI Command für Benutzername kopieren + copy-ccli-password: CCLI Command für Passwort kopieren + copy-ccli-pin: CCLI Command für Pin kopieren + copy-ccli-token: CCLI Command für Token kopieren + copy-ccli-email: CCLI Command für Email kopieren + copy-ccli-custom-attr: CCLI Command für Individuelles Attribut kopieren + copy-ccli-yaml: CCLI Yaml Command kopieren encryptable/transferring/file: new: @@ -325,6 +344,7 @@ de: token_copied: Token wurde kopiert email_copied: Email wurde kopiert customAttr_copied: Individuelles Attribut wurde kopiert + ccli_command_copied: CCLI Command wurde kopiert selectAdditionalField: Du musst ein Feld auswählen encryptable-credentials: diff --git a/frontend/translations/en.yml b/frontend/translations/en.yml index fc7826ee8..57e278491 100644 --- a/frontend/translations/en.yml +++ b/frontend/translations/en.yml @@ -117,6 +117,25 @@ en: clickToSeeAttrs: Click to see all attributes share: title: Share File + ccli-options: + title: Copy CCLI Commands + help: You need more information? + ccli: Get encryptable with CCLI + username: Get username with CCLI + password: Get password with CCLI + pin: Get pin with CCLI + token: Get token with CCLI + email: Get email with CCLI + custom-attr: Get custom attribute with CCLI + yaml: Get encryptable with CCLI as yaml + copy-ccli: Copy CCLI Command + copy-ccli-username: Copy CCLI Command for username + copy-ccli-password: Copy CCLI Command for password + copy-ccli-pin: Copy CCLI Command for pin + copy-ccli-token: Copy CCLI Command for token + copy-ccli-email: Copy CCLI Command for email + copy-ccli-custom-attr: Copy CCLI Command for custom attribute + copy-ccli-yaml: Copy CCLI Yaml Command encryptable/transferring/file: new: @@ -325,6 +344,7 @@ en: token_copied: Token was copied email_copied: Email was copied customAttr_copied: Custom Attribute was copied + ccli_command_copied: CCLI Command was copied selectAdditionalField: You have to choose a field encryptable-credentials: diff --git a/frontend/translations/fr.yml b/frontend/translations/fr.yml index 5370cc929..edc6288db 100644 --- a/frontend/translations/fr.yml +++ b/frontend/translations/fr.yml @@ -117,6 +117,25 @@ fr: clickToSeeAttrs: Cliquez pour voir tous les attributs share: title: Partage fichier + ccli-options: + title: Copier les commandes CCLI + help: Avez-vous besoin de plus d'informations? + ccli: Soyez cryptable avec CCLI + username: Obtenir le nom d'utilisateur avec ccli + password: Obtenir un mot de passe avec CCLI + pin: Obtenez l'épingle avec CCLI + token: Obtenez un jeton avec CCLI + email: Recevoir des e-mails avec CCLI + custom-attr: Obtenir un attribut personnalisé avec CCLI + yaml: Devenez cryptable avec CCLI en tant que yaml + copy-ccli: Copier la commande CCLI + copy-ccli-username: Copier la commande CCLI pour le nom d'utilisateur + copy-ccli-password: Copier la commande CCLI pour le mot de passe + copy-ccli-pin: Copier la commande CCLI pour la broche + copy-ccli-token: Copier la commande CCLI pour le jeton + copy-ccli-email: Copier la commande CCLI pour le courrier électronique + copy-ccli-custom-attr: Copier la commande CCLI pour l'attribut personnalisé + copy-ccli-yaml: Copier la commande CCLI Yaml encryptable/transferring/file: new: @@ -326,6 +345,7 @@ fr: token_copied: Le jeton a été copié email_copied: L'e-mail a été copié customAttr_copied: L'attribut personnalisé a été copié + ccli_command_copied: La commande CCLI a été copiée selectAdditionalField: Tu dois sélectionner un champ encryptable-credentials: