From 80370d128c3d9adf9a75947e8acc66182346ec7a Mon Sep 17 00:00:00 2001 From: Aetherinox Date: Sat, 6 Apr 2024 09:38:36 -0700 Subject: [PATCH] fix: support for different otpauth url syntax adds support for otpauth://totp? and otpauth://totp/ --- app/scripts/models/entry-model.js | 1 + app/scripts/util/data/otp.js | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/scripts/models/entry-model.js b/app/scripts/models/entry-model.js index 06ffa126..4e21bb78 100644 --- a/app/scripts/models/entry-model.js +++ b/app/scripts/models/entry-model.js @@ -467,6 +467,7 @@ class EntryModel extends Model { if (otpUrl.isProtected) { otpUrl = otpUrl.getText(); } + // called only if secret provided, no formatted url if (Otp.isSecret(otpUrl.replace(/\s/g, ''))) { otpUrl = Otp.makeUrl(otpUrl.replace(/\s/g, '').toUpperCase()); } else if (otpUrl.toLowerCase().lastIndexOf('otpauth:', 0) !== 0) { diff --git a/app/scripts/util/data/otp.js b/app/scripts/util/data/otp.js index 2566157c..d4dbdeb1 100644 --- a/app/scripts/util/data/otp.js +++ b/app/scripts/util/data/otp.js @@ -135,12 +135,12 @@ Otp.leftPad = function (str, len) { }; Otp.parseUrl = function (url) { - const match = /^otpauth:\/\/(\w+)\/([^\?]+)\?(.*)/i.exec(url); + const match = /^otpauth:\/\/(\w+)(?:\/([^\?]+)\?|\?)(.*)/i.exec(url); if (!match) { throw 'Not OTP url'; } const params = {}; - const label = decodeURIComponent(match[2]); + const label = decodeURIComponent(match[2] ?? 'default'); if (label) { const parts = label.split(':'); params.issuer = parts[0].trim(); @@ -148,7 +148,8 @@ Otp.parseUrl = function (url) { params.account = parts[1].trim(); } } - params.type = match[1].toLowerCase(); + params.type = match[1].toLowerCase(); // returns "totp" + // match[3] = secret=XXXXXXXXXXXXX&period=30&digits=6&algorithm=SHA1 match[3].split('&').forEach((part) => { const parts = part.split('=', 2); params[parts[0].toLowerCase()] = decodeURIComponent(parts[1]);