From ef897347c389c36c1a4e8f27bcac24423389a2df Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Tue, 27 Aug 2024 02:11:43 +0800 Subject: [PATCH 1/3] Fix OTP type --- src/background.ts | 10 ++++----- src/components/Popup/BackupPage.vue | 15 ++++++++----- src/components/Popup/EntryComponent.vue | 6 ++--- src/definitions/otp.d.ts | 13 +++++++++-- src/import.ts | 10 ++++----- src/models/otp.ts | 15 ++++++------- src/models/storage.ts | 29 +++++++++++-------------- 7 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/background.ts b/src/background.ts index bb59a2f9..2b0447dc 100644 --- a/src/background.ts +++ b/src/background.ts @@ -119,7 +119,7 @@ async function getTotp(text: string, silent = false) { } } else { let uri = text.split("otpauth://")[1]; - let type = uri.substr(0, 4).toLowerCase(); + let type = uri.substr(0, 4).toLowerCase() as OTPType; uri = uri.substr(5); let label = uri.split("?")[0]; const parameterPart = uri.split("?")[1]; @@ -193,15 +193,15 @@ async function getTotp(text: string, silent = false) { if ( !/^[2-7a-z]+=*$/i.test(secret) && /^[0-9a-f]+$/i.test(secret) && - type === "totp" + type === OTPType.totp ) { - type = "hex"; + type = OTPType.hex; } else if ( !/^[2-7a-z]+=*$/i.test(secret) && /^[0-9a-f]+$/i.test(secret) && - type === "hotp" + type === OTPType.hotp ) { - type = "hhex"; + type = OTPType.hhex; } const entryData: { [hash: string]: RawOTPStorage } = {}; entryData[hash] = { diff --git a/src/components/Popup/BackupPage.vue b/src/components/Popup/BackupPage.vue index 8e718b46..3fb6a812 100644 --- a/src/components/Popup/BackupPage.vue +++ b/src/components/Popup/BackupPage.vue @@ -212,10 +212,13 @@ function getOneLineOtpBackupFile(entryData: { [hash: string]: RawOTPStorage }) { ? otpStorage.issuer + ":" + (otpStorage.account || "") : otpStorage.account || ""; let type = ""; - if (otpStorage.type === "totp" || otpStorage.type === "hex") { - type = "totp"; - } else if (otpStorage.type === "hotp" || otpStorage.type === "hhex") { - type = "hotp"; + if (otpStorage.type === OTPType.totp || otpStorage.type === OTPType.hex) { + type = OTPType.totp; + } else if ( + otpStorage.type === OTPType.hotp || + otpStorage.type === OTPType.hhex + ) { + type = OTPType.hotp; } else { continue; } @@ -228,8 +231,8 @@ function getOneLineOtpBackupFile(entryData: { [hash: string]: RawOTPStorage }) { "?secret=" + otpStorage.secret + (otpStorage.issuer ? "&issuer=" + otpStorage.issuer : "") + - (type === "hotp" ? "&counter=" + otpStorage.counter : "") + - (type === "totp" && otpStorage.period + (type === OTPType.hotp ? "&counter=" + otpStorage.counter : "") + + (type === OTPType.totp && otpStorage.period ? "&period=" + otpStorage.period : "") + (otpStorage.digits ? "&digits=" + otpStorage.digits : "") + diff --git a/src/components/Popup/EntryComponent.vue b/src/components/Popup/EntryComponent.vue index 92099b5b..abd96418 100644 --- a/src/components/Popup/EntryComponent.vue +++ b/src/components/Popup/EntryComponent.vue @@ -264,10 +264,10 @@ function getQrUrl(entry: OTPEntry) { : entry.account; const type = entry.type === OTPType.hex - ? OTPType[OTPType.totp] + ? OTPType.totp : entry.type === OTPType.hhex - ? OTPType[OTPType.hotp] - : OTPType[entry.type]; + ? OTPType.hotp + : entry.type; const otpauth = "otpauth://" + type + diff --git a/src/definitions/otp.d.ts b/src/definitions/otp.d.ts index c55fb148..1ac0583f 100644 --- a/src/definitions/otp.d.ts +++ b/src/definitions/otp.d.ts @@ -1,5 +1,14 @@ +declare enum OTPType { + totp = "totp", + hotp = "hotp", + battle = "battle", + steam = "steam", + hex = "hex", + hhex = "hhex", +} + interface OTPEntryInterface { - type: number; // OTPType + type: OTPType; index: number; issuer: string; secret: string | null; @@ -42,7 +51,7 @@ interface RawOTPStorage { index: number; issuer?: string; secret: string; - type: string; + type: OTPType; counter?: number; period?: number; digits?: number; diff --git a/src/import.ts b/src/import.ts index 21bebdab..342debb5 100644 --- a/src/import.ts +++ b/src/import.ts @@ -211,7 +211,7 @@ export async function getEntryDataFromOTPAuthPerLine(importCode: string) { } let uri = item.split("otpauth://")[1]; - let type = uri.substr(0, 4).toLowerCase(); + let type = uri.substr(0, 4).toLowerCase() as OTPType; uri = uri.substr(5); let label = uri.split("?")[0]; const parameterPart = uri.split("?")[1]; @@ -282,15 +282,15 @@ export async function getEntryDataFromOTPAuthPerLine(importCode: string) { if ( !/^[2-7a-z]+=*$/i.test(secret) && /^[0-9a-f]+$/i.test(secret) && - type === "totp" + type === OTPType.totp ) { - type = "hex"; + type = OTPType.hex; } else if ( !/^[2-7a-z]+=*$/i.test(secret) && /^[0-9a-f]+$/i.test(secret) && - type === "hotp" + type === OTPType.hotp ) { - type = "hhex"; + type = OTPType.hhex; } exportData[hash] = { diff --git a/src/models/otp.ts b/src/models/otp.ts index cdfa38db..f9de7a0b 100644 --- a/src/models/otp.ts +++ b/src/models/otp.ts @@ -3,12 +3,12 @@ import { UserSettings } from "./settings"; import { EntryStorage } from "./storage"; export enum OTPType { - totp = 1, - hotp, - battle, - steam, - hex, - hhex, + totp = "totp", + hotp = "hotp", + battle = "battle", + steam = "steam", + hex = "hex", + hhex = "hhex", } export enum CodeState { @@ -223,8 +223,7 @@ export class OTPEntry implements OTPEntryInterface { this.period = decryptedData.period || 30; this.pinned = decryptedData.pinned || false; this.secret = decryptedData.secret; - // @ts-expect-error need a better way to do this - this.type = OTPType[decryptedData.type] || OTPType.totp; + this.type = decryptedData.type || OTPType.totp; if (this.type !== OTPType.hotp && this.type !== OTPType.hhex) { this.generate(); diff --git a/src/models/storage.ts b/src/models/storage.ts index 4b3699fb..fd78ab67 100644 --- a/src/models/storage.ts +++ b/src/models/storage.ts @@ -222,7 +222,7 @@ export class EntryStorage { encrypted, hash: entry.hash, index: entry.index, - type: OTPType[entry.type], + type: entry.type, secret, }; @@ -392,10 +392,7 @@ export class EntryStorage { } // remove unnecessary fields - if ( - !(entry.type === OTPType[OTPType.hotp]) && - !(entry.type === OTPType[OTPType.hhex]) - ) { + if (!(entry.type === OTPType.hotp) && !(entry.type === OTPType.hhex)) { delete entry.counter; } @@ -478,7 +475,7 @@ export class EntryStorage { algorithm: OTPAlgorithm; pinned: boolean; } = { - type: (parseInt(data[hash].type) as OTPType) || OTPType[OTPType.totp], + type: data[hash].type || OTPType.totp, index: data[hash].index || 0, issuer: data[hash].issuer || "", account: data[hash].account || "", @@ -617,29 +614,29 @@ export class EntryStorage { } if (!entryData.type) { - entryData.type = OTPType[OTPType.totp]; + entryData.type = OTPType.totp; } let type: OTPType; switch (entryData.type) { - case "totp": - case "hotp": - case "battle": - case "steam": - case "hex": - case "hhex": - type = OTPType[entryData.type]; + case OTPType.totp: + case OTPType.hotp: + case OTPType.battle: + case OTPType.steam: + case OTPType.hex: + case OTPType.hhex: + type = entryData.type; break; default: // we need correct the type here // and save it type = OTPType.totp; - entryData.type = OTPType[OTPType.totp]; + entryData.type = OTPType.totp; } let period: number | undefined; if ( - entryData.type === OTPType[OTPType.totp] && + entryData.type === OTPType.totp && entryData.period && entryData.period > 0 ) { From cfd775fb450929c5962593042850840920fb5d76 Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Wed, 11 Sep 2024 19:01:47 +0800 Subject: [PATCH 2/3] convert error otp type --- src/components/Popup/BackupPage.vue | 18 ++++++++++++++++-- src/definitions/module-interface.d.ts | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/Popup/BackupPage.vue b/src/components/Popup/BackupPage.vue index 3fb6a812..41ba0a2e 100644 --- a/src/components/Popup/BackupPage.vue +++ b/src/components/Popup/BackupPage.vue @@ -212,11 +212,25 @@ function getOneLineOtpBackupFile(entryData: { [hash: string]: RawOTPStorage }) { ? otpStorage.issuer + ":" + (otpStorage.account || "") : otpStorage.account || ""; let type = ""; - if (otpStorage.type === OTPType.totp || otpStorage.type === OTPType.hex) { + // We may have already have some error OTP type entries in the storage + // totp = 1 + // hotp = 2 + // battle = 3 + // steam = 4 + // hex = 5 + // hhex = 6 + if ( + otpStorage.type === OTPType.totp || + otpStorage.type === OTPType.hex || + (otpStorage.type as unknown) === 1 || + (otpStorage.type as unknown) === 5 + ) { type = OTPType.totp; } else if ( otpStorage.type === OTPType.hotp || - otpStorage.type === OTPType.hhex + otpStorage.type === OTPType.hhex || + (otpStorage.type as unknown) === 2 || + (otpStorage.type as unknown) === 6 ) { type = OTPType.hotp; } else { diff --git a/src/definitions/module-interface.d.ts b/src/definitions/module-interface.d.ts index 49426631..0d8470ec 100644 --- a/src/definitions/module-interface.d.ts +++ b/src/definitions/module-interface.d.ts @@ -62,7 +62,7 @@ interface AccountsState { entries: OTPEntryInterface[]; defaultEncryption: string; encryption: Map; - OTPType: number; + OTPType: OTPType; shouldShowPassphrase: boolean; sectorStart: boolean; sectorOffset: number; From 29b2b95526429ad72ff6375d714c38df2401776a Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Wed, 11 Sep 2024 20:39:49 +0800 Subject: [PATCH 3/3] fix otp type for export --- src/components/Popup/BackupPage.vue | 19 ++--------- src/models/otp.ts | 49 ++++++++++++++++++++++++++++- src/models/storage.ts | 28 +++++++++++++++-- 3 files changed, 77 insertions(+), 19 deletions(-) diff --git a/src/components/Popup/BackupPage.vue b/src/components/Popup/BackupPage.vue index 41ba0a2e..ce797271 100644 --- a/src/components/Popup/BackupPage.vue +++ b/src/components/Popup/BackupPage.vue @@ -71,6 +71,7 @@