diff --git a/lib/models/code.dart b/lib/models/code.dart index d5944354e..dd47c31be 100644 --- a/lib/models/code.dart +++ b/lib/models/code.dart @@ -90,6 +90,7 @@ class Code { static Code fromRawData(String rawData) { Uri uri = Uri.parse(rawData); + try { return Code( _getAccount(uri), _getIssuer(uri), @@ -100,6 +101,15 @@ class Code { _getType(uri), rawData, ); + } catch(e) { + // if account name contains # without encoding, + // rest of the url are treated as url fragment + if(rawData.contains("#")) { + return Code.fromRawData(rawData.replaceAll("#", '%23')); + } else { + rethrow; + } + } } static String _getAccount(Uri uri) { diff --git a/test/models/code_test.dart b/test/models/code_test.dart index 1521c4817..7eb91e901 100644 --- a/test/models/code_test.dart +++ b/test/models/code_test.dart @@ -19,4 +19,14 @@ void main() { expect(code.account, "testdata@ente.io", reason: "accountMismatch"); expect(code.secret, "ASKZNWOU6SVYAMVS"); }); +// + + test("parseWithFunnyAccountName", () { + final code = Code.fromRawData( + "otpauth://totp/Mongo Atlas:Acc !@#444?algorithm=sha1&digits=6&issuer=Mongo Atlas&period=30&secret=NI4CTTFEV4G2JFE6", + ); + expect(code.issuer, "Mongo Atlas", reason: "issuerMismatch"); + expect(code.account, "Acc !@#444", reason: "accountMismatch"); + expect(code.secret, "NI4CTTFEV4G2JFE6"); + }); }