From 0c0476093124776539b7df49ff5ce8808d9b431a Mon Sep 17 00:00:00 2001 From: Li Zhe Date: Wed, 25 Jul 2018 00:35:18 +0800 Subject: [PATCH] support period --- css/popup.css | 10 +++++++--- src/background.ts | 10 ++++++++++ src/models/encryption.ts | 1 - src/models/interface.ts | 2 ++ src/models/key-utilities.ts | 5 +++-- src/models/otp.ts | 11 +++++++++-- src/models/storage.ts | 13 ++++++++++++- src/ui/entry.ts | 37 +++++++++++++++++++++++-------------- src/ui/ui.ts | 2 +- view/popup.html | 4 ++-- 10 files changed, 69 insertions(+), 26 deletions(-) diff --git a/css/popup.css b/css/popup.css index ea41190db..65d51099f 100644 --- a/css/popup.css +++ b/css/popup.css @@ -338,7 +338,7 @@ body { display: block; } -#codes.timeout .code:not(.hotp) { +#codes:not(.edit) .code.timeout:not(.hotp) { animation: twinkling 1s infinite ease-in-out; } @@ -588,12 +588,16 @@ body { stroke: gray; stroke-width: 8px; stroke-dasharray: 25.12; - animation: 30s linear infinite timer; + animation-name: timer; + animation-iteration-count: infinite; + animation-timing-function: linear; } #codes.edit .sector, #codes.edit .counter { - display: none; + position: absolute; + left: -1000px; + opacity: 0; } #menu { diff --git a/src/background.ts b/src/background.ts index 48c6362a0..9e167bdb3 100644 --- a/src/background.ts +++ b/src/background.ts @@ -80,6 +80,7 @@ async function getTotp(text: string, passphrase: string) { let account = ''; let secret = ''; let issuer = ''; + let period: number|undefined = undefined; try { label = decodeURIComponent(label); @@ -106,6 +107,12 @@ async function getTotp(text: string, passphrase: string) { } else if (parameter[0].toLowerCase() === 'counter') { let counter = Number(parameter[1]); counter = (isNaN(counter) || counter < 0) ? 0 : counter; + } else if (parameter[0].toLowerCase() === 'period') { + period = Number(parameter[1]); + period = (isNaN(period) || period < 0 || period > 60 || + 60 % period !== 0) ? + undefined : + period; } }); @@ -136,6 +143,9 @@ async function getTotp(text: string, passphrase: string) { index: 0, counter: 0 }; + if (period) { + entryData[hash].period = period; + } await EntryStorage.import(encryption, entryData); chrome.tabs.sendMessage(id, {action: 'added', account}); } diff --git a/src/models/encryption.ts b/src/models/encryption.ts index b539321a9..639e1e89f 100644 --- a/src/models/encryption.ts +++ b/src/models/encryption.ts @@ -42,7 +42,6 @@ class Encryption { !/^[0-9a-f]+$/i.test(decryptedSecret) && !/^blz\-/.test(decryptedSecret) && !/^bliz\-/.test(decryptedSecret) && !/^stm\-/.test(decryptedSecret)) { - console.log(decryptedSecret); return 'Encrypted'; } diff --git a/src/models/interface.ts b/src/models/interface.ts index b7e48e995..b7a0eceeb 100644 --- a/src/models/interface.ts +++ b/src/models/interface.ts @@ -19,6 +19,7 @@ interface OTP { hash: string; counter: number; code: string; + period: number; create(encryption: Encryption): Promise; update(encryption: Encryption): Promise; next(encryption: Encryption): Promise; @@ -35,6 +36,7 @@ interface OTPStorage { secret: string; type: string; counter: number; + period?: number; } /* tslint:disable-next-line:interface-name */ diff --git a/src/models/key-utilities.ts b/src/models/key-utilities.ts index 470b9f0bd..db1ee509b 100644 --- a/src/models/key-utilities.ts +++ b/src/models/key-utilities.ts @@ -92,7 +92,8 @@ class KeyUtilities { return output; } - static generate(type: OTPType, secret: string, counter: number) { + static generate( + type: OTPType, secret: string, counter: number, period: number) { secret = secret.replace(/\s/g, ''); let len = 6; let b26 = false; @@ -128,7 +129,7 @@ class KeyUtilities { if (localStorage.offset) { epoch = epoch + Number(localStorage.offset); } - counter = Math.floor(epoch / 30); + counter = Math.floor(epoch / period); } const time = this.leftpad(this.dec2hex(counter), 16, '0'); diff --git a/src/models/otp.ts b/src/models/otp.ts index 4f8b4ad27..3125e30d1 100644 --- a/src/models/otp.ts +++ b/src/models/otp.ts @@ -12,11 +12,12 @@ class OTPEntry implements OTP { account: string; hash: string; counter: number; + period: number; code = '••••••'; constructor( type: OTPType, issuer: string, secret: string, account: string, - index: number, counter: number, hash?: string) { + index: number, counter: number, period?: number, hash?: string) { this.type = type; this.index = index; this.issuer = issuer; @@ -26,6 +27,11 @@ class OTPEntry implements OTP { hash : CryptoJS.MD5(secret).toString(); this.counter = counter; + if (this.type === OTPType.totp && period) { + this.period = period; + } else { + this.period = 30; + } if (this.type !== OTPType.hotp && this.type !== OTPType.hhex) { this.generate(); } @@ -61,7 +67,8 @@ class OTPEntry implements OTP { this.code = 'Encrypted'; } else { try { - this.code = KeyUtilities.generate(this.type, this.secret, this.counter); + this.code = KeyUtilities.generate( + this.type, this.secret, this.counter, this.period); } catch (error) { this.code = 'Invalid'; if (parent) { diff --git a/src/models/storage.ts b/src/models/storage.ts index f538fa11a..346824670 100644 --- a/src/models/storage.ts +++ b/src/models/storage.ts @@ -143,6 +143,11 @@ class EntryStorage { data[hash].issuer = data[hash].issuer || ''; data[hash].type = data[hash].type || OTPType[OTPType.totp]; data[hash].counter = data[hash].counter || 0; + const period = data[hash].period; + if (data[hash].type !== OTPType[OTPType.totp] || + period && (isNaN(period) || period <= 0)) { + delete data[hash].period; + } if (/^(blz\-|bliz\-)/.test(data[hash].secret)) { const secretMatches = @@ -306,6 +311,12 @@ class EntryStorage { needMigrate = true; } + let period = 30; + if (entryData.type === OTPType[OTPType.totp] && + entryData.period && entryData.period > 0) { + period = entryData.period; + } + entryData.secret = entryData.encrypted ? encryption.getDecryptedSecret(entryData.secret, hash) : entryData.secret; @@ -354,7 +365,7 @@ class EntryStorage { const entry = new OTPEntry( type, entryData.issuer, entryData.secret, entryData.account, entryData.index, entryData.counter, - entryData.hash); + period, entryData.hash); data.push(entry); // we need correct the hash diff --git a/src/ui/entry.ts b/src/ui/entry.ts index 4f16b7ded..7523d0f48 100644 --- a/src/ui/entry.ts +++ b/src/ui/entry.ts @@ -15,9 +15,11 @@ async function updateCode(app: any) { let second = new Date().getSeconds(); if (localStorage.offset) { // prevent second from negative - second += Number(localStorage.offset) + 30; + second += Number(localStorage.offset) + 60; } - second = second % 30; + + second = second % 60; + app.second = second; // only when sector is not started (timer is not initialized), // passphrase box should not be shown (no passphrase set) or @@ -30,18 +32,24 @@ async function updateCode(app: any) { app.sectorOffset = -second; } - if (second > 25) { - app.class.timeout = true; - } else { - app.class.timeout = false; - } - if (second < 1) { - const entries = app.entries as OTP[]; - for (let i = 0; i < entries.length; i++) { - if (entries[i].type !== OTPType.hotp && - entries[i].type !== OTPType.hhex) { - entries[i].generate(); - } + // if (second > 25) { + // app.class.timeout = true; + // } else { + // app.class.timeout = false; + // } + // if (second < 1) { + // const entries = app.entries as OTP[]; + // for (let i = 0; i < entries.length; i++) { + // if (entries[i].type !== OTPType.hotp && + // entries[i].type !== OTPType.hhex) { + // entries[i].generate(); + // } + // } + // } + const entries = app.entries as OTP[]; + for (let i = 0; i < entries.length; i++) { + if (entries[i].type !== OTPType.hotp && entries[i].type !== OTPType.hhex) { + entries[i].generate(); } } } @@ -226,6 +234,7 @@ async function entry(_ui: UI) { sector: '', sectorStart: false, sectorOffset: 0, + second: 0, notification: '', notificationTimeout: 0, filter: true, diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 05f246a8c..069e1e69a 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -75,7 +75,7 @@ class UI { this.instance.updateCode(); setInterval(async () => { await this.instance.updateCode(); - }, 500); + }, 1000); }, 0); return this.instance; diff --git a/view/popup.html b/view/popup.html index 8d1232245..2127b114e 100644 --- a/view/popup.html +++ b/view/popup.html @@ -45,7 +45,7 @@
- +
@@ -53,7 +53,7 @@
-
+