Appwite 1.5 support

This commit is contained in:
Jake Barnby
2024-03-08 10:44:03 +01:00
parent 1dacc5d3ef
commit 1a8d525cae
27 changed files with 341 additions and 160 deletions
+2 -2
View File
@@ -13,7 +13,7 @@ Appwrite is an open-source backend as a service server that abstract and simplif
![Appwrite](https://appwrite.io/images/github.png)
![Appwrite](https://github.com/appwrite/appwrite/raw/main/public/images/github.png)
## Installation
@@ -21,7 +21,7 @@ Add this to your package's `pubspec.yaml` file:
```yml
dependencies:
appwrite: ^12.0.0-rc.6
appwrite: ^12.0.0
```
You can install packages from the command line:
@@ -6,6 +6,6 @@ Client client = Client()
Account account = Account(client);
MfaType result = await account.addAuthenticator(
MfaType result = await account.createMfaAuthenticator(
type: AuthenticatorType.totp,
);
@@ -6,6 +6,6 @@ Client client = Client()
Account account = Account(client);
MfaChallenge result = await account.createChallenge(
factor: AuthenticationFactor.totp,
MfaChallenge result = await account.createMfaChallenge(
factor: AuthenticationFactor.email,
);
@@ -0,0 +1,9 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('5df5acd0d48c2'); // Your project ID
Account account = Account(client);
MfaRecoveryCodes result = await account.createMfaRecoveryCodes();
@@ -6,7 +6,7 @@ Client client = Client()
Account account = Account(client);
await account.deleteAuthenticator(
await account.deleteMfaAuthenticator(
type: AuthenticatorType.totp,
otp: '<OTP>',
);
@@ -0,0 +1,9 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('5df5acd0d48c2'); // Your project ID
Account account = Account(client);
MfaRecoveryCodes result = await account.getMfaRecoveryCodes();
@@ -6,4 +6,4 @@ Client client = Client()
Account account = Account(client);
MfaFactors result = await account.listFactors();
MfaFactors result = await account.listMfaFactors();
@@ -6,7 +6,7 @@ Client client = Client()
Account account = Account(client);
User result = await account.verifyAuthenticator(
User result = await account.updateMfaAuthenticator(
type: AuthenticatorType.totp,
otp: '<OTP>',
);
@@ -6,7 +6,7 @@ Client client = Client()
Account account = Account(client);
result = await account.updateChallenge(
result = await account.updateMfaChallenge(
challengeId: '<CHALLENGE_ID>',
otp: '<OTP>',
);
@@ -0,0 +1,9 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('5df5acd0d48c2'); // Your project ID
Account account = Account(client);
MfaRecoveryCodes result = await account.updateMfaRecoveryCodes();
+1 -1
View File
@@ -1,8 +1,8 @@
/// Appwrite Enums
library appwrite.enums;
part 'src/enums/authentication_factor.dart';
part 'src/enums/authenticator_type.dart';
part 'src/enums/authentication_factor.dart';
part 'src/enums/o_auth_provider.dart';
part 'src/enums/browser.dart';
part 'src/enums/credit_card.dart';
+1
View File
@@ -44,6 +44,7 @@ part 'src/models/currency.dart';
part 'src/models/phone.dart';
part 'src/models/headers.dart';
part 'src/models/mfa_challenge.dart';
part 'src/models/mfa_recovery_codes.dart';
part 'src/models/mfa_type.dart';
part 'src/models/mfa_factors.dart';
part 'src/models/subscriber.dart';
+118 -43
View File
@@ -184,9 +184,76 @@ class Account extends Service {
}
/// Add Authenticator
///
/// Add an authenticator app to be used as an MFA factor. Verify the
/// authenticator using the [verify
/// authenticator](/docs/references/cloud/client-web/account#verifyAuthenticator)
/// method.
Future<models.MfaType> createMfaAuthenticator({required enums.AuthenticatorType type}) async {
final String apiPath = '/account/mfa/authenticators/{type}'.replaceAll('{type}', type.value);
final Map<String, dynamic> apiParams = {
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders);
return models.MfaType.fromMap(res.data);
}
/// Verify Authenticator
///
/// Verify an authenticator app after adding it using the [add
/// authenticator](/docs/references/cloud/client-web/account#addAuthenticator)
/// method.
Future<models.User> updateMfaAuthenticator({required enums.AuthenticatorType type, required String otp}) async {
final String apiPath = '/account/mfa/authenticators/{type}'.replaceAll('{type}', type.value);
final Map<String, dynamic> apiParams = {
'otp': otp,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: apiPath, params: apiParams, headers: apiHeaders);
return models.User.fromMap(res.data);
}
/// Delete Authenticator
///
/// Delete an authenticator for a user by ID.
Future<models.User> deleteMfaAuthenticator({required enums.AuthenticatorType type, required String otp}) async {
final String apiPath = '/account/mfa/authenticators/{type}'.replaceAll('{type}', type.value);
final Map<String, dynamic> apiParams = {
'otp': otp,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: apiPath, params: apiParams, headers: apiHeaders);
return models.User.fromMap(res.data);
}
/// Create 2FA Challenge
///
Future<models.MfaChallenge> createChallenge({required enums.AuthenticationFactor factor}) async {
/// Begin the process of MFA verification after sign-in. Finish the flow with
/// [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge)
/// method.
Future<models.MfaChallenge> createMfaChallenge({required enums.AuthenticationFactor factor}) async {
const String apiPath = '/account/mfa/challenge';
final Map<String, dynamic> apiParams = {
@@ -205,8 +272,12 @@ class Account extends Service {
/// Create MFA Challenge (confirmation)
///
/// Complete the MFA challenge by providing the one-time password.
Future updateChallenge({required String challengeId, required String otp}) async {
/// Complete the MFA challenge by providing the one-time password. Finish the
/// process of MFA verification by providing the one-time password. To begin
/// the flow, use
/// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge)
/// method.
Future updateMfaChallenge({required String challengeId, required String otp}) async {
const String apiPath = '/account/mfa/challenge';
final Map<String, dynamic> apiParams = {
@@ -227,7 +298,7 @@ class Account extends Service {
/// List Factors
///
/// List the factors available on the account to be used as a MFA challange.
Future<models.MfaFactors> listFactors() async {
Future<models.MfaFactors> listMfaFactors() async {
const String apiPath = '/account/mfa/factors';
final Map<String, dynamic> apiParams = {
@@ -243,14 +314,37 @@ class Account extends Service {
}
/// Add Authenticator
/// Get MFA Recovery Codes
///
/// Add an authenticator app to be used as an MFA factor. Verify the
/// authenticator using the [verify
/// authenticator](/docs/references/cloud/client-web/account#verifyAuthenticator)
/// Get recovery codes that can be used as backup for MFA flow. Before getting
/// codes, they must be generated using
/// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes)
/// method. An OTP challenge is required to read recovery codes.
Future<models.MfaRecoveryCodes> getMfaRecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
final Map<String, dynamic> apiParams = {
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: apiPath, params: apiParams, headers: apiHeaders);
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Create MFA Recovery Codes
///
/// Generate recovery codes as backup for MFA flow. It's recommended to
/// generate and show then immediately after user successfully adds their
/// authehticator. Recovery codes can be used as a MFA verification type in
/// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge)
/// method.
Future<models.MfaType> addAuthenticator({required enums.AuthenticatorType type}) async {
final String apiPath = '/account/mfa/{type}'.replaceAll('{type}', type.value);
Future<models.MfaRecoveryCodes> createMfaRecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
final Map<String, dynamic> apiParams = {
};
@@ -261,49 +355,29 @@ class Account extends Service {
final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders);
return models.MfaType.fromMap(res.data);
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Verify Authenticator
/// Regenerate MFA Recovery Codes
///
/// Verify an authenticator app after adding it using the [add
/// authenticator](/docs/references/cloud/client-web/account#addAuthenticator)
/// method.
Future<models.User> verifyAuthenticator({required enums.AuthenticatorType type, required String otp}) async {
final String apiPath = '/account/mfa/{type}'.replaceAll('{type}', type.value);
/// Regenerate recovery codes that can be used as backup for MFA flow. Before
/// regenerating codes, they must be first generated using
/// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes)
/// method. An OTP challenge is required to regenreate recovery codes.
Future<models.MfaRecoveryCodes> updateMfaRecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
final Map<String, dynamic> apiParams = {
'otp': otp,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: apiPath, params: apiParams, headers: apiHeaders);
final res = await client.call(HttpMethod.patch, path: apiPath, params: apiParams, headers: apiHeaders);
return models.User.fromMap(res.data);
}
/// Delete Authenticator
///
/// Delete an authenticator for a user by ID.
Future<models.User> deleteAuthenticator({required enums.AuthenticatorType type, required String otp}) async {
final String apiPath = '/account/mfa/{type}'.replaceAll('{type}', type.value);
final Map<String, dynamic> apiParams = {
'otp': otp,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: apiPath, params: apiParams, headers: apiHeaders);
return models.User.fromMap(res.data);
return models.MfaRecoveryCodes.fromMap(res.data);
}
@@ -708,10 +782,11 @@ class Account extends Service {
}
/// Update (or renew) session
/// Update session
///
/// Extend session's expiry to increase it's lifespan. Extending a session is
/// useful when session length is short such as 5 minutes.
/// Use this endpoint to extend a session's length. Extending a session is
/// useful when session expiry is short. If the session was created using an
/// OAuth provider, this endpoint refreshes the access token from the provider.
Future<models.Session> updateSession({required String sessionId}) async {
final String apiPath = '/account/sessions/{sessionId}'.replaceAll('{sessionId}', sessionId);
+1 -1
View File
@@ -43,7 +43,7 @@ class ClientBrowser extends ClientBase with ClientMixin {
'x-sdk-name': 'Flutter',
'x-sdk-platform': 'client',
'x-sdk-language': 'flutter',
'x-sdk-version': '12.0.0-rc.6',
'x-sdk-version': '12.0.0',
'X-Appwrite-Response-Format': '1.5.0',
};
+1 -1
View File
@@ -64,7 +64,7 @@ class ClientIO extends ClientBase with ClientMixin {
'x-sdk-name': 'Flutter',
'x-sdk-platform': 'client',
'x-sdk-language': 'flutter',
'x-sdk-version': '12.0.0-rc.6',
'x-sdk-version': '12.0.0',
'X-Appwrite-Response-Format' : '1.5.0',
};
+3 -2
View File
@@ -1,9 +1,10 @@
part of appwrite.enums;
enum AuthenticationFactor {
totp(value: 'totp'),
email(value: 'email'),
phone(value: 'phone'),
email(value: 'email');
totp(value: 'totp'),
recoverycode(value: 'recoverycode');
const AuthenticationFactor({
required this.value
+1 -1
View File
@@ -34,7 +34,7 @@ enum Flag {
switzerland(value: 'ch'),
chile(value: 'cl'),
china(value: 'cn'),
cTeDIvoire(value: 'ci'),
coteDIvoire(value: 'ci'),
cameroon(value: 'cm'),
democraticRepublicOfTheCongo(value: 'cd'),
republicOfTheCongo(value: 'cg'),
+23
View File
@@ -0,0 +1,23 @@
part of appwrite.models;
/// MFA Recovery Codes
class MfaRecoveryCodes implements Model {
/// Recovery codes.
final List recoveryCodes;
MfaRecoveryCodes({
required this.recoveryCodes,
});
factory MfaRecoveryCodes.fromMap(Map<String, dynamic> map) {
return MfaRecoveryCodes(
recoveryCodes: map['recoveryCodes'] ?? [],
);
}
Map<String, dynamic> toMap() {
return {
"recoveryCodes": recoveryCodes,
};
}
}
-5
View File
@@ -2,22 +2,18 @@ part of appwrite.models;
/// MFAType
class MfaType implements Model {
/// Backup codes.
final List backups;
/// Secret token used for TOTP factor.
final String secret;
/// URI for authenticator apps.
final String uri;
MfaType({
required this.backups,
required this.secret,
required this.uri,
});
factory MfaType.fromMap(Map<String, dynamic> map) {
return MfaType(
backups: map['backups'] ?? [],
secret: map['secret'].toString(),
uri: map['uri'].toString(),
);
@@ -25,7 +21,6 @@ class MfaType implements Model {
Map<String, dynamic> toMap() {
return {
"backups": backups,
"secret": secret,
"uri": uri,
};
+5
View File
@@ -56,6 +56,8 @@ class Session implements Model {
final List factors;
/// Secret used to authenticate the user. Only included if the request was made with an API key
final String secret;
/// Most recent date in ISO 8601 format when the session successfully passed MFA challenge.
final String mfaUpdatedAt;
Session({
required this.$id,
@@ -85,6 +87,7 @@ class Session implements Model {
required this.current,
required this.factors,
required this.secret,
required this.mfaUpdatedAt,
});
factory Session.fromMap(Map<String, dynamic> map) {
@@ -116,6 +119,7 @@ class Session implements Model {
current: map['current'],
factors: map['factors'] ?? [],
secret: map['secret'].toString(),
mfaUpdatedAt: map['mfaUpdatedAt'].toString(),
);
}
@@ -148,6 +152,7 @@ class Session implements Model {
"current": current,
"factors": factors,
"secret": secret,
"mfaUpdatedAt": mfaUpdatedAt,
};
}
}
-5
View File
@@ -34,8 +34,6 @@ class User implements Model {
final bool phoneVerification;
/// Multi factor authentication status.
final bool mfa;
/// TOTP status.
final bool totp;
/// User preferences as a key-value object
final Preferences prefs;
/// A user-owned message receiver. A single user may have multiple e.g. emails, phones, and a browser. Each target is registered with a single provider.
@@ -60,7 +58,6 @@ class User implements Model {
required this.emailVerification,
required this.phoneVerification,
required this.mfa,
required this.totp,
required this.prefs,
required this.targets,
required this.accessedAt,
@@ -84,7 +81,6 @@ class User implements Model {
emailVerification: map['emailVerification'],
phoneVerification: map['phoneVerification'],
mfa: map['mfa'],
totp: map['totp'],
prefs: Preferences.fromMap(map['prefs']),
targets: List<Target>.from(map['targets'].map((p) => Target.fromMap(p))),
accessedAt: map['accessedAt'].toString(),
@@ -109,7 +105,6 @@ class User implements Model {
"emailVerification": emailVerification,
"phoneVerification": phoneVerification,
"mfa": mfa,
"totp": totp,
"prefs": prefs.toMap(),
"targets": targets.map((p) => p.toMap()).toList(),
"accessedAt": accessedAt,
+1 -1
View File
@@ -1,5 +1,5 @@
name: appwrite
version: 12.0.0-rc.6
version: 12.0.0
description: Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API
homepage: https://appwrite.io
repository: https://github.com/appwrite/sdk-for-flutter
+130 -87
View File
@@ -69,7 +69,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -101,7 +100,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -136,7 +134,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -233,7 +230,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -251,7 +247,91 @@ void main() {
});
test('test method createChallenge()', () async {
test('test method createMfaAuthenticator()', () async {
final Map<String, dynamic> data = {
'secret': '1',
'uri': '1',};
when(client.call(
HttpMethod.post,
)).thenAnswer((_) async => Response(data: data));
final response = await account.createMfaAuthenticator(
type: 'totp',
);
expect(response, isA<models.MfaType>());
});
test('test method updateMfaAuthenticator()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'John Doe',
'registration': '2020-10-15T06:38:00.000+00:00',
'status': true,
'labels': [],
'passwordUpdate': '2020-10-15T06:38:00.000+00:00',
'email': 'john@appwrite.io',
'phone': '+4930901820',
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
HttpMethod.put,
)).thenAnswer((_) async => Response(data: data));
final response = await account.updateMfaAuthenticator(
type: 'totp',
otp: '<OTP>',
);
expect(response, isA<models.User>());
});
test('test method deleteMfaAuthenticator()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'John Doe',
'registration': '2020-10-15T06:38:00.000+00:00',
'status': true,
'labels': [],
'passwordUpdate': '2020-10-15T06:38:00.000+00:00',
'email': 'john@appwrite.io',
'phone': '+4930901820',
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
HttpMethod.delete,
)).thenAnswer((_) async => Response(data: data));
final response = await account.deleteMfaAuthenticator(
type: 'totp',
otp: '<OTP>',
);
expect(response, isA<models.User>());
});
test('test method createMfaChallenge()', () async {
final Map<String, dynamic> data = {
'\$id': 'bb8ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -264,14 +344,14 @@ void main() {
)).thenAnswer((_) async => Response(data: data));
final response = await account.createChallenge(
factor: 'totp',
final response = await account.createMfaChallenge(
factor: 'email',
);
expect(response, isA<models.MfaChallenge>());
});
test('test method updateChallenge()', () async {
test('test method updateMfaChallenge()', () async {
final data = '';
when(client.call(
@@ -279,13 +359,13 @@ void main() {
)).thenAnswer((_) async => Response(data: data));
final response = await account.updateChallenge(
final response = await account.updateMfaChallenge(
challengeId: '<CHALLENGE_ID>',
otp: '<OTP>',
);
});
test('test method listFactors()', () async {
test('test method listMfaFactors()', () async {
final Map<String, dynamic> data = {
'totp': true,
'phone': true,
@@ -297,17 +377,31 @@ void main() {
)).thenAnswer((_) async => Response(data: data));
final response = await account.listFactors(
final response = await account.listMfaFactors(
);
expect(response, isA<models.MfaFactors>());
});
test('test method addAuthenticator()', () async {
test('test method getMfaRecoveryCodes()', () async {
final Map<String, dynamic> data = {
'backups': [],
'secret': '1',
'uri': '1',};
'recoveryCodes': [],};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await account.getMfaRecoveryCodes(
);
expect(response, isA<models.MfaRecoveryCodes>());
});
test('test method createMfaRecoveryCodes()', () async {
final Map<String, dynamic> data = {
'recoveryCodes': [],};
when(client.call(
@@ -315,78 +409,25 @@ void main() {
)).thenAnswer((_) async => Response(data: data));
final response = await account.addAuthenticator(
type: 'totp',
final response = await account.createMfaRecoveryCodes(
);
expect(response, isA<models.MfaType>());
expect(response, isA<models.MfaRecoveryCodes>());
});
test('test method verifyAuthenticator()', () async {
test('test method updateMfaRecoveryCodes()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'John Doe',
'registration': '2020-10-15T06:38:00.000+00:00',
'status': true,
'labels': [],
'passwordUpdate': '2020-10-15T06:38:00.000+00:00',
'email': 'john@appwrite.io',
'phone': '+4930901820',
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
'recoveryCodes': [],};
when(client.call(
HttpMethod.put,
HttpMethod.patch,
)).thenAnswer((_) async => Response(data: data));
final response = await account.verifyAuthenticator(
type: 'totp',
otp: '<OTP>',
final response = await account.updateMfaRecoveryCodes(
);
expect(response, isA<models.User>());
});
test('test method deleteAuthenticator()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'John Doe',
'registration': '2020-10-15T06:38:00.000+00:00',
'status': true,
'labels': [],
'passwordUpdate': '2020-10-15T06:38:00.000+00:00',
'email': 'john@appwrite.io',
'phone': '+4930901820',
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
HttpMethod.delete,
)).thenAnswer((_) async => Response(data: data));
final response = await account.deleteAuthenticator(
type: 'totp',
otp: '<OTP>',
);
expect(response, isA<models.User>());
expect(response, isA<models.MfaRecoveryCodes>());
});
@@ -405,7 +446,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -438,7 +478,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -471,7 +510,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -520,7 +558,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -642,7 +679,8 @@ void main() {
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',};
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
@@ -684,7 +722,8 @@ void main() {
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',};
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
@@ -728,7 +767,8 @@ void main() {
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',};
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
@@ -784,7 +824,8 @@ void main() {
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',};
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
@@ -828,7 +869,8 @@ void main() {
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',};
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
@@ -872,7 +914,8 @@ void main() {
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',};
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
@@ -915,7 +958,8 @@ void main() {
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',};
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
@@ -958,7 +1002,6 @@ void main() {
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'totp': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
@@ -0,0 +1,18 @@
import 'package:appwrite/models.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('MfaRecoveryCodes', () {
test('model', () {
final model = MfaRecoveryCodes(
recoveryCodes: [],
);
final map = model.toMap();
final result = MfaRecoveryCodes.fromMap(map);
expect(result.recoveryCodes, []);
});
});
}
-2
View File
@@ -6,7 +6,6 @@ void main() {
test('model', () {
final model = MfaType(
backups: [],
secret: '1',
uri: '1',
);
@@ -14,7 +13,6 @@ void main() {
final map = model.toMap();
final result = MfaType.fromMap(map);
expect(result.backups, []);
expect(result.secret, '1');
expect(result.uri, '1');
});
+2
View File
@@ -33,6 +33,7 @@ void main() {
current: true,
factors: [],
secret: '5e5bb8c16897e',
mfaUpdatedAt: '2020-10-15T06:38:00.000+00:00',
);
final map = model.toMap();
@@ -65,6 +66,7 @@ void main() {
expect(result.current, true);
expect(result.factors, []);
expect(result.secret, '5e5bb8c16897e');
expect(result.mfaUpdatedAt, '2020-10-15T06:38:00.000+00:00');
});
});
}
-2
View File
@@ -19,7 +19,6 @@ void main() {
emailVerification: true,
phoneVerification: true,
mfa: true,
totp: true,
prefs: Preferences(data: {}),
targets: [],
accessedAt: '2020-10-15T06:38:00.000+00:00',
@@ -41,7 +40,6 @@ void main() {
expect(result.emailVerification, true);
expect(result.phoneVerification, true);
expect(result.mfa, true);
expect(result.totp, true);
expect(result.prefs.data, {"data": {}});
expect(result.targets, []);
expect(result.accessedAt, '2020-10-15T06:38:00.000+00:00');