diff --git a/LICENSE b/LICENSE index 5479bb8e..c1602fcd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2024 Appwrite (https://appwrite.io) and individual contributors. +Copyright (c) 2025 Appwrite (https://appwrite.io) and individual contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index 122058ae..fdfc0266 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Add this to your package's `pubspec.yaml` file: ```yml dependencies: - appwrite: ^13.1.1 + appwrite: ^14.0.0 ``` You can install packages from the command line: diff --git a/docs/examples/account/update-mfa-challenge.md b/docs/examples/account/update-mfa-challenge.md index c8e1af7e..bbe7c034 100644 --- a/docs/examples/account/update-mfa-challenge.md +++ b/docs/examples/account/update-mfa-challenge.md @@ -6,7 +6,7 @@ Client client = Client() Account account = Account(client); - result = await account.updateMfaChallenge( +Session result = await account.updateMfaChallenge( challengeId: '', otp: '', ); diff --git a/lib/services/account.dart b/lib/services/account.dart index b812a903..c4584672 100644 --- a/lib/services/account.dart +++ b/lib/services/account.dart @@ -283,7 +283,7 @@ class Account extends Service { /// the flow, use /// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) /// method. - Future updateMfaChallenge( + Future updateMfaChallenge( {required String challengeId, required String otp}) async { const String apiPath = '/account/mfa/challenge'; @@ -299,7 +299,7 @@ class Account extends Service { final res = await client.call(HttpMethod.put, path: apiPath, params: apiParams, headers: apiHeaders); - return res.data; + return models.Session.fromMap(res.data); } /// List factors @@ -862,6 +862,11 @@ class Account extends Service { /// Create push target /// + /// Use this endpoint to register a device for push notifications. Provide a + /// target ID (custom or generated using ID.unique()), a device identifier + /// (usually a device token), and optionally specify which provider should send + /// notifications to this target. The target is automatically linked to the + /// current session and includes device information like brand and model. Future createPushTarget( {required String targetId, required String identifier, @@ -886,6 +891,11 @@ class Account extends Service { /// Update push target /// + /// Update the currently logged in user's push notification target. You can + /// modify the target's identifier (device token) and provider ID (token, + /// email, phone etc.). The target must exist and belong to the current user. + /// If you change the provider ID, notifications will be sent through the new + /// messaging provider instead. Future updatePushTarget( {required String targetId, required String identifier}) async { final String apiPath = @@ -907,6 +917,9 @@ class Account extends Service { /// Delete push target /// + /// Delete a push notification target for the currently logged in user. After + /// deletion, the device will no longer receive push notifications. The target + /// must exist and belong to the current user. Future deletePushTarget({required String targetId}) async { final String apiPath = '/account/targets/{targetId}/push'.replaceAll('{targetId}', targetId); @@ -965,9 +978,7 @@ class Account extends Service { /// [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. + /// address is valid for 1 hour. /// /// A user is limited to 10 active sessions at a time by default. [Learn more /// about session diff --git a/lib/src/client_browser.dart b/lib/src/client_browser.dart index 895a0cfc..33550e67 100644 --- a/lib/src/client_browser.dart +++ b/lib/src/client_browser.dart @@ -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': '13.1.1', + 'x-sdk-version': '14.0.0', 'X-Appwrite-Response-Format': '1.6.0', }; @@ -161,7 +161,7 @@ class ClientBrowser extends ClientBase with ClientMixin { } var offset = 0; - if (idParamName.isNotEmpty && params[idParamName] != 'unique()') { + if (idParamName.isNotEmpty) { //make a request to check if a file already exists try { res = await call( diff --git a/lib/src/client_io.dart b/lib/src/client_io.dart index 20fe9572..1ef21ca4 100644 --- a/lib/src/client_io.dart +++ b/lib/src/client_io.dart @@ -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': '13.1.1', + 'x-sdk-version': '14.0.0', 'X-Appwrite-Response-Format': '1.6.0', }; @@ -279,7 +279,7 @@ class ClientIO extends ClientBase with ClientMixin { } var offset = 0; - if (idParamName.isNotEmpty && params[idParamName] != 'unique()') { + if (idParamName.isNotEmpty) { //make a request to check if a file already exists try { res = await call( diff --git a/lib/src/enums/image_format.dart b/lib/src/enums/image_format.dart index acc07f27..4d07af18 100644 --- a/lib/src/enums/image_format.dart +++ b/lib/src/enums/image_format.dart @@ -6,6 +6,7 @@ enum ImageFormat { gif(value: 'gif'), png(value: 'png'), webp(value: 'webp'), + heic(value: 'heic'), avif(value: 'avif'); const ImageFormat({required this.value}); diff --git a/lib/src/realtime_response.dart b/lib/src/realtime_response.dart index a08eda8e..b0356111 100644 --- a/lib/src/realtime_response.dart +++ b/lib/src/realtime_response.dart @@ -29,7 +29,7 @@ class RealtimeResponse { factory RealtimeResponse.fromMap(Map map) { return RealtimeResponse( type: map['type'], - data: Map.from(map['data']), + data: Map.from(map['data'] ?? {}), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 07632898..79300b8c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: appwrite -version: 13.1.1 +version: 14.0.0 description: Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API homepage: https://appwrite.io repository: https://github.com/appwrite/sdk-for-flutter diff --git a/test/services/account_test.dart b/test/services/account_test.dart index 2473d490..045fde1f 100644 --- a/test/services/account_test.dart +++ b/test/services/account_test.dart @@ -332,7 +332,37 @@ void main() { }); test('test method updateMfaChallenge()', () async { - final data = ''; + final Map data = { + '\$id': '5e5ea5c16897e', + '\$createdAt': '2020-10-15T06:38:00.000+00:00', + '\$updatedAt': '2020-10-15T06:38:00.000+00:00', + 'userId': '5e5bb8c16897e', + 'expire': '2020-10-15T06:38:00.000+00:00', + 'provider': 'email', + 'providerUid': 'user@example.com', + 'providerAccessToken': 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3', + 'providerAccessTokenExpiry': '2020-10-15T06:38:00.000+00:00', + 'providerRefreshToken': 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3', + 'ip': '127.0.0.1', + 'osCode': 'Mac', + 'osName': 'Mac', + 'osVersion': 'Mac', + 'clientType': 'browser', + 'clientCode': 'CM', + 'clientName': 'Chrome Mobile iOS', + 'clientVersion': '84.0', + 'clientEngine': 'WebKit', + 'clientEngineVersion': '605.1.15', + 'deviceName': 'smartphone', + 'deviceBrand': 'Google', + 'deviceModel': 'Nexus 5', + 'countryCode': 'US', + 'countryName': 'United States', + 'current': true, + 'factors': [], + 'secret': '5e5bb8c16897e', + 'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',}; + when(client.call( HttpMethod.put, @@ -343,6 +373,8 @@ void main() { challengeId: '', otp: '', ); + expect(response, isA()); + }); test('test method listMfaFactors()', () async {