mirror of
https://github.com/appwrite/sdk-for-flutter.git
synced 2026-04-07 19:27:41 +00:00
Appwite 1.5 support
This commit is contained in:
@@ -13,7 +13,7 @@ Appwrite is an open-source backend as a service server that abstract and simplif
|
||||
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
## 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:
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@ Client client = Client()
|
||||
|
||||
Account account = Account(client);
|
||||
|
||||
MfaType result = await account.addAuthenticator(
|
||||
MfaType result = await account.createMfaAuthenticator(
|
||||
type: AuthenticatorType.totp,
|
||||
);
|
||||
+2
-2
@@ -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();
|
||||
+1
-1
@@ -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();
|
||||
+1
-1
@@ -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>',
|
||||
);
|
||||
+1
-1
@@ -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
@@ -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';
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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',
|
||||
};
|
||||
|
||||
|
||||
@@ -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',
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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, []);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user