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;
}