From dfd7a02e12f977e45699b6a1bbbd49c22a385633 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 21:26:41 +0800 Subject: [PATCH 01/12] Show placeholder "Calculating" Fixes #2 --- apps/authentiwatch/app.js | 43 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index da8b6d220..b5c306b8b 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -6,8 +6,11 @@ const algos = { "SHA256":{sha:crypto.SHA256,retsz:32,blksz:64 }, "SHA1" :{sha:crypto.SHA1 ,retsz:20,blksz:64 }, }; +const calculating = "Calculating"; +const notokens = "No tokens"; +const notsupported = "Not supported"; -var tokens = require("Storage").readJSON("authentiwatch.json", true) || []; +var tokens = require("Storage").readJSON("authentiwatch.json", true) || {data:[],count:0}; tokens = tokens.data; // QR Code Text @@ -67,9 +70,8 @@ function do_hmac(key, message, algo) { var v = new DataView(ret, ret[ret.length - 1] & 0x0F, 4); return v.getUint32(0) & 0x7FFFFFFF; } -function hotp(token) { +function hotp(d, token, dohmac) { var tick; - var d = new Date(); if (token.period > 0) { // RFC6238 - timed var seconds = Math.floor(d.getTime() / 1000); @@ -82,15 +84,17 @@ function hotp(token) { var v = new DataView(msg.buffer); v.setUint32(0, tick >> 16 >> 16); v.setUint32(4, tick & 0xFFFFFFFF); - var ret = ""; - try { - var hash = do_hmac(b32decode(token.secret), msg, token.algorithm.toUpperCase()); - ret = "" + hash % Math.pow(10, token.digits); - while (ret.length < token.digits) { - ret = "0" + ret; + var ret = calculating; + if (dohmac) { + try { + var hash = do_hmac(b32decode(token.secret), msg, token.algorithm.toUpperCase()); + ret = "" + hash % Math.pow(10, token.digits); + while (ret.length < token.digits) { + ret = "0" + ret; + } + } catch(err) { + ret = notsupported; } - } catch(err) { - ret = "Not supported"; } return {hotp:ret, next:((token.period > 0) ? ((tick + 1) * token.period * 1000) : d.getTime() + 30000)}; } @@ -158,6 +162,9 @@ function draw() { var d = new Date(); if (state.curtoken != -1) { var t = tokens[state.curtoken]; + if (state.otp == calculating) { + state.otp = hotp(d, t, true).hotp; + } if (d.getTime() > state.nextTime) { if (state.hide == 0) { // auto-hide the current token @@ -168,7 +175,7 @@ function draw() { state.nextTime = 0; } else { // time to generate a new token - var r = hotp(t); + var r = hotp(d, t, state.otp != ""); state.nextTime = r.next; state.otp = r.hotp; if (t.period <= 0) { @@ -196,7 +203,13 @@ function draw() { if (state.drawtimer) { clearTimeout(state.drawtimer); } - state.drawtimer = setTimeout(draw, (tokens[state.curtoken].period > 0) ? 1000 : state.nexttime - d.getTime()); + var dly; + if (tokens[state.curtoken].period > 0) { + dly = (state.otp == calculating) ? 1 : 1000; + } else { + dly = state.nexttime - d.getTime(); + } + state.drawtimer = setTimeout(draw, dly); if (tokens[state.curtoken].period <= 0) { state.hide = 0; } @@ -211,7 +224,7 @@ function draw() { } else { g.setFont("Vector", 30); g.setFontAlign(0, 0, 0); - g.drawString("No tokens", Bangle.appRect.x + Bangle.appRect.w / 2,Bangle.appRect.y + Bangle.appRect.h / 2, false); + g.drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2,Bangle.appRect.y + Bangle.appRect.h / 2, false); } } @@ -232,6 +245,7 @@ function onTouch(zone, e) { if (y > Bangle.appRect.h) { state.listy += (y - Bangle.appRect.h); } + state.otp = ""; } state.nextTime = 0; state.curtoken = id; @@ -261,6 +275,7 @@ function onSwipe(e) { let save={data:tokens,count:tokens.length}; require("Storage").writeJSON("authentiwatch.json", save); state.nextTime = 0; + state.otp = ""; state.hide = 2; draw(); } From 60a8c487ad9035780ffbaf0a9a5db88d9743fe99 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:05:53 +0800 Subject: [PATCH 02/12] Support updated settings file --- apps/authentiwatch/app.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index b5c306b8b..58e64a48d 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -10,8 +10,9 @@ const calculating = "Calculating"; const notokens = "No tokens"; const notsupported = "Not supported"; -var tokens = require("Storage").readJSON("authentiwatch.json", true) || {data:[],count:0}; -tokens = tokens.data; +var settings = require("Storage").readJSON("authentiwatch.json", true) || {tokens:[],misc:{}}; +if (settings.data ) tokens = settings.data ; /* v0.02 settings */ +if (settings.tokens) tokens = settings.tokens; /* v0.03+ settings */ // QR Code Text // @@ -272,8 +273,8 @@ function onSwipe(e) { } if (e == -1 && state.curtoken != -1 && tokens[state.curtoken].period <= 0) { tokens[state.curtoken].period--; - let save={data:tokens,count:tokens.length}; - require("Storage").writeJSON("authentiwatch.json", save); + let newsettings={tokens:tokens,misc:settings.misc}; + require("Storage").writeJSON("authentiwatch.json", newsettings); state.nextTime = 0; state.otp = ""; state.hide = 2; From d4ddf22399667a2cb98f73c375a98f11869512a3 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:15:55 +0800 Subject: [PATCH 03/12] Try new JSON settings format --- apps/authentiwatch/interface.html | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 6b39c148b..322a03448 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -35,8 +35,9 @@ const otpAuthUrl = 'otpauth://'; const tokentypes = ['TOTP (Timed)', 'HOTP (Counter)']; -/* Array of TOTP tokens */ -var tokens=[]; +/* Settings */ +var settings = {tokens:[], misc:{}}; +var tokens = settings.tokens; /* Remove any non-base-32 characters from the given string and collapses * whitespace to a single space. Optionally removes all whitespace from @@ -319,23 +320,21 @@ function doScan() { */ function loadTokens() { Util.showModal('Loading...'); - Puck.eval(`require('Storage').read(${JSON.stringify('authentiwatch.json')})`,data=>{ + Puck.eval(`require('Storage').readJSON(${JSON.stringify('authentiwatch.json')})`,data=>{ Util.hideModal(); - try { - let load = JSON.parse(data); - tokens = load.data; - updateTokens(); - } catch { - tokens = []; - } + if (data.data ) settings.tokens = data.data ; /* v0.02 settings */ + if (data.tokens) settings.tokens = data.tokens; /* v0.03+ settings */ + if (data.misc ) settings.misc = data.misc ; /* v0.03+ settings */ + tokens = settings.tokens; + updateTokens(); }); } /* Save settings as a JSON file on the watch. */ function saveTokens() { Util.showModal('Saving...'); - let save={data:tokens,count:tokens.length}; - Puck.write(`\x10require('Storage').write(${JSON.stringify('authentiwatch.json')},${JSON.stringify(save)})\n`,()=>{ + let newsettings={tokens:tokens,misc:settings.misc}; + Puck.write(`\x10require('Storage').writeJSON(${JSON.stringify('authentiwatch.json')},${JSON.stringify(newsettings)})\n`,()=>{ Util.hideModal(); }); } From 16f20970d9294d144347cfb02605d1ddc4472be2 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:21:21 +0800 Subject: [PATCH 04/12] Limit scanned label length Fixed #5 --- apps/authentiwatch/interface.html | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/interface.html b/apps/authentiwatch/interface.html index 322a03448..26533b17b 100644 --- a/apps/authentiwatch/interface.html +++ b/apps/authentiwatch/interface.html @@ -262,6 +262,7 @@ qrcode.callback = res => { scanning = false; editToken(parseInt(document.forms['edittoken'].elements['tokenid'].value)); t['label'] = (t['issuer'] == '') ? t['account'] : t['issuer'] + ' (' + t['account'] + ')'; + t['label'] = t['label'].substr(0, 10); var fe = document.forms['edittoken'].elements; if (res.startsWith(otpAuthUrl + 'hotp/')) { t['period'] = '30'; From 4d239bf71e5cc8312e3a5c762088c27ad9f20491 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:24:43 +0800 Subject: [PATCH 05/12] Version 0.03 --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 55a43f5db..40cd5df65 100644 --- a/apps.json +++ b/apps.json @@ -4434,7 +4434,7 @@ "shortName": "AuthWatch", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], - "version": "0.02", + "version": "0.03", "description": "Google Authenticator compatible tool.", "tags": "tool", "interface": "interface.html", From 21961edf42856a2b82f45a8bbbb6751247fa658d Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:26:01 +0800 Subject: [PATCH 06/12] Update ChangeLog --- apps/authentiwatch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/authentiwatch/ChangeLog b/apps/authentiwatch/ChangeLog index 67cb00c67..50cf3fcea 100644 --- a/apps/authentiwatch/ChangeLog +++ b/apps/authentiwatch/ChangeLog @@ -1,2 +1,3 @@ +0.03: Add "Calculating" placeholder, update JSON save format 0.02: Fix JSON save format 0.01: First release From 26cc978a40ffcf415db086025cc63910f7e8e943 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 22:29:37 +0800 Subject: [PATCH 07/12] Update README.md --- apps/authentiwatch/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/authentiwatch/README.md b/apps/authentiwatch/README.md index 403770c2b..8c0d9509b 100644 --- a/apps/authentiwatch/README.md +++ b/apps/authentiwatch/README.md @@ -1,5 +1,8 @@ # Authentiwatch - 2FA Authenticator +* GitHub: https://github.com/andrewgoz/Authentiwatch +* Bleeding edge AppLoader: https://andrewgoz.github.io/Authentiwatch/ + ## Supports * Google Authenticator compatible 2-factor authentication From 3305a5db6ab4e40ef45ea54513c656b503195450 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 23:23:44 +0800 Subject: [PATCH 08/12] Colour icon --- apps/authentiwatch/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/app-icon.js b/apps/authentiwatch/app-icon.js index 27ced695e..c901fb843 100644 --- a/apps/authentiwatch/app-icon.js +++ b/apps/authentiwatch/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mUywkBiIADCxoTFAAcQGBwY/DDQIKDBiMDDCgGCBI4YMGAIDFDCAFEBQwYLFgIYEGQgYMApoYJGAJjFMogYMSQgCDDBwDCY4oMEDBZgHHQQYQf4oYVBgwYQBogYPPYZpFDBKMEDAbdDCxT9IDYIFFABqSEAogySQYoWNFgrFDJZoQBJggYRBwhLGDBwyFDCZGEDCYAEDGrIMbwhnGDEpLGAwxlLFQgQDJiYoFDDAZDDCpMDMpQOCNxQYNBo4KKBpwYYBYJ8NeJgYkLBQY8UYQXVGQIwN")) +require("heatshrink").decompress(atob("mEwxH+AH4AD64ADFlgAFF04INFz4LUF0QwjEBwv/FzwwgF/4v/F6nMAAWi1AFD5nOeEHPEweoFooAB5/X5wvdFwotG5nN6/WAoQuaEoguHSYPQLwIIDF8uo5ouB6AJEFzuiFwup5/WFwI6GL0esXYKMBHYy9j1WqfBSOhBIYKJF8gAKF/4v6cZAvhGDAuWSDAvXMCwuYF+AwUFzX+0XGGAgxKFrYuBAAQxEeg4tcF4oABBQnGAAgv/F6b5KXsIvIGAqNnF/69fX8ZeSF7btNR8IuOF75ePL8ouOd74NKF8IANF94wEF1QAXA")) From 86ea0554b37139afc295437d45b2d85c9b4aee3c Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Wed, 1 Dec 2021 23:26:45 +0800 Subject: [PATCH 09/12] Colour icon --- apps/authentiwatch/app.png | Bin 964 -> 1630 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/authentiwatch/app.png b/apps/authentiwatch/app.png index 208fb63b348a960529406347f23aa9363271a388..8775d3e4079e80a8af83fd03b7dc92619e23d648 100644 GIT binary patch literal 1630 zcmV-k2BGN({N<~^ig*p|{RvHL|#Kc=E zP^r93Egw*|eMJ2LRR>6DV(J$r7#lBTl{SHdXd)^=6tyrk0pCDdd68h+##X#4)O~T9 zlEkUs?!9LpY&Xu09s67xRs5wRJ$~*vet!R)b9_(kg&(=3Q(u%$r&lYbc51D+ipW}^ zAD9%882ft|4Kb=l*R7xEJ)&QT(&d%Q4iJ4GA2ims1j|#lj`nsjy0g}n& z=fL$q3b;NVk3SW(cC7-M5_HE;%?udgoIkU^)D(E zWRQsbPiwu}ah#1>lRozmj|n^^aD@k5#S-N6xLtAb%lkPWjZs8c34rFi3;Dfgvt3Uk zqW^hG40xV*R77r4vqyhD^$*5Hhyl17=5kny8>R-I>)+k9YCz`+|~LU zw#!w#71ThW`#>g>8PZeZ|5E8kL|xYm$K!`w7Tc#zmn_G?fQE4+Zx8PFiY z9`E01V6Q2Q@eG{%E4OOJ2ektWC2$oCuUQBWaP}mW=D=RI0r&C)5E(&=Ul$X(EfJx# zpuY&)WgTyu@Rc5_n0u5 z?tv%#iIM|72^MYEs_g8mlnODTbB7S;6uAO)$LITquRpL2IMgbTkpT@?`*S4+?C4_f zYJ5fCpU9ksnVItE?p_!etOGtDZ#H2vn*mL~f7`n*gu^Uc5;af)3|_{?g?ACW!Hl69 zHbF8nAcCtKU2FtY`7F))&BsRf0;5f=A?wds7LwWKOjOUT(r8vYy%<)p-NGH}kP*Uark`g~4@TGGhqNg8b96!EE_J z8xOY59N}yz%0TsV^*G%dheUrJz@_8gat)6MIZg*MFfq;+JdTE<5RR9Z5tL2L}m za?p1^st^8OG<)P)^S^vm!TzQ6ctQhCuG~Vga#I$%HwFaFU7P}J|1~Wbm#*77CF3PD@jBbljQH~+JTtP3yg%PmosE8I;7#M1ri)iJKe)^gg_Y5Xosc&pGj-dxF`zQCMZT@h8lgz#tN9^hS4Le7e< zE%1EM7hDk4z>@&~gxINe}JmN(x^HNV2#FC>_Rq)?OOy9_fSi2F4O^ch*3yb`s@?i z1G#?*97nz3G*AI-1NQs;>;U?JQQ$A|3-|SWjpa|Gb^Y>RlRNsji4&tdEh;84fQ2lbO2fOf*u2Fe=Wtn1g)r@+Vr;j zd;xYCxDG1StRjVX{^-Ii#z7srTrqbIyezQOiUL6|@W>b3A#$%`y~3?WO?Dlx&x!(| z5ii#V@ixdR;54cf`5qGBBHjvhE5z=$Q5zya<#BL_J{;g|(FA!_>_;_r2lchA;G-sh ztv*hzhBG4e294bTe}2ZUKrp8X;2}y(Eo%ORaom$)g~sjxA1vwMhareuZ9#mb4V<2Q zf+^%5bQ4AByV=0W=HsvsA zSC2ZQl!TBJ;YVFvdn$cEl_(3S)#(aqZ!z_aJ!&NmknbE!yvLlGt-)&b)}P{eSu;Vd84mq`~ Date: Wed, 1 Dec 2021 23:42:17 +0800 Subject: [PATCH 10/12] Improve token display Limit label length. Reduce digits font size until it fits. --- apps/authentiwatch/app.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 58e64a48d..7b442e0e8 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -115,7 +115,7 @@ function drawToken(id, r) { var y1 = r.y; var x2 = r.x + r.w - 1; var y2 = r.y + r.h - 1; - var adj; + var adj, sz; g.setClipRect(Math.max(x1, Bangle.appRect.x ), Math.max(y1, Bangle.appRect.y ), Math.min(x2, Bangle.appRect.x2), Math.min(y2, Bangle.appRect.y2)); if (id == state.curtoken) { @@ -135,7 +135,7 @@ function drawToken(id, r) { adj = (y1 + y2) / 2; } g.clearRect(x1, y1, x2, y2); - g.drawString(tokens[id].label, (x1 + x2) / 2, adj, false); + g.drawString(tokens[id].label.substr(0, 10), (x1 + x2) / 2, adj, false); if (id == state.curtoken) { if (tokens[id].period > 0) { // timed - draw progress bar @@ -149,7 +149,10 @@ function drawToken(id, r) { adj = 5; } // digits just below label - g.setFont("Vector", (state.otp.length > 8) ? 26 : 30); + sz = 30; + do { + g.setFont("Vector", sz--); + } while (g.stringWidth(state.otp) > r.w); g.drawString(state.otp, (x1 + x2) / 2 + adj, y1 + 16, false); } // shaded lines top and bottom From 012982e910436c5abe2ad6f28f68a96762343a18 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 16:03:22 +0800 Subject: [PATCH 11/12] Update README.md --- apps/authentiwatch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentiwatch/README.md b/apps/authentiwatch/README.md index 8c0d9509b..8d0e74a0c 100644 --- a/apps/authentiwatch/README.md +++ b/apps/authentiwatch/README.md @@ -1,6 +1,6 @@ # Authentiwatch - 2FA Authenticator -* GitHub: https://github.com/andrewgoz/Authentiwatch +* GitHub: https://github.com/andrewgoz/Authentiwatch <-- Report bugs here * Bleeding edge AppLoader: https://andrewgoz.github.io/Authentiwatch/ ## Supports From cb8ee706252666bbfd215af26ecd87acc39d077c Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Thu, 2 Dec 2021 16:05:36 +0800 Subject: [PATCH 12/12] Update app.js --- apps/authentiwatch/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/authentiwatch/app.js b/apps/authentiwatch/app.js index 7b442e0e8..85c76b5d1 100644 --- a/apps/authentiwatch/app.js +++ b/apps/authentiwatch/app.js @@ -152,7 +152,7 @@ function drawToken(id, r) { sz = 30; do { g.setFont("Vector", sz--); - } while (g.stringWidth(state.otp) > r.w); + } while (g.stringWidth(state.otp) > (r.w - adj)); g.drawString(state.otp, (x1 + x2) / 2 + adj, y1 + 16, false); } // shaded lines top and bottom @@ -228,7 +228,7 @@ function draw() { } else { g.setFont("Vector", 30); g.setFontAlign(0, 0, 0); - g.drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2,Bangle.appRect.y + Bangle.appRect.h / 2, false); + g.drawString(notokens, Bangle.appRect.x + Bangle.appRect.w / 2, Bangle.appRect.y + Bangle.appRect.h / 2, false); } }