From ef897347c389c36c1a4e8f27bcac24423389a2df Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Tue, 27 Aug 2024 02:11:43 +0800 Subject: [PATCH] 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 ) {