diff --git a/_locales/en/messages.json b/_locales/en/messages.json index f4477898d..5faa3ed24 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -56,8 +56,8 @@ "description": "Account Name." }, "issuer": { - "message": "Issuer", - "description": "Issuer." + "message": "Issuer", + "description": "Issuer." }, "secret": { "message": "Secret", @@ -224,52 +224,52 @@ "description": "Remove password." }, "download_enc_backup": { - "message": "Download Password-Protected Backup", - "description": "Download Encrypted Backup" + "message": "Download Password-Protected Backup", + "description": "Download Encrypted Backup" }, "search": { - "message": "Search", - "description": "Search" + "message": "Search", + "description": "Search" }, "popout": { - "message": "Popup mode", - "description": "Make window turn into persistent popup" + "message": "Popup mode", + "description": "Make window turn into persistent popup" }, "lock": { - "message": "Lock", - "description": "Lock accounts" + "message": "Lock", + "description": "Lock accounts" }, "edit": { - "message": "Edit", - "description": "Edit" + "message": "Edit", + "description": "Edit" }, "manual_dropbox": { - "message": "Manual Sync", - "description": "Manual sync" + "message": "Manual Sync", + "description": "Manual sync" }, "use_autofill": { - "message": "Use Autofill", - "description": "Use Autofill" + "message": "Use Autofill", + "description": "Use Autofill" }, "use_high_contrast": { - "message": "Use High Contrast", - "description": "Use High Contrast" + "message": "Use High Contrast", + "description": "Use High Contrast" }, "storage_menu": { - "message": "Storage & Backup", - "description": "Storage and sync menu title" + "message": "Storage & Backup", + "description": "Storage and sync menu title" }, "storage_location_info": { - "message": "Choose where your data is stored. Using 'local' stores your data on your PC. Using 'sync' lets your browser sync your data to the cloud if you are signed into a sync account.", - "description": "Message explaning the diffrences between sync and local storage spaces." + "message": "Choose where your data is stored. Using 'local' stores your data on your PC. Using 'sync' lets your browser sync your data to the cloud if you are signed into a sync account.", + "description": "Message explaning the diffrences between sync and local storage spaces." }, "storage_sync_info": { - "message": "Automatically backup your data to 3rd party storage services.", - "description": "3rd party backup info" + "message": "Automatically backup your data to 3rd party storage services.", + "description": "3rd party backup info" }, "storage_location": { - "message": "Storage Location", - "description": "Storage location" + "message": "Storage Location", + "description": "Storage location" }, "sign_in": { "message": "Sign in", @@ -312,5 +312,8 @@ }, "type": { "message": "Type" + }, + "invalid": { + "message": "Invalid" } } diff --git a/src/components/Popup/EntryComponent.vue b/src/components/Popup/EntryComponent.vue index 01381ead4..4b8106ee0 100644 --- a/src/components/Popup/EntryComponent.vue +++ b/src/components/Popup/EntryComponent.vue @@ -44,7 +44,7 @@ timeout: entry.period - (second % entry.period) < 5 }" v-on:click="copyCode(entry)" - v-html="style.isEditing ? showBulls(entry.code) : entry.code" + v-html="style.isEditing ? showBulls(entry.code) : showCode(entry.code)" >
{{ entry.account }}
@@ -71,7 +71,7 @@ import Vue from "vue"; import { mapState } from "vuex"; import * as QRGen from "qrcode-generator"; -import { OTPEntry, OTPType } from "../../models/otp"; +import { OTPEntry, OTPType, CodeState } from "../../models/otp"; import IconMinusCircle from "../../../svg/minus-circle.svg"; import IconRedo from "../../../svg/redo.svg"; @@ -103,7 +103,9 @@ export default Vue.extend({ methods: { noCopy(code: string) { return ( - code === "Encrypted" || code === "Invalid" || code.startsWith("•") + code === CodeState.Encrypted || + code === CodeState.Invalid || + code.startsWith("•") ); }, shouldShowQrIcon(entry: OTPEntry) { @@ -113,6 +115,15 @@ export default Vue.extend({ entry.type !== OTPType.steam ); }, + showCode(code: string) { + if (code === CodeState.Encrypted) { + return this.i18n.encrypted; + } else if (code === CodeState.Invalid) { + return this.i18n.invalid; + } else { + return code; + } + }, showBulls(code: string) { if (code.startsWith("•")) { return code; @@ -150,13 +161,13 @@ export default Vue.extend({ async copyCode(entry: OTPEntry) { if ( this.$store.state.style.style.isEditing || - entry.code === "Invalid" || + entry.code === CodeState.Invalid || entry.code.startsWith("•") ) { return; } - if (entry.code === "Encrypted") { + if (entry.code === CodeState.Encrypted) { this.$store.commit("style/showInfo"); this.$store.commit("currentView/changeView", "EnterPasswordPage"); return; diff --git a/src/models/encryption.ts b/src/models/encryption.ts index 1ccc79472..422bb6cfd 100644 --- a/src/models/encryption.ts +++ b/src/models/encryption.ts @@ -68,7 +68,9 @@ export class Encryption implements IEncryption { } console.warn( - `Account ${entry.hash} may have secret ${decryptedSecret}, but hash did not match.` + `Account ${ + entry.hash + } may have secret ${decryptedSecret}, but hash did not match.` ); return null; } catch (error) { diff --git a/src/models/otp.ts b/src/models/otp.ts index bfacd5e75..fab005ca6 100644 --- a/src/models/otp.ts +++ b/src/models/otp.ts @@ -11,6 +11,11 @@ export enum OTPType { hhex } +export enum CodeState { + Invalid = "-1", + Encrypted = "-2" +} + export class OTPEntry implements IOTPEntry { type: OTPType; index: number; @@ -97,9 +102,9 @@ export class OTPEntry implements IOTPEntry { generate() { if (!this.secret && !this.encSecret) { - this.code = "Invalid"; + this.code = CodeState.Invalid; } else if (!this.secret) { - this.code = "Encrypted"; + this.code = CodeState.Encrypted; } else { try { this.code = KeyUtilities.generate( @@ -109,10 +114,8 @@ export class OTPEntry implements IOTPEntry { this.period ); } catch (error) { - this.code = "Invalid"; - if (parent) { - parent.postMessage(`Invalid secret: [${this.secret}]`, "*"); - } + this.code = CodeState.Invalid; + console.log("Invalid secret.", error); } } } diff --git a/src/qrdebug.ts b/src/qrdebug.ts index c2e90826a..0db7cb1c9 100644 --- a/src/qrdebug.ts +++ b/src/qrdebug.ts @@ -60,7 +60,9 @@ function getQrDebug( `Screen Height: ${window.screen.height}
` + `Capture Width: ${qr.width}
` + `Capture Height: ${qr.height}
` + - `Device Pixel Ratio: ${devicePixelRatio} / ${window.devicePixelRatio}
` + + `Device Pixel Ratio: ${devicePixelRatio} / ${ + window.devicePixelRatio + }
` + `Tab ID: ${tab.id}
` + "
" + "Captured Screenshot:"; diff --git a/src/store/Accounts.ts b/src/store/Accounts.ts index dfff8d064..24816935d 100644 --- a/src/store/Accounts.ts +++ b/src/store/Accounts.ts @@ -1,7 +1,7 @@ import { EntryStorage } from "../models/storage"; import { Encryption } from "../models/encryption"; import * as CryptoJS from "crypto-js"; -import { OTPType } from "../models/otp"; +import { OTPType, CodeState } from "../models/otp"; import { ActionContext } from "vuex"; export class Accounts implements IModule { @@ -16,7 +16,7 @@ export class Accounts implements IModule { : await this.getEntries(encryption); for (let i = 0; i < entries.length; i++) { - if (entries[i].code === "Encrypted") { + if (entries[i].code === CodeState.Encrypted) { shouldShowPassphrase = true; break; }