diff --git a/README.md b/README.md index 1465cce..fc105c9 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite) [![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord) -**This SDK is compatible with Appwrite server version 1.4.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-flutter/releases).** +**This SDK is compatible with Appwrite server version 1.5.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-flutter/releases).** Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs) @@ -21,7 +21,7 @@ Add this to your package's `pubspec.yaml` file: ```yml dependencies: - appwrite: ^11.0.1 + appwrite: ^12.0.0-rc.2 ``` You can install packages from the command line: diff --git a/docs/examples/account/update-phone-session.md b/docs/examples/account/add-authenticator.md similarity index 80% rename from docs/examples/account/update-phone-session.md rename to docs/examples/account/add-authenticator.md index 1f97926..0c6f74f 100644 --- a/docs/examples/account/update-phone-session.md +++ b/docs/examples/account/add-authenticator.md @@ -8,9 +8,8 @@ void main() { // Init SDK .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint .setProject('5df5acd0d48c2') // Your project ID ; - Future result = account.updatePhoneSession( - userId: '[USER_ID]', - secret: '[SECRET]', + Future result = account.addAuthenticator( + type: .totp.value, ); result diff --git a/docs/examples/account/create-email-password-session.md b/docs/examples/account/create-email-password-session.md new file mode 100644 index 0000000..fae7af8 --- /dev/null +++ b/docs/examples/account/create-email-password-session.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.createEmailPasswordSession( + email:'email@example.com' , + password:'password' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/create-email-session.md b/docs/examples/account/create-email-token.md similarity index 79% rename from docs/examples/account/create-email-session.md rename to docs/examples/account/create-email-token.md index 52b6b91..fdaf5e2 100644 --- a/docs/examples/account/create-email-session.md +++ b/docs/examples/account/create-email-token.md @@ -8,9 +8,9 @@ void main() { // Init SDK .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint .setProject('5df5acd0d48c2') // Your project ID ; - Future result = account.createEmailSession( - email: 'email@example.com', - password: 'password', + Future result = account.createEmailToken( + userId:'[USER_ID]' , + email:'email@example.com' , ); result diff --git a/docs/examples/account/create-magic-u-r-l-session.md b/docs/examples/account/create-magic-u-r-l-token.md similarity index 78% rename from docs/examples/account/create-magic-u-r-l-session.md rename to docs/examples/account/create-magic-u-r-l-token.md index d1b89bf..81fea12 100644 --- a/docs/examples/account/create-magic-u-r-l-session.md +++ b/docs/examples/account/create-magic-u-r-l-token.md @@ -8,9 +8,9 @@ void main() { // Init SDK .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint .setProject('5df5acd0d48c2') // Your project ID ; - Future result = account.createMagicURLSession( - userId: '[USER_ID]', - email: 'email@example.com', + Future result = account.createMagicURLToken( + userId:'[USER_ID]' , + email:'email@example.com' , ); result diff --git a/docs/examples/account/create-o-auth2session.md b/docs/examples/account/create-o-auth2session.md index e985a92..4ef8054 100644 --- a/docs/examples/account/create-o-auth2session.md +++ b/docs/examples/account/create-o-auth2session.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.createOAuth2Session( - provider: 'amazon', + provider: OAuthProvider.amazon.value, ); result diff --git a/docs/examples/account/create-phone-session.md b/docs/examples/account/create-phone-token.md similarity index 80% rename from docs/examples/account/create-phone-session.md rename to docs/examples/account/create-phone-token.md index fcb705c..9ed27c5 100644 --- a/docs/examples/account/create-phone-session.md +++ b/docs/examples/account/create-phone-token.md @@ -8,9 +8,9 @@ void main() { // Init SDK .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint .setProject('5df5acd0d48c2') // Your project ID ; - Future result = account.createPhoneSession( - userId: '[USER_ID]', - phone: '+12065550100', + Future result = account.createPhoneToken( + userId:'[USER_ID]' , + phone:'+12065550100' , ); result diff --git a/docs/examples/account/create-push-target.md b/docs/examples/account/create-push-target.md new file mode 100644 index 0000000..a130a8e --- /dev/null +++ b/docs/examples/account/create-push-target.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.createPushTarget( + targetId:'[TARGET_ID]' , + identifier:'[IDENTIFIER]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/create-recovery.md b/docs/examples/account/create-recovery.md index 361a9f0..ff00ec0 100644 --- a/docs/examples/account/create-recovery.md +++ b/docs/examples/account/create-recovery.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.createRecovery( - email: 'email@example.com', - url: 'https://example.com', + email:'email@example.com' , + url:'https://example.com' , ); result diff --git a/docs/examples/account/create-session.md b/docs/examples/account/create-session.md new file mode 100644 index 0000000..78fbffb --- /dev/null +++ b/docs/examples/account/create-session.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.createSession( + userId:'[USER_ID]' , + secret:'[SECRET]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/create-verification.md b/docs/examples/account/create-verification.md index d66c3b1..36ff0af 100644 --- a/docs/examples/account/create-verification.md +++ b/docs/examples/account/create-verification.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.createVerification( - url: 'https://example.com', + url:'https://example.com' , ); result diff --git a/docs/examples/account/create.md b/docs/examples/account/create.md index 1ff2ae9..21b9c85 100644 --- a/docs/examples/account/create.md +++ b/docs/examples/account/create.md @@ -9,9 +9,9 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.create( - userId: '[USER_ID]', - email: 'email@example.com', - password: '', + userId:'[USER_ID]' , + email:'email@example.com' , + password:'' , ); result diff --git a/docs/examples/account/create2f-a-challenge.md b/docs/examples/account/create2f-a-challenge.md new file mode 100644 index 0000000..8a5a056 --- /dev/null +++ b/docs/examples/account/create2f-a-challenge.md @@ -0,0 +1,21 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.create2FAChallenge( + factor: .totp.value, + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/delete-authenticator.md b/docs/examples/account/delete-authenticator.md new file mode 100644 index 0000000..6203273 --- /dev/null +++ b/docs/examples/account/delete-authenticator.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.deleteAuthenticator( + type: .totp.value, + otp:'[OTP]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/delete-identity.md b/docs/examples/account/delete-identity.md index c5ea2b3..212bbdf 100644 --- a/docs/examples/account/delete-identity.md +++ b/docs/examples/account/delete-identity.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.deleteIdentity( - identityId: '[IDENTITY_ID]', + identityId:'[IDENTITY_ID]' , ); result diff --git a/docs/examples/account/delete-push-target.md b/docs/examples/account/delete-push-target.md new file mode 100644 index 0000000..3a12f96 --- /dev/null +++ b/docs/examples/account/delete-push-target.md @@ -0,0 +1,21 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.deletePushTarget( + targetId:'[TARGET_ID]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/delete-session.md b/docs/examples/account/delete-session.md index 9146561..05afb9d 100644 --- a/docs/examples/account/delete-session.md +++ b/docs/examples/account/delete-session.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.deleteSession( - sessionId: '[SESSION_ID]', + sessionId:'[SESSION_ID]' , ); result diff --git a/docs/examples/account/get-session.md b/docs/examples/account/get-session.md index 9e0f66c..db2b2ad 100644 --- a/docs/examples/account/get-session.md +++ b/docs/examples/account/get-session.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.getSession( - sessionId: '[SESSION_ID]', + sessionId:'[SESSION_ID]' , ); result diff --git a/docs/examples/account/list-factors.md b/docs/examples/account/list-factors.md new file mode 100644 index 0000000..5448f52 --- /dev/null +++ b/docs/examples/account/list-factors.md @@ -0,0 +1,19 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.listFactors(); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/update-challenge.md b/docs/examples/account/update-challenge.md new file mode 100644 index 0000000..be073ad --- /dev/null +++ b/docs/examples/account/update-challenge.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.updateChallenge( + challengeId:'[CHALLENGE_ID]' , + otp:'[OTP]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/update-email.md b/docs/examples/account/update-email.md index 1fb9a3f..8ecb488 100644 --- a/docs/examples/account/update-email.md +++ b/docs/examples/account/update-email.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updateEmail( - email: 'email@example.com', - password: 'password', + email:'email@example.com' , + password:'password' , ); result diff --git a/docs/examples/account/update-m-f-a.md b/docs/examples/account/update-m-f-a.md new file mode 100644 index 0000000..fdd4166 --- /dev/null +++ b/docs/examples/account/update-m-f-a.md @@ -0,0 +1,21 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.updateMFA( + mfa:false , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/update-magic-u-r-l-session.md b/docs/examples/account/update-magic-u-r-l-session.md index 3c7ef8f..4395765 100644 --- a/docs/examples/account/update-magic-u-r-l-session.md +++ b/docs/examples/account/update-magic-u-r-l-session.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updateMagicURLSession( - userId: '[USER_ID]', - secret: '[SECRET]', + userId:'[USER_ID]' , + secret:'[SECRET]' , ); result diff --git a/docs/examples/account/update-name.md b/docs/examples/account/update-name.md index ae5d623..074d8f1 100644 --- a/docs/examples/account/update-name.md +++ b/docs/examples/account/update-name.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updateName( - name: '[NAME]', + name:'[NAME]' , ); result diff --git a/docs/examples/account/update-password.md b/docs/examples/account/update-password.md index b5e86de..89387ab 100644 --- a/docs/examples/account/update-password.md +++ b/docs/examples/account/update-password.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updatePassword( - password: '', + password:'' , ); result diff --git a/docs/examples/account/update-phone-verification.md b/docs/examples/account/update-phone-verification.md index 86d9b0f..6ac4280 100644 --- a/docs/examples/account/update-phone-verification.md +++ b/docs/examples/account/update-phone-verification.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updatePhoneVerification( - userId: '[USER_ID]', - secret: '[SECRET]', + userId:'[USER_ID]' , + secret:'[SECRET]' , ); result diff --git a/docs/examples/account/update-phone.md b/docs/examples/account/update-phone.md index edfe478..25a70ba 100644 --- a/docs/examples/account/update-phone.md +++ b/docs/examples/account/update-phone.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updatePhone( - phone: '+12065550100', - password: 'password', + phone:'+12065550100' , + password:'password' , ); result diff --git a/docs/examples/account/update-prefs.md b/docs/examples/account/update-prefs.md index 9769708..df8d031 100644 --- a/docs/examples/account/update-prefs.md +++ b/docs/examples/account/update-prefs.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updatePrefs( - prefs: {}, + prefs:{} , ); result diff --git a/docs/examples/account/update-push-target.md b/docs/examples/account/update-push-target.md new file mode 100644 index 0000000..2109e85 --- /dev/null +++ b/docs/examples/account/update-push-target.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.updatePushTarget( + targetId:'[TARGET_ID]' , + identifier:'[IDENTIFIER]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/account/update-recovery.md b/docs/examples/account/update-recovery.md index f499b18..5b45901 100644 --- a/docs/examples/account/update-recovery.md +++ b/docs/examples/account/update-recovery.md @@ -9,10 +9,9 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updateRecovery( - userId: '[USER_ID]', - secret: '[SECRET]', - password: 'password', - passwordAgain: 'password', + userId:'[USER_ID]' , + secret:'[SECRET]' , + password:'' , ); result diff --git a/docs/examples/account/update-session.md b/docs/examples/account/update-session.md index fb1afcc..efb5f94 100644 --- a/docs/examples/account/update-session.md +++ b/docs/examples/account/update-session.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updateSession( - sessionId: '[SESSION_ID]', + sessionId:'[SESSION_ID]' , ); result diff --git a/docs/examples/account/update-verification.md b/docs/examples/account/update-verification.md index fba8ed6..544624b 100644 --- a/docs/examples/account/update-verification.md +++ b/docs/examples/account/update-verification.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = account.updateVerification( - userId: '[USER_ID]', - secret: '[SECRET]', + userId:'[USER_ID]' , + secret:'[SECRET]' , ); result diff --git a/docs/examples/account/verify-authenticator.md b/docs/examples/account/verify-authenticator.md new file mode 100644 index 0000000..c1596bd --- /dev/null +++ b/docs/examples/account/verify-authenticator.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Account account = Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = account.verifyAuthenticator( + type: .totp.value, + otp:'[OTP]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/avatars/get-browser.md b/docs/examples/avatars/get-browser.md index 70af566..c5a740e 100644 --- a/docs/examples/avatars/get-browser.md +++ b/docs/examples/avatars/get-browser.md @@ -10,7 +10,7 @@ void main() { // Init SDK ; // downloading file Future result = avatars.getBrowser( - code: 'aa', + code: Browser.avantBrowser.value, ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -22,7 +22,7 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: avatars.getBrowser( - code: 'aa', + code: Browser.avantBrowser.value, ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/avatars/get-credit-card.md b/docs/examples/avatars/get-credit-card.md index 6a29dc8..46df803 100644 --- a/docs/examples/avatars/get-credit-card.md +++ b/docs/examples/avatars/get-credit-card.md @@ -10,7 +10,7 @@ void main() { // Init SDK ; // downloading file Future result = avatars.getCreditCard( - code: 'amex', + code: CreditCard.americanExpress.value, ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -22,7 +22,7 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: avatars.getCreditCard( - code: 'amex', + code: CreditCard.americanExpress.value, ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/avatars/get-favicon.md b/docs/examples/avatars/get-favicon.md index 2da0f2e..f298317 100644 --- a/docs/examples/avatars/get-favicon.md +++ b/docs/examples/avatars/get-favicon.md @@ -10,7 +10,7 @@ void main() { // Init SDK ; // downloading file Future result = avatars.getFavicon( - url: 'https://example.com', + url:'https://example.com' , ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -22,7 +22,7 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: avatars.getFavicon( - url: 'https://example.com', + url:'https://example.com' , ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/avatars/get-flag.md b/docs/examples/avatars/get-flag.md index 1336788..a23887b 100644 --- a/docs/examples/avatars/get-flag.md +++ b/docs/examples/avatars/get-flag.md @@ -10,7 +10,7 @@ void main() { // Init SDK ; // downloading file Future result = avatars.getFlag( - code: 'af', + code: Flag.afghanistan.value, ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -22,7 +22,7 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: avatars.getFlag( - code: 'af', + code: Flag.afghanistan.value, ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/avatars/get-image.md b/docs/examples/avatars/get-image.md index debbf1e..52ba233 100644 --- a/docs/examples/avatars/get-image.md +++ b/docs/examples/avatars/get-image.md @@ -10,7 +10,7 @@ void main() { // Init SDK ; // downloading file Future result = avatars.getImage( - url: 'https://example.com', + url:'https://example.com' , ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -22,7 +22,7 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: avatars.getImage( - url: 'https://example.com', + url:'https://example.com' , ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/avatars/get-q-r.md b/docs/examples/avatars/get-q-r.md index 8df7293..c148c4d 100644 --- a/docs/examples/avatars/get-q-r.md +++ b/docs/examples/avatars/get-q-r.md @@ -10,7 +10,7 @@ void main() { // Init SDK ; // downloading file Future result = avatars.getQR( - text: '[TEXT]', + text:'[TEXT]' , ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -22,7 +22,7 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: avatars.getQR( - text: '[TEXT]', + text:'[TEXT]' , ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/databases/create-document.md b/docs/examples/databases/create-document.md index 6a03173..f4d765c 100644 --- a/docs/examples/databases/create-document.md +++ b/docs/examples/databases/create-document.md @@ -9,10 +9,10 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = databases.createDocument( - databaseId: '[DATABASE_ID]', - collectionId: '[COLLECTION_ID]', - documentId: '[DOCUMENT_ID]', - data: {}, + databaseId:'[DATABASE_ID]' , + collectionId:'[COLLECTION_ID]' , + documentId:'[DOCUMENT_ID]' , + data:{} , ); result diff --git a/docs/examples/databases/delete-document.md b/docs/examples/databases/delete-document.md index a377b02..edf2d99 100644 --- a/docs/examples/databases/delete-document.md +++ b/docs/examples/databases/delete-document.md @@ -9,9 +9,9 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = databases.deleteDocument( - databaseId: '[DATABASE_ID]', - collectionId: '[COLLECTION_ID]', - documentId: '[DOCUMENT_ID]', + databaseId:'[DATABASE_ID]' , + collectionId:'[COLLECTION_ID]' , + documentId:'[DOCUMENT_ID]' , ); result diff --git a/docs/examples/databases/get-document.md b/docs/examples/databases/get-document.md index b2cf89a..77b484e 100644 --- a/docs/examples/databases/get-document.md +++ b/docs/examples/databases/get-document.md @@ -9,9 +9,9 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = databases.getDocument( - databaseId: '[DATABASE_ID]', - collectionId: '[COLLECTION_ID]', - documentId: '[DOCUMENT_ID]', + databaseId:'[DATABASE_ID]' , + collectionId:'[COLLECTION_ID]' , + documentId:'[DOCUMENT_ID]' , ); result diff --git a/docs/examples/databases/list-documents.md b/docs/examples/databases/list-documents.md index 4cd69e3..88d3a1e 100644 --- a/docs/examples/databases/list-documents.md +++ b/docs/examples/databases/list-documents.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = databases.listDocuments( - databaseId: '[DATABASE_ID]', - collectionId: '[COLLECTION_ID]', + databaseId:'[DATABASE_ID]' , + collectionId:'[COLLECTION_ID]' , ); result diff --git a/docs/examples/databases/update-document.md b/docs/examples/databases/update-document.md index 595099b..81dcea3 100644 --- a/docs/examples/databases/update-document.md +++ b/docs/examples/databases/update-document.md @@ -9,9 +9,9 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = databases.updateDocument( - databaseId: '[DATABASE_ID]', - collectionId: '[COLLECTION_ID]', - documentId: '[DOCUMENT_ID]', + databaseId:'[DATABASE_ID]' , + collectionId:'[COLLECTION_ID]' , + documentId:'[DOCUMENT_ID]' , ); result diff --git a/docs/examples/functions/create-execution.md b/docs/examples/functions/create-execution.md index b188c32..98f80c2 100644 --- a/docs/examples/functions/create-execution.md +++ b/docs/examples/functions/create-execution.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = functions.createExecution( - functionId: '[FUNCTION_ID]', + functionId:'[FUNCTION_ID]' , ); result diff --git a/docs/examples/functions/get-execution.md b/docs/examples/functions/get-execution.md index f30b4b4..4673430 100644 --- a/docs/examples/functions/get-execution.md +++ b/docs/examples/functions/get-execution.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = functions.getExecution( - functionId: '[FUNCTION_ID]', - executionId: '[EXECUTION_ID]', + functionId:'[FUNCTION_ID]' , + executionId:'[EXECUTION_ID]' , ); result diff --git a/docs/examples/functions/list-executions.md b/docs/examples/functions/list-executions.md index 1840f50..b742c85 100644 --- a/docs/examples/functions/list-executions.md +++ b/docs/examples/functions/list-executions.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = functions.listExecutions( - functionId: '[FUNCTION_ID]', + functionId:'[FUNCTION_ID]' , ); result diff --git a/docs/examples/graphql/mutation.md b/docs/examples/graphql/mutation.md index c0bffce..6d201cb 100644 --- a/docs/examples/graphql/mutation.md +++ b/docs/examples/graphql/mutation.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = graphql.mutation( - query: {}, + query:{} , ); result diff --git a/docs/examples/graphql/query.md b/docs/examples/graphql/query.md index 455cb0b..18adfaa 100644 --- a/docs/examples/graphql/query.md +++ b/docs/examples/graphql/query.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = graphql.query( - query: {}, + query:{} , ); result diff --git a/docs/examples/messaging/create-subscriber.md b/docs/examples/messaging/create-subscriber.md new file mode 100644 index 0000000..062ccf9 --- /dev/null +++ b/docs/examples/messaging/create-subscriber.md @@ -0,0 +1,23 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Messaging messaging = Messaging(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = messaging.createSubscriber( + topicId:'[TOPIC_ID]' , + subscriberId:'[SUBSCRIBER_ID]' , + targetId:'[TARGET_ID]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/messaging/delete-subscriber.md b/docs/examples/messaging/delete-subscriber.md new file mode 100644 index 0000000..63e9883 --- /dev/null +++ b/docs/examples/messaging/delete-subscriber.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +void main() { // Init SDK + Client client = Client(); + Messaging messaging = Messaging(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('5df5acd0d48c2') // Your project ID + ; + Future result = messaging.deleteSubscriber( + topicId:'[TOPIC_ID]' , + subscriberId:'[SUBSCRIBER_ID]' , + ); + + result + .then((response) { + print(response); + }).catchError((error) { + print(error.response); + }); +} diff --git a/docs/examples/storage/create-file.md b/docs/examples/storage/create-file.md index 0f5e44f..cbb58ba 100644 --- a/docs/examples/storage/create-file.md +++ b/docs/examples/storage/create-file.md @@ -10,9 +10,9 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = storage.createFile( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', - file: InputFile(path: './path-to-files/image.jpg', filename: 'image.jpg'), + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , + file:InputFile(path: './path-to-files/image.jpg', filename: 'image.jpg') , ); result diff --git a/docs/examples/storage/delete-file.md b/docs/examples/storage/delete-file.md index 230b73a..9d84188 100644 --- a/docs/examples/storage/delete-file.md +++ b/docs/examples/storage/delete-file.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = storage.deleteFile( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ); result diff --git a/docs/examples/storage/get-file-download.md b/docs/examples/storage/get-file-download.md index 883b7d6..97190cd 100644 --- a/docs/examples/storage/get-file-download.md +++ b/docs/examples/storage/get-file-download.md @@ -10,8 +10,8 @@ void main() { // Init SDK ; // downloading file Future result = storage.getFileDownload( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -23,8 +23,8 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: storage.getFileDownload( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/storage/get-file-preview.md b/docs/examples/storage/get-file-preview.md index f42138b..90c4605 100644 --- a/docs/examples/storage/get-file-preview.md +++ b/docs/examples/storage/get-file-preview.md @@ -10,8 +10,8 @@ void main() { // Init SDK ; // downloading file Future result = storage.getFilePreview( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -23,8 +23,8 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: storage.getFilePreview( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/storage/get-file-view.md b/docs/examples/storage/get-file-view.md index 4f7c4d9..fb69ffe 100644 --- a/docs/examples/storage/get-file-view.md +++ b/docs/examples/storage/get-file-view.md @@ -10,8 +10,8 @@ void main() { // Init SDK ; // downloading file Future result = storage.getFileView( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ).then((bytes) { final file = File('path_to_file/filename.ext'); file.writeAsBytesSync(bytes) @@ -23,8 +23,8 @@ void main() { // Init SDK //displaying image preview FutureBuilder( future: storage.getFileView( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ), //works for both public file and private file, for private files you need to be logged in builder: (context, snapshot) { return snapshot.hasData && snapshot.data != null diff --git a/docs/examples/storage/get-file.md b/docs/examples/storage/get-file.md index 681aca4..d658134 100644 --- a/docs/examples/storage/get-file.md +++ b/docs/examples/storage/get-file.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = storage.getFile( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ); result diff --git a/docs/examples/storage/list-files.md b/docs/examples/storage/list-files.md index e574f7b..04befaa 100644 --- a/docs/examples/storage/list-files.md +++ b/docs/examples/storage/list-files.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = storage.listFiles( - bucketId: '[BUCKET_ID]', + bucketId:'[BUCKET_ID]' , ); result diff --git a/docs/examples/storage/update-file.md b/docs/examples/storage/update-file.md index 1170f05..f9dce12 100644 --- a/docs/examples/storage/update-file.md +++ b/docs/examples/storage/update-file.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = storage.updateFile( - bucketId: '[BUCKET_ID]', - fileId: '[FILE_ID]', + bucketId:'[BUCKET_ID]' , + fileId:'[FILE_ID]' , ); result diff --git a/docs/examples/teams/create-membership.md b/docs/examples/teams/create-membership.md index 9944626..8fddcca 100644 --- a/docs/examples/teams/create-membership.md +++ b/docs/examples/teams/create-membership.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.createMembership( - teamId: '[TEAM_ID]', - roles: [], + teamId:'[TEAM_ID]' , + roles:[] , ); result diff --git a/docs/examples/teams/create.md b/docs/examples/teams/create.md index bd62ce3..e804e25 100644 --- a/docs/examples/teams/create.md +++ b/docs/examples/teams/create.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.create( - teamId: '[TEAM_ID]', - name: '[NAME]', + teamId:'[TEAM_ID]' , + name:'[NAME]' , ); result diff --git a/docs/examples/teams/delete-membership.md b/docs/examples/teams/delete-membership.md index 0febe42..6bf6044 100644 --- a/docs/examples/teams/delete-membership.md +++ b/docs/examples/teams/delete-membership.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.deleteMembership( - teamId: '[TEAM_ID]', - membershipId: '[MEMBERSHIP_ID]', + teamId:'[TEAM_ID]' , + membershipId:'[MEMBERSHIP_ID]' , ); result diff --git a/docs/examples/teams/delete.md b/docs/examples/teams/delete.md index b45d971..3faa80a 100644 --- a/docs/examples/teams/delete.md +++ b/docs/examples/teams/delete.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.delete( - teamId: '[TEAM_ID]', + teamId:'[TEAM_ID]' , ); result diff --git a/docs/examples/teams/get-membership.md b/docs/examples/teams/get-membership.md index 28d95a2..46bc0d7 100644 --- a/docs/examples/teams/get-membership.md +++ b/docs/examples/teams/get-membership.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.getMembership( - teamId: '[TEAM_ID]', - membershipId: '[MEMBERSHIP_ID]', + teamId:'[TEAM_ID]' , + membershipId:'[MEMBERSHIP_ID]' , ); result diff --git a/docs/examples/teams/get-prefs.md b/docs/examples/teams/get-prefs.md index e9ae94e..7d074b6 100644 --- a/docs/examples/teams/get-prefs.md +++ b/docs/examples/teams/get-prefs.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.getPrefs( - teamId: '[TEAM_ID]', + teamId:'[TEAM_ID]' , ); result diff --git a/docs/examples/teams/get.md b/docs/examples/teams/get.md index 0ec7027..870bb34 100644 --- a/docs/examples/teams/get.md +++ b/docs/examples/teams/get.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.get( - teamId: '[TEAM_ID]', + teamId:'[TEAM_ID]' , ); result diff --git a/docs/examples/teams/list-memberships.md b/docs/examples/teams/list-memberships.md index cbbc525..1977e37 100644 --- a/docs/examples/teams/list-memberships.md +++ b/docs/examples/teams/list-memberships.md @@ -9,7 +9,7 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.listMemberships( - teamId: '[TEAM_ID]', + teamId:'[TEAM_ID]' , ); result diff --git a/docs/examples/teams/update-membership-status.md b/docs/examples/teams/update-membership-status.md index ed31f54..a7a3762 100644 --- a/docs/examples/teams/update-membership-status.md +++ b/docs/examples/teams/update-membership-status.md @@ -9,10 +9,10 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.updateMembershipStatus( - teamId: '[TEAM_ID]', - membershipId: '[MEMBERSHIP_ID]', - userId: '[USER_ID]', - secret: '[SECRET]', + teamId:'[TEAM_ID]' , + membershipId:'[MEMBERSHIP_ID]' , + userId:'[USER_ID]' , + secret:'[SECRET]' , ); result diff --git a/docs/examples/teams/update-membership.md b/docs/examples/teams/update-membership.md index 669568b..b3f34e1 100644 --- a/docs/examples/teams/update-membership.md +++ b/docs/examples/teams/update-membership.md @@ -9,9 +9,9 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.updateMembership( - teamId: '[TEAM_ID]', - membershipId: '[MEMBERSHIP_ID]', - roles: [], + teamId:'[TEAM_ID]' , + membershipId:'[MEMBERSHIP_ID]' , + roles:[] , ); result diff --git a/docs/examples/teams/update-name.md b/docs/examples/teams/update-name.md index 5c794bd..be9aed0 100644 --- a/docs/examples/teams/update-name.md +++ b/docs/examples/teams/update-name.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.updateName( - teamId: '[TEAM_ID]', - name: '[NAME]', + teamId:'[TEAM_ID]' , + name:'[NAME]' , ); result diff --git a/docs/examples/teams/update-prefs.md b/docs/examples/teams/update-prefs.md index c29cbb9..712bfec 100644 --- a/docs/examples/teams/update-prefs.md +++ b/docs/examples/teams/update-prefs.md @@ -9,8 +9,8 @@ void main() { // Init SDK .setProject('5df5acd0d48c2') // Your project ID ; Future result = teams.updatePrefs( - teamId: '[TEAM_ID]', - prefs: {}, + teamId:'[TEAM_ID]' , + prefs:{} , ); result diff --git a/lib/appwrite.dart b/lib/appwrite.dart index e8d4a27..7f1bb2f 100644 --- a/lib/appwrite.dart +++ b/lib/appwrite.dart @@ -7,10 +7,13 @@ library appwrite; import 'dart:async'; import 'dart:typed_data'; +import 'dart:convert'; + import 'src/enums.dart'; import 'src/service.dart'; import 'src/input_file.dart'; import 'models.dart' as models; +import 'enums.dart' as enums; import 'src/upload_progress.dart'; export 'src/response.dart'; @@ -32,5 +35,6 @@ part 'services/databases.dart'; part 'services/functions.dart'; part 'services/graphql.dart'; part 'services/locale.dart'; +part 'services/messaging.dart'; part 'services/storage.dart'; part 'services/teams.dart'; diff --git a/lib/enums.dart b/lib/enums.dart new file mode 100644 index 0000000..21e2dba --- /dev/null +++ b/lib/enums.dart @@ -0,0 +1,12 @@ +/// Appwrite Enums +library appwrite.enums; + +part 'src/enums/factor.dart'; +part 'src/enums/type.dart'; +part 'src/enums/o_auth_provider.dart'; +part 'src/enums/browser.dart'; +part 'src/enums/credit_card.dart'; +part 'src/enums/flag.dart'; +part 'src/enums/execution_method.dart'; +part 'src/enums/image_gravity.dart'; +part 'src/enums/image_format.dart'; diff --git a/lib/models.dart b/lib/models.dart index 31e8119..920216e 100644 --- a/lib/models.dart +++ b/lib/models.dart @@ -43,3 +43,8 @@ part 'src/models/language.dart'; 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_type.dart'; +part 'src/models/mfa_factors.dart'; +part 'src/models/subscriber.dart'; +part 'src/models/target.dart'; diff --git a/lib/query.dart b/lib/query.dart index c70f7ab..5e7870a 100644 --- a/lib/query.dart +++ b/lib/query.dart @@ -1,8 +1,32 @@ part of appwrite; + /// Helper class to generate query strings. class Query { - Query._(); + final String method; + final String? attribute; + final dynamic values; + + Query._(this.method, [this.attribute = null, this.values = null]); + + Map toJson() { + final map = { + 'method': method, + }; + + if(attribute != null) { + map['attribute'] = attribute; + } + + if(values != null) { + map['values'] = values is List ? values : [values]; + } + + return map; + } + + @override + String toString() => jsonEncode(toJson()); /// Filter resources where [attribute] is equal to [value]. /// @@ -10,90 +34,90 @@ class Query { /// the query will return resources where [attribute] is equal /// to any of the values in the list. static String equal(String attribute, dynamic value) => - _addQuery(attribute, 'equal', value); + Query._('equal', attribute, value).toString(); /// Filter resources where [attribute] is not equal to [value]. - /// - /// [value] can be a single value or a list. If a list is used - /// the query will return resources where [attribute] is equal - /// to any of the values in the list. static String notEqual(String attribute, dynamic value) => - _addQuery(attribute, 'notEqual', value); + Query._('notEqual', attribute, [value]).toString(); /// Filter resources where [attribute] is less than [value]. static String lessThan(String attribute, dynamic value) => - _addQuery(attribute, 'lessThan', value); + Query._('lessThan', attribute, value).toString(); /// Filter resources where [attribute] is less than or equal to [value]. static String lessThanEqual(String attribute, dynamic value) => - _addQuery(attribute, 'lessThanEqual', value); + Query._('lessThanEqual', attribute, value).toString(); /// Filter resources where [attribute] is greater than [value]. static String greaterThan(String attribute, dynamic value) => - _addQuery(attribute, 'greaterThan', value); + Query._('greaterThan', attribute, value).toString(); /// Filter resources where [attribute] is greater than or equal to [value]. static String greaterThanEqual(String attribute, dynamic value) => - _addQuery(attribute, 'greaterThanEqual', value); + Query._('greaterThanEqual', attribute, value).toString(); /// Filter resources where by searching [attribute] for [value]. static String search(String attribute, String value) => - _addQuery(attribute, 'search', value); + Query._('search', attribute, value).toString(); /// Filter resources where [attribute] is null. - static String isNull(String attribute) => 'isNull("$attribute")'; + static String isNull(String attribute) => Query._('isNull', attribute).toString(); /// Filter resources where [attribute] is not null. - static String isNotNull(String attribute) => 'isNotNull("$attribute")'; + static String isNotNull(String attribute) => Query._('isNotNull', attribute).toString(); /// Filter resources where [attribute] is between [start] and [end] (inclusive). static String between(String attribute, dynamic start, dynamic end) => - 'between("$attribute", ${_parseValues(start)}, ${_parseValues(end)})'; + Query._('between', attribute, [start, end]).toString(); /// Filter resources where [attribute] starts with [value]. static String startsWith(String attribute, String value) => - _addQuery(attribute, 'startsWith', value); + Query._('startsWith', attribute, value).toString(); /// Filter resources where [attribute] ends with [value]. static String endsWith(String attribute, String value) => - _addQuery(attribute, 'endsWith', value); + Query._('endsWith', attribute, value).toString(); + + /// Filter resources where [attribute] contains [value] + /// [value] can be a single value or a list. + static String contains(String attribute, dynamic value) => + Query._('contains', attribute, value).toString(); + + static String or(List queries) => + Query._('or', null, queries.map((query) => jsonDecode(query)).toList()).toString(); + + static String and(List queries) => + Query._('and', null, queries.map((query) => jsonDecode(query)).toList()).toString(); /// Specify which attributes should be returned by the API call. static String select(List attributes) => - 'select([${attributes.map((attr) => "\"$attr\"").join(",")}])'; + Query._('select', null, attributes).toString(); /// Sort results by [attribute] ascending. - static String orderAsc(String attribute) => 'orderAsc("$attribute")'; + static String orderAsc(String attribute) => Query._('orderAsc', attribute).toString(); /// Sort results by [attribute] descending. - static String orderDesc(String attribute) => 'orderDesc("$attribute")'; + static String orderDesc(String attribute) => Query._('orderDesc', attribute).toString(); /// Return results before [id]. /// /// Refer to the [Cursor Based Pagination](https://appwrite.io/docs/pagination#cursor-pagination) /// docs for more information. - static String cursorBefore(String id) => 'cursorBefore("$id")'; + static String cursorBefore(String id) => Query._('cursorBefore', null, id).toString(); /// Return results after [id]. /// /// Refer to the [Cursor Based Pagination](https://appwrite.io/docs/pagination#cursor-pagination) /// docs for more information. - static String cursorAfter(String id) => 'cursorAfter("$id")'; + static String cursorAfter(String id) => Query._('cursorAfter', null, id).toString(); /// Return only [limit] results. - static String limit(int limit) => 'limit($limit)'; + static String limit(int limit) => Query._('limit', null, limit).toString(); /// Return results from [offset]. /// /// Refer to the [Offset Pagination](https://appwrite.io/docs/pagination#offset-pagination) /// docs for more information. - static String offset(int offset) => 'offset($offset)'; + static String offset(int offset) => Query._('offset', null, offset).toString(); - static String _addQuery(String attribute, String method, dynamic value) => (value - is List) - ? '$method("$attribute", [${value.map((item) => _parseValues(item)).join(",")}])' - : '$method("$attribute", [${_parseValues(value)}])'; - - static String _parseValues(dynamic value) => - (value is String) ? '"$value"' : '$value'; } \ No newline at end of file diff --git a/lib/services/account.dart b/lib/services/account.dart index 56bebc1..97c3b5f 100644 --- a/lib/services/account.dart +++ b/lib/services/account.dart @@ -84,7 +84,7 @@ class Account extends Service { /// List Identities /// /// Get the list of identities for the currently logged in user. - Future listIdentities({String? queries}) async { + Future listIdentities({List? queries}) async { const String apiPath = '/account/identities'; final Map apiParams = { @@ -101,7 +101,7 @@ class Account extends Service { } - /// Delete Identity + /// Delete identity /// /// Delete an identity by its unique ID. Future deleteIdentity({required String identityId}) async { @@ -164,6 +164,138 @@ class Account extends Service { } + /// Update MFA + /// + Future updateMFA({required bool mfa}) async { + const String apiPath = '/account/mfa'; + + final Map apiParams = { + 'mfa': mfa, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.patch, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.User.fromMap(res.data); + + } + + /// Create 2FA Challenge + /// + Future create2FAChallenge({required enums.Factor factor}) async { + const String apiPath = '/account/mfa/challenge'; + + final Map apiParams = { + 'factor': factor, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.MfaChallenge.fromMap(res.data); + + } + + /// Create MFA Challenge (confirmation) + /// + Future updateChallenge({required String challengeId, required String otp}) async { + const String apiPath = '/account/mfa/challenge'; + + final Map apiParams = { + 'challengeId': challengeId, + 'otp': otp, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.put, path: apiPath, params: apiParams, headers: apiHeaders); + + return res.data; + + } + + /// List Factors + /// + Future listFactors() async { + const String apiPath = '/account/mfa/factors'; + + final Map apiParams = { + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.get, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.MfaFactors.fromMap(res.data); + + } + + /// Add Authenticator + /// + Future addAuthenticator({required enums.Type type}) async { + final String apiPath = '/account/mfa/{type}'.replaceAll('{type}', type); + + final Map apiParams = { + }; + + final Map 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 + /// + Future verifyAuthenticator({required enums.Type type, required String otp}) async { + final String apiPath = '/account/mfa/{type}'.replaceAll('{type}', type); + + final Map apiParams = { + 'otp': otp, + }; + + final Map 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 + /// + Future deleteAuthenticator({required enums.Type type, required String otp}) async { + final String apiPath = '/account/mfa/{type}'.replaceAll('{type}', type); + + final Map apiParams = { + 'otp': otp, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.delete, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.User.fromMap(res.data); + + } + /// Update name /// /// Update currently logged in user account name. @@ -313,14 +445,13 @@ class Account extends Service { /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) /// the only valid redirect URLs are the ones from domains you have set when /// adding your platforms in the console interface. - Future updateRecovery({required String userId, required String secret, required String password, required String passwordAgain}) async { + Future updateRecovery({required String userId, required String secret, required String password}) async { const String apiPath = '/account/recovery'; final Map apiParams = { 'userId': userId, 'secret': secret, 'password': password, - 'passwordAgain': passwordAgain, }; final Map apiHeaders = { @@ -398,7 +529,7 @@ class Account extends Service { } - /// Create email session + /// Create email password session /// /// Allow the user to login into their account by providing a valid email and /// password combination. This route will create a new session for the user. @@ -406,7 +537,7 @@ class Account extends Service { /// A user is limited to 10 active sessions at a time by default. [Learn more /// about session /// limits](https://appwrite.io/docs/authentication-security#limits). - Future createEmailSession({required String email, required String password}) async { + Future createEmailPasswordSession({required String email, required String password}) async { const String apiPath = '/account/sessions/email'; final Map apiParams = { @@ -424,56 +555,11 @@ class Account extends Service { } - /// Create magic URL session + /// Create session (deprecated) /// - /// Sends the user an email with a secret key for creating a session. If the - /// provided user ID has not been registered, a new user will be created. When - /// the user clicks the link in the email, the user is redirected back to the - /// URL you provided with the secret key and userId values attached to the URL - /// query string. Use the query string parameters to submit a request to the - /// [PUT - /// /account/sessions/magic-url](https://appwrite.io/docs/references/cloud/client-web/account#updateMagicURLSession) - /// endpoint to complete the login process. The link sent to the user's email - /// address is valid for 1 hour. If you are on a mobile device you can leave - /// the URL parameter empty, so that the login completion will be handled by - /// your Appwrite instance by default. - /// - /// A user is limited to 10 active sessions at a time by default. [Learn more - /// about session - /// limits](https://appwrite.io/docs/authentication-security#limits). - /// - Future createMagicURLSession({required String userId, required String email, String? url}) async { - const String apiPath = '/account/sessions/magic-url'; - - final Map apiParams = { - 'userId': userId, - 'email': email, - 'url': url, - }; - - final Map apiHeaders = { - 'content-type': 'application/json', - }; - - final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); - - return models.Token.fromMap(res.data); - - } - - /// Create magic URL session (confirmation) - /// - /// Use this endpoint to complete creating the session with the Magic URL. Both - /// the **userId** and **secret** arguments will be passed as query parameters - /// to the redirect URL you have provided when sending your request to the - /// [POST - /// /account/sessions/magic-url](https://appwrite.io/docs/references/cloud/client-web/account#createMagicURLSession) - /// endpoint. - /// - /// Please note that in order to avoid a [Redirect - /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) - /// the only valid redirect URLs are the ones from domains you have set when - /// adding your platforms in the console interface. + /// Use this endpoint to create a session from token. Provide the **userId** + /// and **secret** parameters from the successful response of authentication + /// flows initiated by token creation. For example, magic URL and phone login. Future updateMagicURLSession({required String userId, required String secret}) async { const String apiPath = '/account/sessions/magic-url'; @@ -510,13 +596,14 @@ class Account extends Service { /// about session /// limits](https://appwrite.io/docs/authentication-security#limits). /// - Future createOAuth2Session({required String provider, String? success, String? failure, List? scopes}) async { + Future createOAuth2Session({required enums.OAuthProvider provider, String? success, String? failure, bool? token, List? scopes}) async { final String apiPath = '/account/sessions/oauth2/{provider}'.replaceAll('{provider}', provider); final Map params = { 'success': success, 'failure': failure, + 'token': token, 'scopes': scopes, 'project': client.config['project'], @@ -545,45 +632,13 @@ class Account extends Service { return client.webAuth(url, callbackUrlScheme: success); } - /// Create phone session + /// Create session /// - /// Sends the user an SMS with a secret key for creating a session. If the - /// provided user ID has not be registered, a new user will be created. Use the - /// returned user ID and secret and submit a request to the [PUT - /// /account/sessions/phone](https://appwrite.io/docs/references/cloud/client-web/account#updatePhoneSession) - /// endpoint to complete the login process. The secret sent to the user's phone - /// is valid for 15 minutes. - /// - /// A user is limited to 10 active sessions at a time by default. [Learn more - /// about session - /// limits](https://appwrite.io/docs/authentication-security#limits). - Future createPhoneSession({required String userId, required String phone}) async { - const String apiPath = '/account/sessions/phone'; - - final Map apiParams = { - 'userId': userId, - 'phone': phone, - }; - - final Map apiHeaders = { - 'content-type': 'application/json', - }; - - final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); - - return models.Token.fromMap(res.data); - - } - - /// Create phone session (confirmation) - /// - /// Use this endpoint to complete creating a session with SMS. Use the - /// **userId** from the - /// [createPhoneSession](https://appwrite.io/docs/references/cloud/client-web/account#createPhoneSession) - /// endpoint and the **secret** received via SMS to successfully update and - /// confirm the phone session. - Future updatePhoneSession({required String userId, required String secret}) async { - const String apiPath = '/account/sessions/phone'; + /// Use this endpoint to create a session from token. Provide the **userId** + /// and **secret** parameters from the successful response of authentication + /// flows initiated by token creation. For example, magic URL and phone login. + Future createSession({required String userId, required String secret}) async { + const String apiPath = '/account/sessions/token'; final Map apiParams = { 'userId': userId, @@ -594,7 +649,7 @@ class Account extends Service { 'content-type': 'application/json', }; - final res = await client.call(HttpMethod.put, path: apiPath, params: apiParams, headers: apiHeaders); + final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); return models.Session.fromMap(res.data); @@ -620,11 +675,10 @@ class Account extends Service { } - /// Update OAuth session (refresh tokens) + /// Update (or renew) a session /// - /// Access tokens have limited lifespan and expire to mitigate security risks. - /// If session was created using an OAuth provider, this route can be used to - /// "refresh" the access token. + /// Extend session's expiry to increase it's lifespan. Extending a session is + /// useful when session length is short such as 5 minutes. Future updateSession({required String sessionId}) async { final String apiPath = '/account/sessions/{sessionId}'.replaceAll('{sessionId}', sessionId); @@ -685,6 +739,163 @@ class Account extends Service { } + /// Create a push target + /// + Future createPushTarget({required String targetId, required String identifier, String? providerId}) async { + const String apiPath = '/account/targets/push'; + + final Map apiParams = { + 'targetId': targetId, + 'identifier': identifier, + 'providerId': providerId, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.Target.fromMap(res.data); + + } + + /// Update a push target + /// + Future updatePushTarget({required String targetId, required String identifier}) async { + final String apiPath = '/account/targets/{targetId}/push'.replaceAll('{targetId}', targetId); + + final Map apiParams = { + 'identifier': identifier, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.put, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.Target.fromMap(res.data); + + } + + /// Delete a push target + /// + Future deletePushTarget({required String targetId}) async { + final String apiPath = '/account/targets/{targetId}/push'.replaceAll('{targetId}', targetId); + + final Map apiParams = { + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.delete, path: apiPath, params: apiParams, headers: apiHeaders); + + return res.data; + + } + + /// Create email token (OTP) + /// + /// Sends the user an email with a secret key for creating a session. If the + /// provided user ID has not be registered, a new user will be created. Use the + /// returned user ID and secret and submit a request to the [POST + /// /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint to complete the login process. The secret sent to the user's email + /// is valid for 15 minutes. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + Future createEmailToken({required String userId, required String email, bool? phrase}) async { + const String apiPath = '/account/tokens/email'; + + final Map apiParams = { + 'userId': userId, + 'email': email, + 'phrase': phrase, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.Token.fromMap(res.data); + + } + + /// Create magic URL token + /// + /// Sends the user an email with a secret key for creating a session. If the + /// provided user ID has not been registered, a new user will be created. When + /// the user clicks the link in the email, the user is redirected back to the + /// URL you provided with the secret key and userId values attached to the URL + /// query string. Use the query string parameters to submit a request to the + /// [POST + /// /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint to complete the login process. The link sent to the user's email + /// address is valid for 1 hour. If you are on a mobile device you can leave + /// the URL parameter empty, so that the login completion will be handled by + /// your Appwrite instance by default. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + /// + Future createMagicURLToken({required String userId, required String email, String? url, bool? phrase}) async { + const String apiPath = '/account/tokens/magic-url'; + + final Map apiParams = { + 'userId': userId, + 'email': email, + 'url': url, + 'phrase': phrase, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.Token.fromMap(res.data); + + } + + /// Create phone token + /// + /// Sends the user an SMS with a secret key for creating a session. If the + /// provided user ID has not be registered, a new user will be created. Use the + /// returned user ID and secret and submit a request to the [POST + /// /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + /// endpoint to complete the login process. The secret sent to the user's phone + /// is valid for 15 minutes. + /// + /// A user is limited to 10 active sessions at a time by default. [Learn more + /// about session + /// limits](https://appwrite.io/docs/authentication-security#limits). + Future createPhoneToken({required String userId, required String phone}) async { + const String apiPath = '/account/tokens/phone'; + + final Map apiParams = { + 'userId': userId, + 'phone': phone, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.Token.fromMap(res.data); + + } + /// Create email verification /// /// Use this endpoint to send a verification message to your user email address diff --git a/lib/services/avatars.dart b/lib/services/avatars.dart index 2bf8723..a656e52 100644 --- a/lib/services/avatars.dart +++ b/lib/services/avatars.dart @@ -18,7 +18,7 @@ class Avatars extends Service { /// with preserved aspect ratio. If both dimensions are 0, the API provides an /// image at source quality. If dimensions are not specified, the default size /// of image returned is 100x100px. - Future getBrowser({required String code, int? width, int? height, int? quality}) async { + Future getBrowser({required enums.Browser code, int? width, int? height, int? quality}) async { final String apiPath = '/avatars/browsers/{code}'.replaceAll('{code}', code); final Map params = { @@ -45,7 +45,7 @@ class Avatars extends Service { /// image at source quality. If dimensions are not specified, the default size /// of image returned is 100x100px. /// - Future getCreditCard({required String code, int? width, int? height, int? quality}) async { + Future getCreditCard({required enums.CreditCard code, int? width, int? height, int? quality}) async { final String apiPath = '/avatars/credit-cards/{code}'.replaceAll('{code}', code); final Map params = { @@ -92,7 +92,7 @@ class Avatars extends Service { /// image at source quality. If dimensions are not specified, the default size /// of image returned is 100x100px. /// - Future getFlag({required String code, int? width, int? height, int? quality}) async { + Future getFlag({required enums.Flag code, int? width, int? height, int? quality}) async { final String apiPath = '/avatars/flags/{code}'.replaceAll('{code}', code); final Map params = { diff --git a/lib/services/functions.dart b/lib/services/functions.dart index 8342494..f3688b4 100644 --- a/lib/services/functions.dart +++ b/lib/services/functions.dart @@ -34,7 +34,7 @@ class Functions extends Service { /// current execution status. You can ping the `Get Execution` endpoint to get /// updates on the current execution status. Once this endpoint is called, your /// function execution process will start asynchronously. - Future createExecution({required String functionId, String? body, bool? xasync, String? path, String? method, Map? headers}) async { + Future createExecution({required String functionId, String? body, bool? xasync, String? path, enums.ExecutionMethod? method, Map? headers}) async { final String apiPath = '/functions/{functionId}/executions'.replaceAll('{functionId}', functionId); final Map apiParams = { diff --git a/lib/services/messaging.dart b/lib/services/messaging.dart new file mode 100644 index 0000000..30e6544 --- /dev/null +++ b/lib/services/messaging.dart @@ -0,0 +1,46 @@ +part of appwrite; + +/// The Messaging service allows you to send messages to any provider type +/// (SMTP, push notification, SMS, etc.). +class Messaging extends Service { + /// Initializes a [Messaging] service + Messaging(super.client); + + /// Create a subscriber. + /// + Future createSubscriber({required String topicId, required String subscriberId, required String targetId}) async { + final String apiPath = '/messaging/topics/{topicId}/subscribers'.replaceAll('{topicId}', topicId); + + final Map apiParams = { + 'subscriberId': subscriberId, + 'targetId': targetId, + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.post, path: apiPath, params: apiParams, headers: apiHeaders); + + return models.Subscriber.fromMap(res.data); + + } + + /// Delete a subscriber. + /// + Future deleteSubscriber({required String topicId, required String subscriberId}) async { + final String apiPath = '/messaging/topics/{topicId}/subscribers/{subscriberId}'.replaceAll('{topicId}', topicId).replaceAll('{subscriberId}', subscriberId); + + final Map apiParams = { + }; + + final Map apiHeaders = { + 'content-type': 'application/json', + }; + + final res = await client.call(HttpMethod.delete, path: apiPath, params: apiParams, headers: apiHeaders); + + return res.data; + + } +} \ No newline at end of file diff --git a/lib/services/storage.dart b/lib/services/storage.dart index affb323..36643e0 100644 --- a/lib/services/storage.dart +++ b/lib/services/storage.dart @@ -165,7 +165,7 @@ class Storage extends Service { /// and spreadsheets, will return the file icon image. You can also pass query /// string arguments for cutting and resizing your preview image. Preview is /// supported only for image files smaller than 10MB. - Future getFilePreview({required String bucketId, required String fileId, int? width, int? height, String? gravity, int? quality, int? borderWidth, String? borderColor, int? borderRadius, double? opacity, int? rotation, String? background, String? output}) async { + Future getFilePreview({required String bucketId, required String fileId, int? width, int? height, enums.ImageGravity? gravity, int? quality, int? borderWidth, String? borderColor, int? borderRadius, double? opacity, int? rotation, String? background, enums.ImageFormat? output}) async { final String apiPath = '/storage/buckets/{bucketId}/files/{fileId}/preview'.replaceAll('{bucketId}', bucketId).replaceAll('{fileId}', fileId); final Map params = { diff --git a/lib/src/client.dart b/lib/src/client.dart index 0104067..5201aed 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -23,7 +23,7 @@ abstract class Client { /// Initializes a [Client]. factory Client( - {String endPoint = 'https://HOSTNAME/v1', + {String endPoint = 'https://cloud.appwrite.io/v1', bool selfSigned = false}) => createClient(endPoint: endPoint, selfSigned: selfSigned); @@ -66,6 +66,11 @@ abstract class Client { /// Set Locale. Client setLocale(value); + /// Set Session. + /// + /// The user session to authenticate with. + Client setSession(value); + /// Add headers that should be sent with all API calls. Client addHeader(String key, String value); diff --git a/lib/src/client_base.dart b/lib/src/client_base.dart index a38c1a6..f94505a 100644 --- a/lib/src/client_base.dart +++ b/lib/src/client_base.dart @@ -11,6 +11,9 @@ abstract class ClientBase implements Client { ClientBase setJWT(value); @override ClientBase setLocale(value); + /// The user session to authenticate with + @override + ClientBase setSession(value); @override ClientBase setSelfSigned({bool status = true}); diff --git a/lib/src/client_browser.dart b/lib/src/client_browser.dart index c8c40b5..919d98d 100644 --- a/lib/src/client_browser.dart +++ b/lib/src/client_browser.dart @@ -31,7 +31,7 @@ class ClientBrowser extends ClientBase with ClientMixin { String? get endPointRealtime => _endPointRealtime; ClientBrowser({ - String endPoint = 'https://HOSTNAME/v1', + String endPoint = 'https://cloud.appwrite.io/v1', bool selfSigned = false, }) : _endPoint = endPoint { _httpClient = BrowserClient(); @@ -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': '11.0.1', + 'x-sdk-version': '12.0.0-rc.2', 'X-Appwrite-Response-Format': '1.4.0', }; @@ -77,6 +77,13 @@ class ClientBrowser extends ClientBase with ClientMixin { addHeader('X-Appwrite-Locale', value); return this; } + /// The user session to authenticate with + @override + ClientBrowser setSession(value) { + config['session'] = value; + addHeader('X-Appwrite-Session', value); + return this; + } @override ClientBrowser setSelfSigned({bool status = true}) { diff --git a/lib/src/client_io.dart b/lib/src/client_io.dart index f70da7e..c22165e 100644 --- a/lib/src/client_io.dart +++ b/lib/src/client_io.dart @@ -49,7 +49,7 @@ class ClientIO extends ClientBase with ClientMixin { String? get endPointRealtime => _endPointRealtime; ClientIO({ - String endPoint = 'https://HOSTNAME/v1', + String endPoint = 'https://cloud.appwrite.io/v1', this.selfSigned = false, }) : _endPoint = endPoint { _nativeClient = HttpClient() @@ -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': '11.0.1', + 'x-sdk-version': '12.0.0-rc.2', 'X-Appwrite-Response-Format' : '1.4.0', }; @@ -106,6 +106,13 @@ class ClientIO extends ClientBase with ClientMixin { addHeader('X-Appwrite-Locale', value); return this; } + /// The user session to authenticate with + @override + ClientIO setSession(value) { + config['session'] = value; + addHeader('X-Appwrite-Session', value); + return this; + } @override ClientIO setSelfSigned({bool status = true}) { diff --git a/lib/src/enums/browser.dart b/lib/src/enums/browser.dart new file mode 100644 index 0000000..18c83a3 --- /dev/null +++ b/lib/src/enums/browser.dart @@ -0,0 +1,26 @@ +part of appwrite.enums; + +enum Browser { + avantBrowser(value: 'aa'), + androidWebViewBeta(value: 'an'), + googleChrome(value: 'ch'), + googleChromeIOS(value: 'ci'), + googleChromeMobile(value: 'cm'), + chromium(value: 'cr'), + mozillaFirefox(value: 'ff'), + safari(value: 'sf'), + mobileSafari(value: 'mf'), + microsoftEdge(value: 'ps'), + microsoftEdgeIOS(value: 'oi'), + operaMini(value: 'om'), + opera(value: 'op'), + operaNext(value: 'on'); + + const Browser({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/credit_card.dart b/lib/src/enums/credit_card.dart new file mode 100644 index 0000000..64987a0 --- /dev/null +++ b/lib/src/enums/credit_card.dart @@ -0,0 +1,28 @@ +part of appwrite.enums; + +enum CreditCard { + americanExpress(value: 'amex'), + argencard(value: 'argencard'), + cabal(value: 'cabal'), + consosud(value: 'censosud'), + dinersClub(value: 'diners'), + discover(value: 'discover'), + elo(value: 'elo'), + hipercard(value: 'hipercard'), + jCB(value: 'jcb'), + mastercard(value: 'mastercard'), + naranja(value: 'naranja'), + tarjetaShopping(value: 'targeta-shopping'), + unionChinaPay(value: 'union-china-pay'), + visa(value: 'visa'), + mIR(value: 'mir'), + maestro(value: 'maestro'); + + const CreditCard({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/execution_method.dart b/lib/src/enums/execution_method.dart new file mode 100644 index 0000000..27a94a5 --- /dev/null +++ b/lib/src/enums/execution_method.dart @@ -0,0 +1,18 @@ +part of appwrite.enums; + +enum ExecutionMethod { + gET(value: 'GET'), + pOST(value: 'POST'), + pUT(value: 'PUT'), + pATCH(value: 'PATCH'), + dELETE(value: 'DELETE'), + oPTIONS(value: 'OPTIONS'); + + const ExecutionMethod({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/factor.dart b/lib/src/enums/factor.dart new file mode 100644 index 0000000..b2d15df --- /dev/null +++ b/lib/src/enums/factor.dart @@ -0,0 +1,15 @@ +part of appwrite.enums; + +enum Factor { + totp(value: 'totp'), + phone(value: 'phone'), + email(value: 'email'); + + const Factor({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/flag.dart b/lib/src/enums/flag.dart new file mode 100644 index 0000000..38a890a --- /dev/null +++ b/lib/src/enums/flag.dart @@ -0,0 +1,206 @@ +part of appwrite.enums; + +enum Flag { + afghanistan(value: 'af'), + angola(value: 'ao'), + albania(value: 'al'), + andorra(value: 'ad'), + unitedArabEmirates(value: 'ae'), + argentina(value: 'ar'), + armenia(value: 'am'), + antiguaAndBarbuda(value: 'ag'), + australia(value: 'au'), + austria(value: 'at'), + azerbaijan(value: 'az'), + burundi(value: 'bi'), + belgium(value: 'be'), + benin(value: 'bj'), + burkinaFaso(value: 'bf'), + bangladesh(value: 'bd'), + bulgaria(value: 'bg'), + bahrain(value: 'bh'), + bahamas(value: 'bs'), + bosniaAndHerzegovina(value: 'ba'), + belarus(value: 'by'), + belize(value: 'bz'), + bolivia(value: 'bo'), + brazil(value: 'br'), + barbados(value: 'bb'), + bruneiDarussalam(value: 'bn'), + bhutan(value: 'bt'), + botswana(value: 'bw'), + centralAfricanRepublic(value: 'cf'), + canada(value: 'ca'), + switzerland(value: 'ch'), + chile(value: 'cl'), + china(value: 'cn'), + cTeDIvoire(value: 'ci'), + cameroon(value: 'cm'), + democraticRepublicOfTheCongo(value: 'cd'), + republicOfTheCongo(value: 'cg'), + colombia(value: 'co'), + comoros(value: 'km'), + capeVerde(value: 'cv'), + costaRica(value: 'cr'), + cuba(value: 'cu'), + cyprus(value: 'cy'), + czechRepublic(value: 'cz'), + germany(value: 'de'), + djibouti(value: 'dj'), + dominica(value: 'dm'), + denmark(value: 'dk'), + dominicanRepublic(value: 'do'), + algeria(value: 'dz'), + ecuador(value: 'ec'), + egypt(value: 'eg'), + eritrea(value: 'er'), + spain(value: 'es'), + estonia(value: 'ee'), + ethiopia(value: 'et'), + finland(value: 'fi'), + fiji(value: 'fj'), + france(value: 'fr'), + micronesiaFederatedStatesOf(value: 'fm'), + gabon(value: 'ga'), + unitedKingdom(value: 'gb'), + georgia(value: 'ge'), + ghana(value: 'gh'), + guinea(value: 'gn'), + gambia(value: 'gm'), + guineaBissau(value: 'gw'), + equatorialGuinea(value: 'gq'), + greece(value: 'gr'), + grenada(value: 'gd'), + guatemala(value: 'gt'), + guyana(value: 'gy'), + honduras(value: 'hn'), + croatia(value: 'hr'), + haiti(value: 'ht'), + hungary(value: 'hu'), + indonesia(value: 'id'), + india(value: 'in'), + ireland(value: 'ie'), + iranIslamicRepublicOf(value: 'ir'), + iraq(value: 'iq'), + iceland(value: 'is'), + israel(value: 'il'), + italy(value: 'it'), + jamaica(value: 'jm'), + jordan(value: 'jo'), + japan(value: 'jp'), + kazakhstan(value: 'kz'), + kenya(value: 'ke'), + kyrgyzstan(value: 'kg'), + cambodia(value: 'kh'), + kiribati(value: 'ki'), + saintKittsAndNevis(value: 'kn'), + southKorea(value: 'kr'), + kuwait(value: 'kw'), + laoPeopleSDemocraticRepublic(value: 'la'), + lebanon(value: 'lb'), + liberia(value: 'lr'), + libya(value: 'ly'), + saintLucia(value: 'lc'), + liechtenstein(value: 'li'), + sriLanka(value: 'lk'), + lesotho(value: 'ls'), + lithuania(value: 'lt'), + luxembourg(value: 'lu'), + latvia(value: 'lv'), + morocco(value: 'ma'), + monaco(value: 'mc'), + moldova(value: 'md'), + madagascar(value: 'mg'), + maldives(value: 'mv'), + mexico(value: 'mx'), + marshallIslands(value: 'mh'), + northMacedonia(value: 'mk'), + mali(value: 'ml'), + malta(value: 'mt'), + myanmar(value: 'mm'), + montenegro(value: 'me'), + mongolia(value: 'mn'), + mozambique(value: 'mz'), + mauritania(value: 'mr'), + mauritius(value: 'mu'), + malawi(value: 'mw'), + malaysia(value: 'my'), + namibia(value: 'na'), + niger(value: 'ne'), + nigeria(value: 'ng'), + nicaragua(value: 'ni'), + netherlands(value: 'nl'), + norway(value: 'no'), + nepal(value: 'np'), + nauru(value: 'nr'), + newZealand(value: 'nz'), + oman(value: 'om'), + pakistan(value: 'pk'), + panama(value: 'pa'), + peru(value: 'pe'), + philippines(value: 'ph'), + palau(value: 'pw'), + papuaNewGuinea(value: 'pg'), + poland(value: 'pl'), + northKorea(value: 'kp'), + portugal(value: 'pt'), + paraguay(value: 'py'), + qatar(value: 'qa'), + romania(value: 'ro'), + russia(value: 'ru'), + rwanda(value: 'rw'), + saudiArabia(value: 'sa'), + sudan(value: 'sd'), + senegal(value: 'sn'), + singapore(value: 'sg'), + solomonIslands(value: 'sb'), + sierraLeone(value: 'sl'), + elSalvador(value: 'sv'), + sanMarino(value: 'sm'), + somalia(value: 'so'), + serbia(value: 'rs'), + southSudan(value: 'ss'), + saoTomeAndPrincipe(value: 'st'), + suriname(value: 'sr'), + slovakia(value: 'sk'), + slovenia(value: 'si'), + sweden(value: 'se'), + eswatini(value: 'sz'), + seychelles(value: 'sc'), + syria(value: 'sy'), + chad(value: 'td'), + togo(value: 'tg'), + thailand(value: 'th'), + tajikistan(value: 'tj'), + turkmenistan(value: 'tm'), + timorLeste(value: 'tl'), + tonga(value: 'to'), + trinidadAndTobago(value: 'tt'), + tunisia(value: 'tn'), + turkey(value: 'tr'), + tuvalu(value: 'tv'), + tanzania(value: 'tz'), + uganda(value: 'ug'), + ukraine(value: 'ua'), + uruguay(value: 'uy'), + unitedStates(value: 'us'), + uzbekistan(value: 'uz'), + vaticanCity(value: 'va'), + saintVincentAndTheGrenadines(value: 'vc'), + venezuela(value: 've'), + vietnam(value: 'vn'), + vanuatu(value: 'vu'), + samoa(value: 'ws'), + yemen(value: 'ye'), + southAfrica(value: 'za'), + zambia(value: 'zm'), + zimbabwe(value: 'zw'); + + const Flag({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/image_format.dart b/lib/src/enums/image_format.dart new file mode 100644 index 0000000..99941fb --- /dev/null +++ b/lib/src/enums/image_format.dart @@ -0,0 +1,17 @@ +part of appwrite.enums; + +enum ImageFormat { + jpg(value: 'jpg'), + jpeg(value: 'jpeg'), + gif(value: 'gif'), + png(value: 'png'), + webp(value: 'webp'); + + const ImageFormat({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/image_gravity.dart b/lib/src/enums/image_gravity.dart new file mode 100644 index 0000000..1d05c57 --- /dev/null +++ b/lib/src/enums/image_gravity.dart @@ -0,0 +1,21 @@ +part of appwrite.enums; + +enum ImageGravity { + center(value: 'center'), + topLeft(value: 'top-left'), + top(value: 'top'), + topRight(value: 'top-right'), + left(value: 'left'), + right(value: 'right'), + bottomLeft(value: 'bottom-left'), + bottom(value: 'bottom'), + bottomRight(value: 'bottom-right'); + + const ImageGravity({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/o_auth_provider.dart b/lib/src/enums/o_auth_provider.dart new file mode 100644 index 0000000..ee6d5aa --- /dev/null +++ b/lib/src/enums/o_auth_provider.dart @@ -0,0 +1,51 @@ +part of appwrite.enums; + +enum OAuthProvider { + amazon(value: 'amazon'), + apple(value: 'apple'), + auth0(value: 'auth0'), + authentik(value: 'authentik'), + autodesk(value: 'autodesk'), + bitbucket(value: 'bitbucket'), + bitly(value: 'bitly'), + box(value: 'box'), + dailymotion(value: 'dailymotion'), + discord(value: 'discord'), + disqus(value: 'disqus'), + dropbox(value: 'dropbox'), + etsy(value: 'etsy'), + facebook(value: 'facebook'), + github(value: 'github'), + gitlab(value: 'gitlab'), + google(value: 'google'), + linkedin(value: 'linkedin'), + microsoft(value: 'microsoft'), + notion(value: 'notion'), + oidc(value: 'oidc'), + okta(value: 'okta'), + paypal(value: 'paypal'), + paypalSandbox(value: 'paypalSandbox'), + podio(value: 'podio'), + salesforce(value: 'salesforce'), + slack(value: 'slack'), + spotify(value: 'spotify'), + stripe(value: 'stripe'), + tradeshift(value: 'tradeshift'), + tradeshiftBox(value: 'tradeshiftBox'), + twitch(value: 'twitch'), + wordpress(value: 'wordpress'), + yahoo(value: 'yahoo'), + yammer(value: 'yammer'), + yandex(value: 'yandex'), + zoho(value: 'zoho'), + zoom(value: 'zoom'), + mock(value: 'mock'); + + const OAuthProvider({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/enums/type.dart b/lib/src/enums/type.dart new file mode 100644 index 0000000..6604287 --- /dev/null +++ b/lib/src/enums/type.dart @@ -0,0 +1,13 @@ +part of appwrite.enums; + +enum Type { + totp(value: 'totp'); + + const Type({ + required this.value + }); + + final String value; + + String toJson() => value; +} \ No newline at end of file diff --git a/lib/src/models/membership.dart b/lib/src/models/membership.dart index 75ddb8d..c3a22fa 100644 --- a/lib/src/models/membership.dart +++ b/lib/src/models/membership.dart @@ -24,6 +24,8 @@ class Membership implements Model { final String joined; /// User confirmation status, true if the user has joined the team or false otherwise. final bool confirm; + /// Multi factor authentication status, true if the user has MFA enabled or false otherwise. + final bool mfa; /// User list of roles final List roles; @@ -39,6 +41,7 @@ class Membership implements Model { required this.invited, required this.joined, required this.confirm, + required this.mfa, required this.roles, }); @@ -55,6 +58,7 @@ class Membership implements Model { invited: map['invited'].toString(), joined: map['joined'].toString(), confirm: map['confirm'], + mfa: map['mfa'], roles: map['roles'] ?? [], ); } @@ -72,6 +76,7 @@ class Membership implements Model { "invited": invited, "joined": joined, "confirm": confirm, + "mfa": mfa, "roles": roles, }; } diff --git a/lib/src/models/mfa_challenge.dart b/lib/src/models/mfa_challenge.dart new file mode 100644 index 0000000..db1c024 --- /dev/null +++ b/lib/src/models/mfa_challenge.dart @@ -0,0 +1,38 @@ +part of appwrite.models; + +/// MFA Challenge +class MfaChallenge implements Model { + /// Token ID. + final String $id; + /// Token creation date in ISO 8601 format. + final String $createdAt; + /// User ID. + final String userId; + /// Token expiration date in ISO 8601 format. + final String expire; + + MfaChallenge({ + required this.$id, + required this.$createdAt, + required this.userId, + required this.expire, + }); + + factory MfaChallenge.fromMap(Map map) { + return MfaChallenge( + $id: map['\$id'].toString(), + $createdAt: map['\$createdAt'].toString(), + userId: map['userId'].toString(), + expire: map['expire'].toString(), + ); + } + + Map toMap() { + return { + "\$id": $id, + "\$createdAt": $createdAt, + "userId": userId, + "expire": expire, + }; + } +} diff --git a/lib/src/models/mfa_factors.dart b/lib/src/models/mfa_factors.dart new file mode 100644 index 0000000..2fe4978 --- /dev/null +++ b/lib/src/models/mfa_factors.dart @@ -0,0 +1,33 @@ +part of appwrite.models; + +/// MFAFactors +class MfaFactors implements Model { + /// TOTP + final bool totp; + /// Phone + final bool phone; + /// Email + final bool email; + + MfaFactors({ + required this.totp, + required this.phone, + required this.email, + }); + + factory MfaFactors.fromMap(Map map) { + return MfaFactors( + totp: map['totp'], + phone: map['phone'], + email: map['email'], + ); + } + + Map toMap() { + return { + "totp": totp, + "phone": phone, + "email": email, + }; + } +} diff --git a/lib/src/models/mfa_type.dart b/lib/src/models/mfa_type.dart new file mode 100644 index 0000000..d30fb32 --- /dev/null +++ b/lib/src/models/mfa_type.dart @@ -0,0 +1,33 @@ +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 map) { + return MfaType( + backups: map['backups'] ?? [], + secret: map['secret'].toString(), + uri: map['uri'].toString(), + ); + } + + Map toMap() { + return { + "backups": backups, + "secret": secret, + "uri": uri, + }; + } +} diff --git a/lib/src/models/session.dart b/lib/src/models/session.dart index 6f3421c..76b921f 100644 --- a/lib/src/models/session.dart +++ b/lib/src/models/session.dart @@ -52,6 +52,10 @@ class Session implements Model { final String countryName; /// Returns true if this the current user session. final bool current; + /// Returns a list of active session factors. + final List factors; + /// Secret used to authenticate the user. Only included if the request was made with an API key + final String secret; Session({ required this.$id, @@ -79,6 +83,8 @@ class Session implements Model { required this.countryCode, required this.countryName, required this.current, + required this.factors, + required this.secret, }); factory Session.fromMap(Map map) { @@ -108,6 +114,8 @@ class Session implements Model { countryCode: map['countryCode'].toString(), countryName: map['countryName'].toString(), current: map['current'], + factors: map['factors'] ?? [], + secret: map['secret'].toString(), ); } @@ -138,6 +146,8 @@ class Session implements Model { "countryCode": countryCode, "countryName": countryName, "current": current, + "factors": factors, + "secret": secret, }; } } diff --git a/lib/src/models/subscriber.dart b/lib/src/models/subscriber.dart new file mode 100644 index 0000000..59ed84a --- /dev/null +++ b/lib/src/models/subscriber.dart @@ -0,0 +1,63 @@ +part of appwrite.models; + +/// Subscriber +class Subscriber implements Model { + /// Subscriber ID. + final String $id; + /// Subscriber creation time in ISO 8601 format. + final String $createdAt; + /// Subscriber update date in ISO 8601 format. + final String $updatedAt; + /// Target ID. + final String targetId; + /// Target. + final Target target; + /// Topic ID. + final String userId; + /// User Name. + final String userName; + /// Topic ID. + final String topicId; + /// The target provider type. Can be one of the following: `email`, `sms` or `push`. + final String providerType; + + Subscriber({ + required this.$id, + required this.$createdAt, + required this.$updatedAt, + required this.targetId, + required this.target, + required this.userId, + required this.userName, + required this.topicId, + required this.providerType, + }); + + factory Subscriber.fromMap(Map map) { + return Subscriber( + $id: map['\$id'].toString(), + $createdAt: map['\$createdAt'].toString(), + $updatedAt: map['\$updatedAt'].toString(), + targetId: map['targetId'].toString(), + target: Target.fromMap(map['target']), + userId: map['userId'].toString(), + userName: map['userName'].toString(), + topicId: map['topicId'].toString(), + providerType: map['providerType'].toString(), + ); + } + + Map toMap() { + return { + "\$id": $id, + "\$createdAt": $createdAt, + "\$updatedAt": $updatedAt, + "targetId": targetId, + "target": target.toMap(), + "userId": userId, + "userName": userName, + "topicId": topicId, + "providerType": providerType, + }; + } +} diff --git a/lib/src/models/target.dart b/lib/src/models/target.dart new file mode 100644 index 0000000..9cb7fed --- /dev/null +++ b/lib/src/models/target.dart @@ -0,0 +1,58 @@ +part of appwrite.models; + +/// Target +class Target implements Model { + /// Target ID. + final String $id; + /// Target creation time in ISO 8601 format. + final String $createdAt; + /// Target update date in ISO 8601 format. + final String $updatedAt; + /// Target Name. + final String name; + /// User ID. + final String userId; + /// Provider ID. + final String? providerId; + /// The target provider type. Can be one of the following: `email`, `sms` or `push`. + final String providerType; + /// The target identifier. + final String identifier; + + Target({ + required this.$id, + required this.$createdAt, + required this.$updatedAt, + required this.name, + required this.userId, + this.providerId, + required this.providerType, + required this.identifier, + }); + + factory Target.fromMap(Map map) { + return Target( + $id: map['\$id'].toString(), + $createdAt: map['\$createdAt'].toString(), + $updatedAt: map['\$updatedAt'].toString(), + name: map['name'].toString(), + userId: map['userId'].toString(), + providerId: map['providerId']?.toString(), + providerType: map['providerType'].toString(), + identifier: map['identifier'].toString(), + ); + } + + Map toMap() { + return { + "\$id": $id, + "\$createdAt": $createdAt, + "\$updatedAt": $updatedAt, + "name": name, + "userId": userId, + "providerId": providerId, + "providerType": providerType, + "identifier": identifier, + }; + } +} diff --git a/lib/src/models/token.dart b/lib/src/models/token.dart index 156bca5..31acde3 100644 --- a/lib/src/models/token.dart +++ b/lib/src/models/token.dart @@ -12,6 +12,8 @@ class Token implements Model { final String secret; /// Token expiration date in ISO 8601 format. final String expire; + /// Security phrase of a token. Empty if security phrase was not requested when creating a token. It includes randomly generated phrase which is also sent in the external resource such as email. + final String phrase; Token({ required this.$id, @@ -19,6 +21,7 @@ class Token implements Model { required this.userId, required this.secret, required this.expire, + required this.phrase, }); factory Token.fromMap(Map map) { @@ -28,6 +31,7 @@ class Token implements Model { userId: map['userId'].toString(), secret: map['secret'].toString(), expire: map['expire'].toString(), + phrase: map['phrase'].toString(), ); } @@ -38,6 +42,7 @@ class Token implements Model { "userId": userId, "secret": secret, "expire": expire, + "phrase": phrase, }; } } diff --git a/lib/src/models/user.dart b/lib/src/models/user.dart index bc32994..e5108be 100644 --- a/lib/src/models/user.dart +++ b/lib/src/models/user.dart @@ -32,8 +32,14 @@ class User implements Model { final bool emailVerification; /// Phone verification status. 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. + final List targets; /// Most recent access date in ISO 8601 format. This attribute is only updated again after 24 hours. final String accessedAt; @@ -53,7 +59,10 @@ class User implements Model { required this.phone, required this.emailVerification, required this.phoneVerification, + required this.mfa, + required this.totp, required this.prefs, + required this.targets, required this.accessedAt, }); @@ -74,7 +83,10 @@ class User implements Model { phone: map['phone'].toString(), emailVerification: map['emailVerification'], phoneVerification: map['phoneVerification'], + mfa: map['mfa'], + totp: map['totp'], prefs: Preferences.fromMap(map['prefs']), + targets: List.from(map['targets'].map((p) => Target.fromMap(p))), accessedAt: map['accessedAt'].toString(), ); } @@ -96,7 +108,10 @@ class User implements Model { "phone": phone, "emailVerification": emailVerification, "phoneVerification": phoneVerification, + "mfa": mfa, + "totp": totp, "prefs": prefs.toMap(), + "targets": targets.map((p) => p.toMap()).toList(), "accessedAt": accessedAt, }; } diff --git a/pubspec.yaml b/pubspec.yaml index 4f5b03f..2af5e10 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: appwrite -version: 11.0.1 +version: 12.0.0-rc.2 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 diff --git a/test/query_test.dart b/test/query_test.dart index 6fd1a07..5784cf4 100644 --- a/test/query_test.dart +++ b/test/query_test.dart @@ -19,42 +19,42 @@ void main() { BasicFilterQueryTest( description: 'with a string', value: 's', - expectedValues: '["s"]', + expectedValues: ["s"], ), BasicFilterQueryTest( description: 'with an integer', value: 1, - expectedValues: '[1]', + expectedValues: [1], ), BasicFilterQueryTest( description: 'with a double', value: 1.2, - expectedValues: '[1.2]', + expectedValues: [1.2], ), BasicFilterQueryTest( description: 'with a whole number double', value: 1.0, - expectedValues: '[1.0]', + expectedValues: [1.0], ), BasicFilterQueryTest( description: 'with a bool', value: false, - expectedValues: '[false]', + expectedValues: [false], ), BasicFilterQueryTest( description: 'with a list', value: ['a', 'b', 'c'], - expectedValues: '["a","b","c"]', + expectedValues: ["a","b","c"], ), ]; group('equal()', () { for (var t in tests) { test(t.description, () { - expect( - Query.equal('attr', t.value), - 'equal("attr", ${t.expectedValues})', - ); + final query = Query.equal('attr', t.value).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], t.expectedValues); + expect(query['method'], 'equal'); }); } }); @@ -62,10 +62,10 @@ void main() { group('notEqual()', () { for (var t in tests) { test(t.description, () { - expect( - Query.notEqual('attr', t.value), - 'notEqual("attr", ${t.expectedValues})', - ); + final query = Query.notEqual('attr', t.value).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], t.expectedValues); + expect(query['method'], 'notEqual'); }); } }); @@ -73,10 +73,10 @@ void main() { group('lessThan()', () { for (var t in tests) { test(t.description, () { - expect( - Query.lessThan('attr', t.value), - 'lessThan("attr", ${t.expectedValues})', - ); + final query = Query.lessThan('attr', t.value).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], t.expectedValues); + expect(query['method'], 'lessThan'); }); } }); @@ -84,10 +84,10 @@ void main() { group('lessThanEqual()', () { for (var t in tests) { test(t.description, () { - expect( - Query.lessThanEqual('attr', t.value), - 'lessThanEqual("attr", ${t.expectedValues})', - ); + final query = Query.lessThanEqual('attr', t.value).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], t.expectedValues); + expect(query['method'], 'lessThanEqual'); }); } }); @@ -95,10 +95,10 @@ void main() { group('greaterThan()', () { for (var t in tests) { test(t.description, () { - expect( - Query.greaterThan('attr', t.value), - 'greaterThan("attr", ${t.expectedValues})', - ); + final query = Query.greaterThan('attr', t.value).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], t.expectedValues); + expect(query['method'], 'greaterThan'); }); } }); @@ -106,87 +106,106 @@ void main() { group('greaterThanEqual()', () { for (var t in tests) { test(t.description, () { - expect( - Query.greaterThanEqual('attr', t.value), - 'greaterThanEqual("attr", ${t.expectedValues})', - ); + final query = Query.greaterThanEqual('attr', t.value).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], t.expectedValues); + expect(query['method'], 'greaterThanEqual'); }); } }); }); - group('search()', () { - test('returns search', () { - expect(Query.search('attr', 'keyword1 keyword2'), 'search("attr", ["keyword1 keyword2"])'); - }); + test('returns search', () { + final query = Query.search('attr', 'keyword1 keyword2').toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], ['keyword1 keyword2']); + expect(query['method'], 'search'); }); - group('isNull()', () { - test('returns isNull', () { - expect(Query.isNull('attr'), 'isNull("attr")'); - }); + test('returns isNull', () { + final query = Query.isNull('attr').toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], null); + expect(query['method'], 'isNull'); }); - group('isNotNull()', () { - test('returns isNotNull', () { - expect(Query.isNotNull('attr'), 'isNotNull("attr")'); - }); + test('returns isNotNull', () { + final query = Query.isNotNull('attr', 'keyword1 keyword2').toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], null); + expect(query['method'], 'isNotNull'); }); group('between()', () { test('with integers', () { - expect(Query.between('attr', 1, 2), 'between("attr", [1,2])'); + final query = Query.between('attr', 1, 2).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], [1, 2]); + expect(query['method'], 'between'); }); test('with doubles', () { - expect(Query.between('attr', 1.0, 2.0), 'between("attr", [1.0,2.0])'); + final query = Query.between('attr', 1.0, 2.0).toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], [1.0, 2.0]); + expect(query['method'], 'between'); }); test('with strings', () { - expect(Query.between('attr', "a", "z"), 'between("attr", ["a","z"])'); + final query = Query.between('attr', 'a', 'z').toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], ['a', 'z']); + expect(query['method'], 'between'); }); }); - group('select()', () { - test('returns select', () { - expect(Query.select(['attr1', 'attr2']), 'select(["attr1","attr2"])'); - }); + test('returns select', () { + final query = Query.select(['attr1', 'attr2']).toJson(); + expect(query['attribute'], null); + expect(query['values'], ['attr1', 'attr2']); + expect(query['method'], 'select'); }); - group('orderAsc()', () { - test('returns orderAsc', () { - expect(Query.orderAsc('attr'), 'orderAsc("attr")'); - }); + test('returns orderAsc', () { + final query = Query.orderAsc('attr').toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], null); + expect(query['method'], 'orderAsc'); }); - group('orderDesc()', () { - test('returns orderDesc', () { - expect(Query.orderDesc('attr'), 'orderDesc("attr")'); - }); + test('returns orderDesc', () { + final query = Query.orderDesc('attr').toJson(); + expect(query['attribute'], 'attr'); + expect(query['values'], null); + expect(query['method'], 'orderDesc'); }); - group('cursorBefore()', () { - test('returns cursorBefore', () { - expect(Query.cursorBefore(ID.custom('custom')), 'cursorBefore("custom")'); - }); + test('returns cursorBefore', () { + final query = Query.cursorBefore('custom').toJson(); + expect(query['attribute'], null); + expect(query['values'], 'custom'); + expect(query['method'], 'cursorBefore'); }); - group('cursorAfter()', () { - test('returns cursorAfter', () { - expect(Query.cursorAfter(ID.custom('custom')), 'cursorAfter("custom")'); - }); + test('returns cursorAfter', () { + final query = Query.cursorAfter('custom').toJson(); + expect(query['attribute'], null); + expect(query['values'], 'custom'); + expect(query['method'], 'cursorAfter'); }); - group('limit()', () { - test('returns limit', () { - expect(Query.limit(1), 'limit(1)'); - }); + test('returns limit', () { + final query = Query.limit(1).toJson(); + expect(query['attribute'], null); + expect(query['values'], 1); + expect(query['method'], 'limit'); }); - group('offset()', () { - test('returns offset', () { - expect(Query.offset(1), 'offset(1)'); - }); + test('returns offset', () { + final query = Query.offset(1).toJson(); + expect(query['attribute'], null); + expect(query['values'], 1); + expect(query['method'], 'offset'); }); } diff --git a/test/services/account_test.dart b/test/services/account_test.dart index 026d920..e82475b 100644 --- a/test/services/account_test.dart +++ b/test/services/account_test.dart @@ -68,7 +68,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -97,7 +100,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -129,7 +135,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -209,6 +218,178 @@ void main() { }); + test('test method updateMFA()', () async { + final Map 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': {}, + 'targets': [], + 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; + + + when(client.call( + HttpMethod.patch, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.updateMFA( + mfa: true, + ); + expect(response, isA()); + + }); + + test('test method create2FAChallenge()', () async { + final Map data = { + '\$id': 'bb8ea5c16897e', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + 'userId': '5e5ea5c168bb8', + 'expire': '2020-10-15T06:38:00.000+00:00',}; + + + when(client.call( + HttpMethod.post, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.create2FAChallenge( + factor: 'totp', + ); + expect(response, isA()); + + }); + + test('test method updateChallenge()', () async { + final data = ''; + + when(client.call( + HttpMethod.put, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.updateChallenge( + challengeId: '[CHALLENGE_ID]', + otp: '[OTP]', + ); + }); + + test('test method listFactors()', () async { + final Map data = { + 'totp': true, + 'phone': true, + 'email': true,}; + + + when(client.call( + HttpMethod.get, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.listFactors( + ); + expect(response, isA()); + + }); + + test('test method addAuthenticator()', () async { + final Map data = { + 'backups': [], + 'secret': '1', + 'uri': '1',}; + + + when(client.call( + HttpMethod.post, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.addAuthenticator( + type: 'totp', + ); + expect(response, isA()); + + }); + + test('test method verifyAuthenticator()', () async { + final Map 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': {}, + 'targets': [], + 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; + + + when(client.call( + HttpMethod.put, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.verifyAuthenticator( + type: 'totp', + otp: '[OTP]', + ); + expect(response, isA()); + + }); + + test('test method deleteAuthenticator()', () async { + final Map 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': {}, + '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()); + + }); + test('test method updateName()', () async { final Map data = { '\$id': '5e5ea5c16897e', @@ -223,7 +404,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -253,7 +437,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -283,7 +470,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -329,7 +519,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -351,7 +544,8 @@ void main() { '\$createdAt': '2020-10-15T06:38:00.000+00:00', 'userId': '5e5ea5c168bb8', 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; when(client.call( @@ -373,7 +567,8 @@ void main() { '\$createdAt': '2020-10-15T06:38:00.000+00:00', 'userId': '5e5ea5c168bb8', 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; when(client.call( @@ -384,8 +579,7 @@ void main() { final response = await account.updateRecovery( userId: '[USER_ID]', secret: '[SECRET]', - password: 'password', - passwordAgain: 'password', + password: '', ); expect(response, isA()); @@ -446,7 +640,9 @@ void main() { 'deviceModel': 'Nexus 5', 'countryCode': 'US', 'countryName': 'United States', - 'current': true,}; + 'current': true, + 'factors': [], + 'secret': '5e5bb8c16897e',}; when(client.call( @@ -460,7 +656,7 @@ void main() { }); - test('test method createEmailSession()', () async { + test('test method createEmailPasswordSession()', () async { final Map data = { '\$id': '5e5ea5c16897e', '\$createdAt': '2020-10-15T06:38:00.000+00:00', @@ -486,7 +682,9 @@ void main() { 'deviceModel': 'Nexus 5', 'countryCode': 'US', 'countryName': 'United States', - 'current': true,}; + 'current': true, + 'factors': [], + 'secret': '5e5bb8c16897e',}; when(client.call( @@ -494,7 +692,7 @@ void main() { )).thenAnswer((_) async => Response(data: data)); - final response = await account.createEmailSession( + final response = await account.createEmailPasswordSession( email: 'email@example.com', password: 'password', ); @@ -502,28 +700,6 @@ void main() { }); - test('test method createMagicURLSession()', () async { - final Map data = { - '\$id': 'bb8ea5c16897e', - '\$createdAt': '2020-10-15T06:38:00.000+00:00', - 'userId': '5e5ea5c168bb8', - 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; - - - when(client.call( - HttpMethod.post, - )).thenAnswer((_) async => Response(data: data)); - - - final response = await account.createMagicURLSession( - userId: '[USER_ID]', - email: 'email@example.com', - ); - expect(response, isA()); - - }); - test('test method updateMagicURLSession()', () async { final Map data = { '\$id': '5e5ea5c16897e', @@ -550,7 +726,9 @@ void main() { 'deviceModel': 'Nexus 5', 'countryCode': 'US', 'countryName': 'United States', - 'current': true,}; + 'current': true, + 'factors': [], + 'secret': '5e5bb8c16897e',}; when(client.call( @@ -578,29 +756,7 @@ void main() { ); }); - test('test method createPhoneSession()', () async { - final Map data = { - '\$id': 'bb8ea5c16897e', - '\$createdAt': '2020-10-15T06:38:00.000+00:00', - 'userId': '5e5ea5c168bb8', - 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; - - - when(client.call( - HttpMethod.post, - )).thenAnswer((_) async => Response(data: data)); - - - final response = await account.createPhoneSession( - userId: '[USER_ID]', - phone: '+12065550100', - ); - expect(response, isA()); - - }); - - test('test method updatePhoneSession()', () async { + test('test method createSession()', () async { final Map data = { '\$id': '5e5ea5c16897e', '\$createdAt': '2020-10-15T06:38:00.000+00:00', @@ -626,15 +782,17 @@ void main() { 'deviceModel': 'Nexus 5', 'countryCode': 'US', 'countryName': 'United States', - 'current': true,}; + 'current': true, + 'factors': [], + 'secret': '5e5bb8c16897e',}; when(client.call( - HttpMethod.put, + HttpMethod.post, )).thenAnswer((_) async => Response(data: data)); - final response = await account.updatePhoneSession( + final response = await account.createSession( userId: '[USER_ID]', secret: '[SECRET]', ); @@ -668,7 +826,9 @@ void main() { 'deviceModel': 'Nexus 5', 'countryCode': 'US', 'countryName': 'United States', - 'current': true,}; + 'current': true, + 'factors': [], + 'secret': '5e5bb8c16897e',}; when(client.call( @@ -709,7 +869,9 @@ void main() { 'deviceModel': 'Nexus 5', 'countryCode': 'US', 'countryName': 'United States', - 'current': true,}; + 'current': true, + 'factors': [], + 'secret': '5e5bb8c16897e',}; when(client.call( @@ -751,7 +913,10 @@ void main() { 'phone': '+4930901820', 'emailVerification': true, 'phoneVerification': true, + 'mfa': true, + 'totp': true, 'prefs': {}, + 'targets': [], 'accessedAt': '2020-10-15T06:38:00.000+00:00',}; @@ -766,13 +931,144 @@ void main() { }); + test('test method createPushTarget()', () async { + final Map data = { + '\$id': '259125845563242502', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + '\$updatedAt': '2020-10-15T06:38:00.000+00:00', + 'name': 'Aegon apple token', + 'userId': '259125845563242502', + 'providerType': 'email', + 'identifier': 'token',}; + + + when(client.call( + HttpMethod.post, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.createPushTarget( + targetId: '[TARGET_ID]', + identifier: '[IDENTIFIER]', + ); + expect(response, isA()); + + }); + + test('test method updatePushTarget()', () async { + final Map data = { + '\$id': '259125845563242502', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + '\$updatedAt': '2020-10-15T06:38:00.000+00:00', + 'name': 'Aegon apple token', + 'userId': '259125845563242502', + 'providerType': 'email', + 'identifier': 'token',}; + + + when(client.call( + HttpMethod.put, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.updatePushTarget( + targetId: '[TARGET_ID]', + identifier: '[IDENTIFIER]', + ); + expect(response, isA()); + + }); + + test('test method deletePushTarget()', () async { + final data = ''; + + when(client.call( + HttpMethod.delete, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.deletePushTarget( + targetId: '[TARGET_ID]', + ); + }); + + test('test method createEmailToken()', () async { + final Map data = { + '\$id': 'bb8ea5c16897e', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + 'userId': '5e5ea5c168bb8', + 'secret': '', + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; + + + when(client.call( + HttpMethod.post, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.createEmailToken( + userId: '[USER_ID]', + email: 'email@example.com', + ); + expect(response, isA()); + + }); + + test('test method createMagicURLToken()', () async { + final Map data = { + '\$id': 'bb8ea5c16897e', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + 'userId': '5e5ea5c168bb8', + 'secret': '', + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; + + + when(client.call( + HttpMethod.post, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.createMagicURLToken( + userId: '[USER_ID]', + email: 'email@example.com', + ); + expect(response, isA()); + + }); + + test('test method createPhoneToken()', () async { + final Map data = { + '\$id': 'bb8ea5c16897e', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + 'userId': '5e5ea5c168bb8', + 'secret': '', + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; + + + when(client.call( + HttpMethod.post, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await account.createPhoneToken( + userId: '[USER_ID]', + phone: '+12065550100', + ); + expect(response, isA()); + + }); + test('test method createVerification()', () async { final Map data = { '\$id': 'bb8ea5c16897e', '\$createdAt': '2020-10-15T06:38:00.000+00:00', 'userId': '5e5ea5c168bb8', 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; when(client.call( @@ -793,7 +1089,8 @@ void main() { '\$createdAt': '2020-10-15T06:38:00.000+00:00', 'userId': '5e5ea5c168bb8', 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; when(client.call( @@ -815,7 +1112,8 @@ void main() { '\$createdAt': '2020-10-15T06:38:00.000+00:00', 'userId': '5e5ea5c168bb8', 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; when(client.call( @@ -835,7 +1133,8 @@ void main() { '\$createdAt': '2020-10-15T06:38:00.000+00:00', 'userId': '5e5ea5c168bb8', 'secret': '', - 'expire': '2020-10-15T06:38:00.000+00:00',}; + 'expire': '2020-10-15T06:38:00.000+00:00', + 'phrase': 'Golden Fox',}; when(client.call( diff --git a/test/services/messaging_test.dart b/test/services/messaging_test.dart new file mode 100644 index 0000000..bc90a29 --- /dev/null +++ b/test/services/messaging_test.dart @@ -0,0 +1,99 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:appwrite/models.dart' as models; +import 'package:appwrite/src/enums.dart'; +import 'package:appwrite/src/response.dart'; +import 'dart:typed_data'; +import 'package:appwrite/appwrite.dart'; + +class MockClient extends Mock implements Client { + Map config = {'project': 'testproject'}; + String endPoint = 'https://localhost/v1'; + @override + Future call( + HttpMethod? method, { + String path = '', + Map headers = const {}, + Map params = const {}, + ResponseType? responseType, + }) async { + return super.noSuchMethod(Invocation.method(#call, [method]), + returnValue: Response()); + } + + @override + Future webAuth( + Uri? url, + { + String? callbackUrlScheme, + } + ) async { + return super.noSuchMethod(Invocation.method(#webAuth, [url]), returnValue: 'done'); + } + + @override + Future chunkedUpload({ + String? path, + Map? params, + String? paramName, + String? idParamName, + Map? headers, + Function(UploadProgress)? onProgress, + }) async { + return super.noSuchMethod(Invocation.method(#chunkedUpload, [path, params, paramName, idParamName, headers]), returnValue: Response(data: {})); + } +} + +void main() { + group('Messaging test', () { + late MockClient client; + late Messaging messaging; + + setUp(() { + client = MockClient(); + messaging = Messaging(client); + }); + + test('test method createSubscriber()', () async { + final Map data = { + '\$id': '259125845563242502', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + '\$updatedAt': '2020-10-15T06:38:00.000+00:00', + 'targetId': '259125845563242502', + 'target': {}, + 'userId': '5e5ea5c16897e', + 'userName': 'Aegon Targaryen', + 'topicId': '259125845563242502', + 'providerType': 'email',}; + + + when(client.call( + HttpMethod.post, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await messaging.createSubscriber( + topicId: '[TOPIC_ID]', + subscriberId: '[SUBSCRIBER_ID]', + targetId: '[TARGET_ID]', + ); + expect(response, isA()); + + }); + + test('test method deleteSubscriber()', () async { + final data = ''; + + when(client.call( + HttpMethod.delete, + )).thenAnswer((_) async => Response(data: data)); + + + final response = await messaging.deleteSubscriber( + topicId: '[TOPIC_ID]', + subscriberId: '[SUBSCRIBER_ID]', + ); + }); + + }); +} \ No newline at end of file diff --git a/test/services/teams_test.dart b/test/services/teams_test.dart index 9c80d1c..9b8217f 100644 --- a/test/services/teams_test.dart +++ b/test/services/teams_test.dart @@ -183,6 +183,7 @@ void main() { 'invited': '2020-10-15T06:38:00.000+00:00', 'joined': '2020-10-15T06:38:00.000+00:00', 'confirm': true, + 'mfa': true, 'roles': [],}; @@ -212,6 +213,7 @@ void main() { 'invited': '2020-10-15T06:38:00.000+00:00', 'joined': '2020-10-15T06:38:00.000+00:00', 'confirm': true, + 'mfa': true, 'roles': [],}; @@ -241,6 +243,7 @@ void main() { 'invited': '2020-10-15T06:38:00.000+00:00', 'joined': '2020-10-15T06:38:00.000+00:00', 'confirm': true, + 'mfa': true, 'roles': [],}; @@ -285,6 +288,7 @@ void main() { 'invited': '2020-10-15T06:38:00.000+00:00', 'joined': '2020-10-15T06:38:00.000+00:00', 'confirm': true, + 'mfa': true, 'roles': [],}; diff --git a/test/src/models/membership_test.dart b/test/src/models/membership_test.dart index bc7b3eb..5e5033e 100644 --- a/test/src/models/membership_test.dart +++ b/test/src/models/membership_test.dart @@ -17,6 +17,7 @@ void main() { invited: '2020-10-15T06:38:00.000+00:00', joined: '2020-10-15T06:38:00.000+00:00', confirm: true, + mfa: true, roles: [], ); @@ -34,6 +35,7 @@ void main() { expect(result.invited, '2020-10-15T06:38:00.000+00:00'); expect(result.joined, '2020-10-15T06:38:00.000+00:00'); expect(result.confirm, true); + expect(result.mfa, true); expect(result.roles, []); }); }); diff --git a/test/src/models/mfa_challenge_test.dart b/test/src/models/mfa_challenge_test.dart new file mode 100644 index 0000000..75afb97 --- /dev/null +++ b/test/src/models/mfa_challenge_test.dart @@ -0,0 +1,24 @@ +import 'package:appwrite/models.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('MfaChallenge', () { + + test('model', () { + final model = MfaChallenge( + $id: 'bb8ea5c16897e', + $createdAt: '2020-10-15T06:38:00.000+00:00', + userId: '5e5ea5c168bb8', + expire: '2020-10-15T06:38:00.000+00:00', + ); + + final map = model.toMap(); + final result = MfaChallenge.fromMap(map); + + expect(result.$id, 'bb8ea5c16897e'); + expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00'); + expect(result.userId, '5e5ea5c168bb8'); + expect(result.expire, '2020-10-15T06:38:00.000+00:00'); + }); + }); +} diff --git a/test/src/models/mfa_factors_test.dart b/test/src/models/mfa_factors_test.dart new file mode 100644 index 0000000..9a2e803 --- /dev/null +++ b/test/src/models/mfa_factors_test.dart @@ -0,0 +1,22 @@ +import 'package:appwrite/models.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('MfaFactors', () { + + test('model', () { + final model = MfaFactors( + totp: true, + phone: true, + email: true, + ); + + final map = model.toMap(); + final result = MfaFactors.fromMap(map); + + expect(result.totp, true); + expect(result.phone, true); + expect(result.email, true); + }); + }); +} diff --git a/test/src/models/mfa_type_test.dart b/test/src/models/mfa_type_test.dart new file mode 100644 index 0000000..2f106ca --- /dev/null +++ b/test/src/models/mfa_type_test.dart @@ -0,0 +1,22 @@ +import 'package:appwrite/models.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('MfaType', () { + + test('model', () { + final model = MfaType( + backups: [], + secret: '1', + uri: '1', + ); + + final map = model.toMap(); + final result = MfaType.fromMap(map); + + expect(result.backups, []); + expect(result.secret, '1'); + expect(result.uri, '1'); + }); + }); +} diff --git a/test/src/models/session_test.dart b/test/src/models/session_test.dart index 259ba68..20a1803 100644 --- a/test/src/models/session_test.dart +++ b/test/src/models/session_test.dart @@ -31,6 +31,8 @@ void main() { countryCode: 'US', countryName: 'United States', current: true, + factors: [], + secret: '5e5bb8c16897e', ); final map = model.toMap(); @@ -61,6 +63,8 @@ void main() { expect(result.countryCode, 'US'); expect(result.countryName, 'United States'); expect(result.current, true); + expect(result.factors, []); + expect(result.secret, '5e5bb8c16897e'); }); }); } diff --git a/test/src/models/subscriber_test.dart b/test/src/models/subscriber_test.dart new file mode 100644 index 0000000..5401b86 --- /dev/null +++ b/test/src/models/subscriber_test.dart @@ -0,0 +1,34 @@ +import 'package:appwrite/models.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Subscriber', () { + + test('model', () { + final model = Subscriber( + $id: '259125845563242502', + $createdAt: '2020-10-15T06:38:00.000+00:00', + $updatedAt: '2020-10-15T06:38:00.000+00:00', + targetId: '259125845563242502', + target: {}, + userId: '5e5ea5c16897e', + userName: 'Aegon Targaryen', + topicId: '259125845563242502', + providerType: 'email', + ); + + final map = model.toMap(); + final result = Subscriber.fromMap(map); + + expect(result.$id, '259125845563242502'); + expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00'); + expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00'); + expect(result.targetId, '259125845563242502'); + expect(result.target, {}); + expect(result.userId, '5e5ea5c16897e'); + expect(result.userName, 'Aegon Targaryen'); + expect(result.topicId, '259125845563242502'); + expect(result.providerType, 'email'); + }); + }); +} diff --git a/test/src/models/target_test.dart b/test/src/models/target_test.dart new file mode 100644 index 0000000..15d1826 --- /dev/null +++ b/test/src/models/target_test.dart @@ -0,0 +1,30 @@ +import 'package:appwrite/models.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Target', () { + + test('model', () { + final model = Target( + $id: '259125845563242502', + $createdAt: '2020-10-15T06:38:00.000+00:00', + $updatedAt: '2020-10-15T06:38:00.000+00:00', + name: 'Aegon apple token', + userId: '259125845563242502', + providerType: 'email', + identifier: 'token', + ); + + final map = model.toMap(); + final result = Target.fromMap(map); + + expect(result.$id, '259125845563242502'); + expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00'); + expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00'); + expect(result.name, 'Aegon apple token'); + expect(result.userId, '259125845563242502'); + expect(result.providerType, 'email'); + expect(result.identifier, 'token'); + }); + }); +} diff --git a/test/src/models/token_test.dart b/test/src/models/token_test.dart index 8ac3339..a2a694d 100644 --- a/test/src/models/token_test.dart +++ b/test/src/models/token_test.dart @@ -11,6 +11,7 @@ void main() { userId: '5e5ea5c168bb8', secret: '', expire: '2020-10-15T06:38:00.000+00:00', + phrase: 'Golden Fox', ); final map = model.toMap(); @@ -21,6 +22,7 @@ void main() { expect(result.userId, '5e5ea5c168bb8'); expect(result.secret, ''); expect(result.expire, '2020-10-15T06:38:00.000+00:00'); + expect(result.phrase, 'Golden Fox'); }); }); } diff --git a/test/src/models/user_test.dart b/test/src/models/user_test.dart index b98b081..cd85545 100644 --- a/test/src/models/user_test.dart +++ b/test/src/models/user_test.dart @@ -18,7 +18,10 @@ void main() { phone: '+4930901820', emailVerification: true, phoneVerification: true, + mfa: true, + totp: true, prefs: Preferences(data: {}), + targets: [], accessedAt: '2020-10-15T06:38:00.000+00:00', ); @@ -37,7 +40,10 @@ void main() { expect(result.phone, '+4930901820'); 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'); }); });