Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
# Change Log

## 23.1.0

* Added `x` OAuth provider to `OAuthProvider` enum
* Added `userType` field to `Log` model
* Added `getHeaders()` method to `Client`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing [BREAKING] tag for Log constructor change

Adding userType as a required named parameter to the Log constructor is a source-breaking change — any code that constructs Log directly (e.g. in unit tests or test doubles) will fail to compile without updating the call site. The 23.0.0 entry uses [BREAKING] for the $sequence type change, but this addition is unmarked in 23.1.0.

Suggested change
* Added `getHeaders()` method to `Client`
* [BREAKING] Added required `userType` field to `Log` model

* Updated `X-Appwrite-Response-Format` header to `1.9.1`
* Updated TTL description for list caching in Databases and TablesDB

## 23.0.0

* [BREAKING] Changed `$sequence` type from `int` to `string` for rows and documents
* Updated README badge to API version `1.9.x` and dependency example
* Updated dependency example to `^21.1.0`
* [BREAKING] Changed `$sequence` type from `int` to `String` for `Row` and `Document` models
* Added impersonation support: `setImpersonateUserId()`, `setImpersonateUserEmail()`, `setImpersonateUserPhone()` on `Client`, `ClientBrowser`, and `ClientIO`
* Added `impersonator` and `impersonatorUserId` optional fields to `User` model
* Updated `Log` model field descriptions to clarify impersonation behavior for `userId`, `userEmail`, `userName`
* Updated `X-Appwrite-Response-Format` header to `1.9.0`
* Updated README badge to API version `1.9.x` and dependency example to `^23.0.0`

## 22.0.0

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Add this to your package's `pubspec.yaml` file:

```yml
dependencies:
appwrite: ^23.0.0
appwrite: ^23.1.0
```

