Improve guest auth and reset flow#3477
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR refactors the mobile app's authentication session handling and password reset flow. Password reset validation shifts from 5-digit email-dependent pins to 6-digit codes validated independently. Auth bloc now emits ChangesAuth Flow and Password Reset Refactor
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/mobile/lib/src/app/auth/pages/password_reset/password_reset.dart (1)
27-38:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winDispose of TextEditingControllers before re-instantiation to prevent resource leaks.
The field-level initialization creates controller instances that are immediately replaced in
initState()without being disposed. This leaks resources. Initialize them only ininitState()by removing the field-level assignment.Proposed fix
- late TextEditingController passwordConfirmController = - TextEditingController(); - late TextEditingController passwordController = TextEditingController(); + late final TextEditingController passwordConfirmController; + late final TextEditingController passwordController; late GlobalKey<FormState> formKey = GlobalKey<FormState>(); bool _isPasswordVisible = false; bool _isConfirmPasswordVisible = false; `@override` void initState() { super.initState(); passwordConfirmController = TextEditingController(); passwordController = TextEditingController();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/lib/src/app/auth/pages/password_reset/password_reset.dart` around lines 27 - 38, The TextEditingController fields passwordConfirmController and passwordController are being instantiated at field declaration and then reassigned in initState, leaking resources; remove the field-level initializers so the controllers are only created inside initState, and implement dispose to call passwordConfirmController.dispose() and passwordController.dispose(); update the class methods (initState and add a dispose override) to ensure controllers are created once and properly disposed to prevent leaks.
🧹 Nitpick comments (2)
src/mobile/test/widget_test.dart (1)
151-151: ⚡ Quick winTighten the
MaterialAppassertion to avoid false positives.Using
findsWidgetshere will still pass if multipleMaterialApproots are introduced accidentally. PreferfindsOneWidgetfor a stricter regression signal.Suggested change
- expect(find.byType(MaterialApp), findsWidgets); + expect(find.byType(MaterialApp), findsOneWidget);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/test/widget_test.dart` at line 151, The assertion using expect(find.byType(MaterialApp), findsWidgets) is too loose; update the test in widget_test.dart to assert exactly one MaterialApp by replacing findsWidgets with findsOneWidget so the test fails if multiple MaterialApp roots are present (locate the expect call using find.byType(MaterialApp) and change the matcher to findsOneWidget).src/mobile/test/app/shared/services/cache_manager_test.dart (1)
104-107: ⚡ Quick winKeep an explicit map cast in the deserialization converter.
(json) => jsonrelaxes this test and won’t verify the expectedMap<String, dynamic>shape as strictly as before.Suggested change
final restored = CachedData<Map<String, dynamic>>.fromJson( jsonData, - (json) => json, + (json) => json as Map<String, dynamic>, );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mobile/test/app/shared/services/cache_manager_test.dart` around lines 104 - 107, The test currently uses a lax converter `(json) => json` when calling `CachedData<Map<String, dynamic>>.fromJson`, which fails to enforce the expected Map<String, dynamic> shape; replace the converter with an explicit cast such as `(json) => Map<String, dynamic>.from(json as Map)` or `(json) => (json as Map).cast<String, dynamic>()` so the deserializer for `CachedData.fromJson` is validated against a proper Map<String, dynamic>.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/mobile/lib/src/app/auth/bloc/auth_bloc.dart`:
- Around line 73-76: When AuthHelper.refreshTokenIfNeeded() throws, clear any
persisted auth state before emitting GuestUser() to avoid repeated refresh
failures with stale tokens; update the catch block in auth_bloc.dart to call the
project's auth-clear routine (e.g., AuthHelper.clearAuthData() or
AuthRepository.clearAuthData()/clear()) to remove stored tokens and user info,
handle/ignore any error from that clear operation, then emit(GuestUser()).
In `@src/mobile/lib/src/app/dashboard/pages/dashboard_page.dart`:
- Around line 41-43: The initState in DashboardPage is dispatching LoadUser()
redundantly: locate the initState where you call context.read<AuthBloc>().state
and context.read<UserBloc>().add(LoadUser()) and remove that dispatch so
LoadUser is only triggered by Decider on AuthLoaded; if you need a safety guard,
replace the direct add with a no-op or a conditional that checks a
UserBloc-specific flag (e.g., userLoaded boolean/event) before calling add to
avoid duplicating Decider-triggered loads.
---
Outside diff comments:
In `@src/mobile/lib/src/app/auth/pages/password_reset/password_reset.dart`:
- Around line 27-38: The TextEditingController fields passwordConfirmController
and passwordController are being instantiated at field declaration and then
reassigned in initState, leaking resources; remove the field-level initializers
so the controllers are only created inside initState, and implement dispose to
call passwordConfirmController.dispose() and passwordController.dispose();
update the class methods (initState and add a dispose override) to ensure
controllers are created once and properly disposed to prevent leaks.
---
Nitpick comments:
In `@src/mobile/test/app/shared/services/cache_manager_test.dart`:
- Around line 104-107: The test currently uses a lax converter `(json) => json`
when calling `CachedData<Map<String, dynamic>>.fromJson`, which fails to enforce
the expected Map<String, dynamic> shape; replace the converter with an explicit
cast such as `(json) => Map<String, dynamic>.from(json as Map)` or `(json) =>
(json as Map).cast<String, dynamic>()` so the deserializer for
`CachedData.fromJson` is validated against a proper Map<String, dynamic>.
In `@src/mobile/test/widget_test.dart`:
- Line 151: The assertion using expect(find.byType(MaterialApp), findsWidgets)
is too loose; update the test in widget_test.dart to assert exactly one
MaterialApp by replacing findsWidgets with findsOneWidget so the test fails if
multiple MaterialApp roots are present (locate the expect call using
find.byType(MaterialApp) and change the matcher to findsOneWidget).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7786ec9a-104a-4412-802a-840de87a72ee
📒 Files selected for processing (11)
src/mobile/lib/main.dartsrc/mobile/lib/src/app/auth/bloc/ForgotPasswordBloc/forgot_password_bloc.dartsrc/mobile/lib/src/app/auth/bloc/auth_bloc.dartsrc/mobile/lib/src/app/auth/pages/password_reset/password_reset.dartsrc/mobile/lib/src/app/auth/pages/password_reset/reset_link_sent.dartsrc/mobile/lib/src/app/auth/repository/auth_repository.dartsrc/mobile/lib/src/app/auth/repository/auth_repository_impl.dartsrc/mobile/lib/src/app/dashboard/pages/dashboard_page.dartsrc/mobile/test/app/dashboard/widgets/nearby_view_test.dartsrc/mobile/test/app/shared/services/cache_manager_test.dartsrc/mobile/test/widget_test.dart
Summary by CodeRabbit
Release Notes
Bug Fixes
Improvements