Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 29 additions & 26 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
"description": "Account Name."
},
"issuer": {
"message": "Issuer",
"description": "Issuer."
"message": "Issuer",
"description": "Issuer."
},
"secret": {
"message": "Secret",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -312,5 +312,8 @@
},
"type": {
"message": "Type"
},
"invalid": {
"message": "Invalid"
}
}
21 changes: 16 additions & 5 deletions src/components/Popup/EntryComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
></div>
<div class="issuer">{{ entry.account }}</div>
<div class="issuerEdit">
Expand All @@ -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";
Expand Down Expand Up @@ -103,7 +103,9 @@ export default Vue.extend({
methods: {
noCopy(code: string) {
return (
code === "Encrypted" || code === "Invalid" || code.startsWith("&bull;")
code === CodeState.Encrypted ||
code === CodeState.Invalid ||
code.startsWith("&bull;")
);
},
shouldShowQrIcon(entry: OTPEntry) {
Expand All @@ -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("&bull;")) {
return code;
Expand Down Expand Up @@ -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("&bull;")
) {
return;
}

if (entry.code === "Encrypted") {
if (entry.code === CodeState.Encrypted) {
this.$store.commit("style/showInfo");
this.$store.commit("currentView/changeView", "EnterPasswordPage");
return;
Expand Down
4 changes: 3 additions & 1 deletion src/models/encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
15 changes: 9 additions & 6 deletions src/models/otp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export enum OTPType {
hhex
}

export enum CodeState {
Invalid = "-1",
Encrypted = "-2"
}

export class OTPEntry implements IOTPEntry {
type: OTPType;
index: number;
Expand Down Expand Up @@ -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(
Expand All @@ -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);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/qrdebug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ function getQrDebug(
`Screen Height: ${window.screen.height}<br>` +
`Capture Width: ${qr.width}<br>` +
`Capture Height: ${qr.height}<br>` +
`Device Pixel Ratio: ${devicePixelRatio} / ${window.devicePixelRatio}<br>` +
`Device Pixel Ratio: ${devicePixelRatio} / ${
window.devicePixelRatio
}<br>` +
`Tab ID: ${tab.id}<br>` +
"<br>" +
"<b>Captured Screenshot:</b>";
Expand Down
4 changes: 2 additions & 2 deletions src/store/Accounts.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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;
}
Expand Down