You can install packages from the command line:
Expand Down
3 changes: 3 additions & 0 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ abstract class Client {
/// Add headers that should be sent with all API calls.
Client addHeader(String key, String value);

/// Get the current request headers.
Map<String, String> getHeaders();

/// Sends a "ping" request to Appwrite to verify connectivity.
Future<String> ping();

Expand Down
3 changes: 3 additions & 0 deletions lib/src/client_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ abstract class ClientBase implements Client {
@override
ClientBase addHeader(String key, String value);

@override
Map<String, String> getHeaders();

@override
Future<String> ping() async {
final String apiPath = '/ping';
Expand Down
9 changes: 7 additions & 2 deletions lib/src/client_browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class ClientBrowser extends ClientBase with ClientMixin {
'x-sdk-name': 'Flutter',
'x-sdk-platform': 'client',
'x-sdk-language': 'flutter',
'x-sdk-version': '23.0.0',
'X-Appwrite-Response-Format': '1.9.0',
'x-sdk-version': '23.1.0',
'X-Appwrite-Response-Format': '1.9.1',
};

config = {};
Expand Down Expand Up @@ -155,6 +155,11 @@ class ClientBrowser extends ClientBase with ClientMixin {
return this;
}

@override
Map<String, String> getHeaders() {
return Map<String, String>.from(_headers!);
}
Comment on lines +159 to +161
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 getHeaders() exposes sensitive authentication headers

The returned map includes all headers set via addHeader, which may contain X-Appwrite-JWT, X-Appwrite-Session, X-Appwrite-Dev-Key, or impersonation tokens. The defensive copy (Map.from(...)) prevents mutation of internal state, which is good, but callers receive plain-text copies of any credentials stored in _headers. A brief doc comment noting that the return value may include sensitive values would help consumers use this API safely.


Future init() async {
final cookieFallback = web.window.localStorage.getItem('cookieFallback');
if (cookieFallback != null) {
Expand Down
10 changes: 7 additions & 3 deletions lib/src/client_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ class ClientIO extends ClientBase with ClientMixin {
'x-sdk-name': 'Flutter',
'x-sdk-platform': 'client',
'x-sdk-language': 'flutter',
'x-sdk-version': '23.0.0',
'X-Appwrite-Response-Format': '1.9.0',
'x-sdk-version': '23.1.0',
'X-Appwrite-Response-Format': '1.9.1',
};

config = {};
Expand Down Expand Up @@ -184,6 +184,11 @@ class ClientIO extends ClientBase with ClientMixin {
return this;
}

@override
Map<String, String> getHeaders() {
return Map<String, String>.from(_headers!);
}

Future init() async {
if (_initProgress) return;
_initProgress = true;
Expand Down Expand Up @@ -384,7 +389,6 @@ class ClientIO extends ClientBase with ClientMixin {
? callbackUrlScheme
: "appwrite-callback-${config['project']!}",
options: const FlutterWebAuth2Options(
intentFlags: ephemeralIntentFlags,
useWebview: false,
),
).then((value) async {
Expand Down
1 change: 1 addition & 0 deletions lib/src/enums/o_auth_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum OAuthProvider {
tradeshiftBox(value: 'tradeshiftBox'),
twitch(value: 'twitch'),
wordpress(value: 'wordpress'),
x(value: 'x'),
yahoo(value: 'yahoo'),
yammer(value: 'yammer'),
yandex(value: 'yandex'),
Expand Down
6 changes: 6 additions & 0 deletions lib/src/models/log.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class Log implements Model {
/// API mode when event triggered.
final String mode;

/// User type who triggered the audit log. Possible values: user, admin, guest, keyProject, keyAccount, keyOrganization.
final String userType;

/// IP session in use when the session was created.
final String ip;

Expand Down Expand Up @@ -71,6 +74,7 @@ class Log implements Model {
required this.userEmail,
required this.userName,
required this.mode,
required this.userType,
required this.ip,
required this.time,
required this.osCode,
Expand All @@ -96,6 +100,7 @@ class Log implements Model {
userEmail: map['userEmail'].toString(),
userName: map['userName'].toString(),
mode: map['mode'].toString(),
userType: map['userType'].toString(),
ip: map['ip'].toString(),
time: map['time'].toString(),
osCode: map['osCode'].toString(),
Expand Down Expand Up @@ -123,6 +128,7 @@ class Log implements Model {
"userEmail": userEmail,
"userName": userName,
"mode": mode,
"userType": userType,
"ip": ip,
"time": time,
"osCode": osCode,
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: appwrite
version: 23.0.0
version: 23.1.0
description: Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API
homepage: https://appwrite.io
repository: https://github.com/appwrite/sdk-for-flutter
Expand All @@ -20,7 +20,7 @@ dependencies:
sdk: flutter
cookie_jar: ^4.0.8
device_info_plus: '>=11.5.0 <13.0.0'
flutter_web_auth_2: ^5.0.0-alpha.3
flutter_web_auth_2: ^5.0.0
http: '>=0.13.6 <2.0.0'
package_info_plus: '>=8.0.2 <10.0.0'
path_provider: ^2.1.4
Expand Down
10 changes: 6 additions & 4 deletions test/services/account_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,9 @@ void main() {

test('test method createMfaAuthenticator()', () async {
final Map<String, dynamic> data = {
'secret': '1',
'uri': '1',
'secret': '[SHARED_SECRET]',
'uri':
'otpauth://totp/appwrite:user@example.com?secret=[SHARED_SECRET]&issuer=appwrite',
};

when(client.call(
Expand All @@ -250,8 +251,9 @@ void main() {

test('test method createMFAAuthenticator()', () async {
final Map<String, dynamic> data = {
'secret': '1',
'uri': '1',
'secret': '[SHARED_SECRET]',
'uri':
'otpauth://totp/appwrite:user@example.com?secret=[SHARED_SECRET]&issuer=appwrite',
};

when(client.call(
Expand Down
2 changes: 2 additions & 0 deletions test/src/models/log_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ void main() {
userEmail: 'john@appwrite.io',
userName: 'John Doe',
mode: 'admin',
userType: 'user',
ip: '127.0.0.1',
time: '2020-10-15T06:38:00.000+00:00',
osCode: 'Mac',
Expand All @@ -36,6 +37,7 @@ void main() {
expect(result.userEmail, 'john@appwrite.io');
expect(result.userName, 'John Doe');
expect(result.mode, 'admin');
expect(result.userType, 'user');
expect(result.ip, '127.0.0.1');
expect(result.time, '2020-10-15T06:38:00.000+00:00');
expect(result.osCode, 'Mac');
Expand Down
10 changes: 6 additions & 4 deletions test/src/models/mfa_type_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ void main() {
group('MfaType', () {
test('model', () {
final model = MfaType(
secret: '1',
uri: '1',
secret: '[SHARED_SECRET]',
uri:
'otpauth://totp/appwrite:user@example.com?secret=[SHARED_SECRET]&issuer=appwrite',
);

final map = model.toMap();
final result = MfaType.fromMap(map);

expect(result.secret, '1');
expect(result.uri, '1');
expect(result.secret, '[SHARED_SECRET]');
expect(result.uri,
'otpauth://totp/appwrite:user@example.com?secret=[SHARED_SECRET]&issuer=appwrite');
});
});
}