code.dart 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import 'package:ente_auth/utils/totp_util.dart';
  2. class Code {
  3. static const defaultDigits = 6;
  4. static const defaultPeriod = 30;
  5. int? id;
  6. final String account;
  7. final String issuer;
  8. final int digits;
  9. final int period;
  10. final String secret;
  11. final Algorithm algorithm;
  12. final Type type;
  13. final String rawData;
  14. bool? hasSynced;
  15. Code(
  16. this.account,
  17. this.issuer,
  18. this.digits,
  19. this.period,
  20. this.secret,
  21. this.algorithm,
  22. this.type,
  23. this.rawData, {
  24. this.id,
  25. });
  26. static Code fromAccountAndSecret(String account, String secret) {
  27. return Code(
  28. account,
  29. "",
  30. defaultDigits,
  31. defaultPeriod,
  32. secret,
  33. Algorithm.sha1,
  34. Type.totp,
  35. "otpauth://totp/" +
  36. account +
  37. ":" +
  38. account +
  39. "?algorithm=SHA1&digits=6&issuer=" +
  40. account +
  41. "period=30&secret=" +
  42. secret,
  43. );
  44. }
  45. static Code fromRawData(String rawData) {
  46. Uri uri = Uri.parse(rawData);
  47. return Code(
  48. _getAccount(uri),
  49. _getIssuer(uri),
  50. _getDigits(uri),
  51. _getPeriod(uri),
  52. getSanitizedSecret(uri.queryParameters['secret']!),
  53. _getAlgorithm(uri),
  54. _getType(uri),
  55. rawData,
  56. );
  57. }
  58. static String _getAccount(Uri uri) {
  59. try {
  60. return uri.path.split(':')[1];
  61. } catch (e) {
  62. return "";
  63. }
  64. }
  65. static String _getIssuer(Uri uri) {
  66. try {
  67. return uri.path.split(':')[0].substring(1);
  68. } catch (e) {
  69. return "";
  70. }
  71. }
  72. static int _getDigits(Uri uri) {
  73. try {
  74. return int.parse(uri.queryParameters['digits']!);
  75. } catch (e) {
  76. return defaultDigits;
  77. }
  78. }
  79. static int _getPeriod(Uri uri) {
  80. try {
  81. return int.parse(uri.queryParameters['period']!);
  82. } catch (e) {
  83. return defaultPeriod;
  84. }
  85. }
  86. static Algorithm _getAlgorithm(Uri uri) {
  87. try {
  88. final algorithm =
  89. uri.queryParameters['algorithm'].toString().toLowerCase();
  90. if (algorithm == "sha256") {
  91. return Algorithm.sha256;
  92. } else if (algorithm == "sha512") {
  93. return Algorithm.sha512;
  94. }
  95. } catch (e) {
  96. // nothing
  97. }
  98. return Algorithm.sha1;
  99. }
  100. static Type _getType(Uri uri) {
  101. return uri.host == "totp" ? Type.totp : Type.hotp;
  102. }
  103. @override
  104. bool operator ==(Object other) {
  105. if (identical(this, other)) return true;
  106. return other is Code &&
  107. other.account == account &&
  108. other.issuer == issuer &&
  109. other.digits == digits &&
  110. other.period == period &&
  111. other.secret == secret &&
  112. other.type == type &&
  113. other.rawData == rawData;
  114. }
  115. @override
  116. int get hashCode {
  117. return account.hashCode ^
  118. issuer.hashCode ^
  119. digits.hashCode ^
  120. period.hashCode ^
  121. secret.hashCode ^
  122. type.hashCode ^
  123. rawData.hashCode;
  124. }
  125. }
  126. enum Type {
  127. totp,
  128. hotp,
  129. }
  130. enum Algorithm {
  131. sha1,
  132. sha256,
  133. sha512,
  134. }