From 953e0b1c4533a7ac886b17fac897be05df6119d4 Mon Sep 17 00:00:00 2001 From: ahmtydn Date: Fri, 19 Sep 2025 01:16:06 +0300 Subject: [PATCH 1/4] feat(user): Add bannedUntil property and isBanned method to User class --- packages/gotrue/lib/src/types/user.dart | 27 ++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/gotrue/lib/src/types/user.dart b/packages/gotrue/lib/src/types/user.dart index 5a680ad1e..eeca22937 100644 --- a/packages/gotrue/lib/src/types/user.dart +++ b/packages/gotrue/lib/src/types/user.dart @@ -27,6 +27,7 @@ class User { final List? identities; final List? factors; final bool isAnonymous; + final String? bannedUntil; const User({ required this.id, @@ -51,8 +52,24 @@ class User { this.identities, this.factors, this.isAnonymous = false, + this.bannedUntil, }); + /// Returns true if the user is currently banned + /// Compares the current UTC time with the bannedUntil timestamp + bool get isBanned { + if (bannedUntil == null) return false; + + try { + final banExpiration = DateTime.parse(bannedUntil!); + final now = DateTime.now().toUtc(); + return now.isBefore(banExpiration); + } catch (e) { + // If bannedUntil cannot be parsed, consider user not banned + return false; + } + } + /// Returns a `User` object from a map of json /// returns `null` if there is no `id` present static User? fromJson(Map json) { @@ -88,6 +105,7 @@ class User { ? List.from(json['factors']?.map((x) => Factor.fromJson(x))) : null, isAnonymous: json['is_anonymous'] ?? false, + bannedUntil: json['banned_until'], ); } @@ -115,12 +133,13 @@ class User { 'identities': identities?.map((identity) => identity.toJson()).toList(), 'factors': factors?.map((factor) => factor.toJson()).toList(), 'is_anonymous': isAnonymous, + 'banned_until': bannedUntil, }; } @override String toString() { - return 'User(id: $id, appMetadata: $appMetadata, userMetadata: $userMetadata, aud: $aud, confirmationSentAt: $confirmationSentAt, recoverySentAt: $recoverySentAt, emailChangeSentAt: $emailChangeSentAt, newEmail: $newEmail, invitedAt: $invitedAt, actionLink: $actionLink, email: $email, phone: $phone, createdAt: $createdAt, confirmedAt: $confirmedAt, emailConfirmedAt: $emailConfirmedAt, phoneConfirmedAt: $phoneConfirmedAt, lastSignInAt: $lastSignInAt, role: $role, updatedAt: $updatedAt, identities: $identities, factors: $factors, isAnonymous: $isAnonymous)'; + return 'User(id: $id, appMetadata: $appMetadata, userMetadata: $userMetadata, aud: $aud, confirmationSentAt: $confirmationSentAt, recoverySentAt: $recoverySentAt, emailChangeSentAt: $emailChangeSentAt, newEmail: $newEmail, invitedAt: $invitedAt, actionLink: $actionLink, email: $email, phone: $phone, createdAt: $createdAt, confirmedAt: $confirmedAt, emailConfirmedAt: $emailConfirmedAt, phoneConfirmedAt: $phoneConfirmedAt, lastSignInAt: $lastSignInAt, role: $role, updatedAt: $updatedAt, identities: $identities, factors: $factors, isAnonymous: $isAnonymous, bannedUntil: $bannedUntil, isBanned: $isBanned)'; } @override @@ -150,7 +169,8 @@ class User { other.updatedAt == updatedAt && collectionEquals(other.identities, identities) && collectionEquals(other.factors, factors) && - other.isAnonymous == isAnonymous; + other.isAnonymous == isAnonymous && + other.bannedUntil == bannedUntil; } @override @@ -176,7 +196,8 @@ class User { updatedAt.hashCode ^ identities.hashCode ^ factors.hashCode ^ - isAnonymous.hashCode; + isAnonymous.hashCode ^ + bannedUntil.hashCode; } } From 0fda2a3ecbe31228fa57585471b5f1cea971d107 Mon Sep 17 00:00:00 2001 From: ahmtydn Date: Fri, 19 Sep 2025 01:26:28 +0300 Subject: [PATCH 2/4] feat: Update dependencies to use git references for gotrue and supabase packages --- packages/supabase/pubspec.yaml | 7 ++++++- packages/supabase_flutter/pubspec.yaml | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 0435fa665..ee4b94460 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -10,7 +10,12 @@ environment: dependencies: functions_client: 2.4.4 - gotrue: 2.15.0 + gotrue: + git: + url: https://github.com/ahmtydn/supabase-flutter.git + ref: feat/banned-user-support + path: packages/gotrue + http: '>=0.13.5 <2.0.0' postgrest: 2.4.2 realtime_client: 2.5.2 diff --git a/packages/supabase_flutter/pubspec.yaml b/packages/supabase_flutter/pubspec.yaml index dba750184..e0eceb2ee 100644 --- a/packages/supabase_flutter/pubspec.yaml +++ b/packages/supabase_flutter/pubspec.yaml @@ -17,7 +17,11 @@ dependencies: sdk: flutter http: '>=0.13.4 <2.0.0' meta: ^1.7.0 - supabase: 2.9.1 + supabase: + git: + url: https://github.com/ahmtydn/supabase-flutter.git + ref: feat/banned-user-support + path: packages/supabase url_launcher: ^6.1.2 path_provider: ^2.0.0 shared_preferences: ^2.0.0 From ec8cf2bc4c6d841b3f5eff4351a7f5a07ee58b96 Mon Sep 17 00:00:00 2001 From: ahmtydn Date: Fri, 19 Sep 2025 01:37:28 +0300 Subject: [PATCH 3/4] Revert "feat: Update dependencies to use git references for gotrue and supabase packages" This reverts commit 0fda2a3ecbe31228fa57585471b5f1cea971d107. --- packages/supabase/pubspec.yaml | 7 +------ packages/supabase_flutter/pubspec.yaml | 6 +----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index ee4b94460..0435fa665 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -10,12 +10,7 @@ environment: dependencies: functions_client: 2.4.4 - gotrue: - git: - url: https://github.com/ahmtydn/supabase-flutter.git - ref: feat/banned-user-support - path: packages/gotrue - + gotrue: 2.15.0 http: '>=0.13.5 <2.0.0' postgrest: 2.4.2 realtime_client: 2.5.2 diff --git a/packages/supabase_flutter/pubspec.yaml b/packages/supabase_flutter/pubspec.yaml index e0eceb2ee..dba750184 100644 --- a/packages/supabase_flutter/pubspec.yaml +++ b/packages/supabase_flutter/pubspec.yaml @@ -17,11 +17,7 @@ dependencies: sdk: flutter http: '>=0.13.4 <2.0.0' meta: ^1.7.0 - supabase: - git: - url: https://github.com/ahmtydn/supabase-flutter.git - ref: feat/banned-user-support - path: packages/supabase + supabase: 2.9.1 url_launcher: ^6.1.2 path_provider: ^2.0.0 shared_preferences: ^2.0.0 From 2a96573f3530f7d59ecb1602858b5551531dcecd Mon Sep 17 00:00:00 2001 From: ahmtydn Date: Tue, 23 Sep 2025 00:46:52 +0300 Subject: [PATCH 4/4] fix(user): Simplify isBanned logic and improve date parsing --- packages/gotrue/lib/src/types/user.dart | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/gotrue/lib/src/types/user.dart b/packages/gotrue/lib/src/types/user.dart index eeca22937..846d98002 100644 --- a/packages/gotrue/lib/src/types/user.dart +++ b/packages/gotrue/lib/src/types/user.dart @@ -59,15 +59,10 @@ class User { /// Compares the current UTC time with the bannedUntil timestamp bool get isBanned { if (bannedUntil == null) return false; - - try { - final banExpiration = DateTime.parse(bannedUntil!); - final now = DateTime.now().toUtc(); - return now.isBefore(banExpiration); - } catch (e) { - // If bannedUntil cannot be parsed, consider user not banned - return false; - } + final banExpiration = DateTime.tryParse(bannedUntil!); + if (banExpiration == null) return false; + final now = DateTime.now().toUtc(); + return now.isBefore(banExpiration); } /// Returns a `User` object from a map of json @@ -99,7 +94,8 @@ class User { updatedAt: json['updated_at'], identities: json['identities'] != null ? List.from( - json['identities']?.map((x) => UserIdentity.fromMap(x))) + json['identities']?.map((x) => UserIdentity.fromMap(x)), + ) : null, factors: json['factors'] != null ? List.from(json['factors']?.map((x) => Factor.fromJson(x)))