ente/lib/models/code.dart
2022-11-01 11:43:06 +05:30

148 lines
2.8 KiB
Dart

class Code {
static const defaultDigits = 6;
static const defaultPeriod = 30;
int? id;
final String account;
final String issuer;
final int digits;
final int period;
final String secret;
final Algorithm algorithm;
final Type type;
final String rawData;
Code(
this.account,
this.issuer,
this.digits,
this.period,
this.secret,
this.algorithm,
this.type,
this.rawData, {
this.id,
});
static Code fromAccountAndSecret(String account, String secret) {
return Code(
account,
"",
defaultDigits,
defaultPeriod,
secret,
Algorithm.sha1,
Type.totp,
"otpauth://totp/" +
account +
":" +
account +
"?algorithm=SHA1&digits=6&issuer=" +
account +
"period=30&secret=" +
secret,
);
}
static Code fromRawData(String rawData) {
Uri uri = Uri.parse(rawData);
return Code(
_getAccount(uri),
_getIssuer(uri),
_getDigits(uri),
_getPeriod(uri),
uri.queryParameters['secret']!,
_getAlgorithm(uri),
_getType(uri),
rawData,
);
}
static String _getAccount(Uri uri) {
try {
return uri.path.split(':')[1];
} catch (e) {
return "";
}
}
static String _getIssuer(Uri uri) {
try {
return uri.path.split(':')[0].substring(1);
} catch (e) {
return "";
}
}
static int _getDigits(Uri uri) {
try {
return int.parse(uri.queryParameters['digits']!);
} catch (e) {
return defaultDigits;
}
}
static int _getPeriod(Uri uri) {
try {
return int.parse(uri.queryParameters['period']!);
} catch (e) {
return defaultPeriod;
}
}
static Algorithm _getAlgorithm(Uri uri) {
try {
final algorithm =
uri.queryParameters['algorithm'].toString().toLowerCase();
if (algorithm == "sha256") {
return Algorithm.sha256;
} else if (algorithm == "sha512") {
return Algorithm.sha512;
}
} catch (e) {
// nothing
}
return Algorithm.sha1;
}
static Type _getType(Uri uri) {
return uri.host == "totp" ? Type.totp : Type.hotp;
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Code &&
other.account == account &&
other.issuer == issuer &&
other.digits == digits &&
other.period == period &&
other.secret == secret &&
other.type == type &&
other.rawData == rawData;
}
@override
int get hashCode {
return account.hashCode ^
issuer.hashCode ^
digits.hashCode ^
period.hashCode ^
secret.hashCode ^
type.hashCode ^
rawData.hashCode;
}
}
enum Type {
totp,
hotp,
}
enum Algorithm {
sha1,
sha256,
sha512,
}