diff --git a/app/lib/core/providers/router.dart b/app/lib/core/providers/router.dart
index 4835d0db..15d1eb5a 100644
--- a/app/lib/core/providers/router.dart
+++ b/app/lib/core/providers/router.dart
@@ -17,10 +17,13 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
+import 'dart:async';
+
import 'package:go_router/go_router.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:weblibre/core/providers/app_state.dart';
import 'package:weblibre/core/routing/routes.dart';
+import 'package:weblibre/features/user/domain/providers/profile_auth.dart';
import 'package:weblibre/features/user/domain/repositories/onboarding.dart';
part 'router.g.dart';
@@ -30,6 +33,7 @@ Future router(Ref ref) async {
ref.watch(appStateKeyProvider); //Rebuild router on key changes
final onboardingRepository = ref.read(onboardingRepositoryProvider.notifier);
+ unawaited(ref.read(profileAuthStateProvider.notifier).bootstrapFromProfile());
String? initialLocation;
@@ -46,10 +50,32 @@ Future router(Ref ref) async {
initialLocation = route.location;
}
+ final profileAuthRefreshListenable = ref.watch(profileAuthProvider);
+
return GoRouter(
debugLogDiagnostics: true,
routes: $appRoutes,
- initialLocation: initialLocation ?? const BrowserRoute().location,
+ initialLocation: initialLocation ?? const LockRoute().location,
+ refreshListenable: profileAuthRefreshListenable,
+ redirect: (context, state) {
+ final authenticated = ref.read(profileAuthStateProvider);
+ final currentTopRouteName = state.topRoute?.name;
+ final isOnLockRoute = currentTopRouteName == LockRoute.name;
+ final isOnOnboarding = currentTopRouteName == OnboardingRoute.name;
+
+ // Don't redirect during onboarding
+ if (isOnOnboarding) return null;
+
+ if (!authenticated && !isOnLockRoute) {
+ return const LockRoute().location;
+ }
+
+ if (authenticated && isOnLockRoute) {
+ return const BrowserRoute().location;
+ }
+
+ return null;
+ },
);
}
diff --git a/app/lib/core/providers/router.g.dart b/app/lib/core/providers/router.g.dart
index be3a5bca..efaaf06d 100644
--- a/app/lib/core/providers/router.g.dart
+++ b/app/lib/core/providers/router.g.dart
@@ -41,7 +41,7 @@ final class RouterProvider
}
}
-String _$routerHash() => r'cbaa7e982114942303574f9573f4a75b79955583';
+String _$routerHash() => r'4402ca2d7061945c395f3963d6bde29be8999f96';
@ProviderFor(CurrentTopRoute)
final currentTopRouteProvider = CurrentTopRouteProvider._();
diff --git a/app/lib/core/routing/routes.dart b/app/lib/core/routing/routes.dart
index 18f9a702..624c415e 100644
--- a/app/lib/core/routing/routes.dart
+++ b/app/lib/core/routing/routes.dart
@@ -77,6 +77,7 @@ import 'package:weblibre/features/user/domain/presentation/screens/profile_backu
import 'package:weblibre/features/user/domain/presentation/screens/profile_edit.dart';
import 'package:weblibre/features/user/domain/presentation/screens/profile_list.dart';
import 'package:weblibre/features/user/domain/presentation/screens/profile_restore.dart';
+import 'package:weblibre/features/user/domain/presentation/widgets/auth_gate.dart';
import 'package:weblibre/features/web_feed/presentation/add_feed_dialog.dart';
import 'package:weblibre/features/web_feed/presentation/screens/feed_article.dart';
import 'package:weblibre/features/web_feed/presentation/screens/feed_article_list.dart';
@@ -103,10 +104,13 @@ class AboutRoute extends GoRouteData with $AboutRoute {
}
@TypedGoRoute(
- name: 'OnboardingRoute',
- path: '/onboarding/:currentRevision/:targetRevision',
+ name: OnboardingRoute.name,
+ path: '${OnboardingRoute.pathPrefix}/:currentRevision/:targetRevision',
)
class OnboardingRoute extends GoRouteData with $OnboardingRoute {
+ static const name = 'OnboardingRoute';
+ static const pathPrefix = '/onboarding';
+
final int currentRevision;
final int targetRevision;
@@ -123,3 +127,16 @@ class OnboardingRoute extends GoRouteData with $OnboardingRoute {
);
}
}
+
+@TypedGoRoute(name: LockRoute.name, path: LockRoute.path)
+class LockRoute extends GoRouteData with $LockRoute {
+ static const name = 'LockRoute';
+ static const path = '/lock';
+
+ const LockRoute();
+
+ @override
+ Widget build(BuildContext context, GoRouterState state) {
+ return const LockScreen();
+ }
+}
diff --git a/app/lib/core/routing/routes.g.dart b/app/lib/core/routing/routes.g.dart
index 54037de7..4e425d79 100644
--- a/app/lib/core/routing/routes.g.dart
+++ b/app/lib/core/routing/routes.g.dart
@@ -9,6 +9,7 @@ part of 'routes.dart';
List get $appRoutes => [
$aboutRoute,
$onboardingRoute,
+ $lockRoute,
$bangMenuRoute,
$bookmarksRoute,
$browserRoute,
@@ -78,6 +79,32 @@ mixin $OnboardingRoute on GoRouteData {
void replace(BuildContext context) => context.replace(location);
}
+RouteBase get $lockRoute => GoRouteData.$route(
+ path: '/lock',
+ name: 'LockRoute',
+ factory: $LockRoute._fromState,
+);
+
+mixin $LockRoute on GoRouteData {
+ static LockRoute _fromState(GoRouterState state) => const LockRoute();
+
+ @override
+ String get location => GoRouteData.$location('/lock');
+
+ @override
+ void go(BuildContext context) => context.go(location);
+
+ @override
+ Future push(BuildContext context) => context.push(location);
+
+ @override
+ void pushReplacement(BuildContext context) =>
+ context.pushReplacement(location);
+
+ @override
+ void replace(BuildContext context) => context.replace(location);
+}
+
RouteBase get $bangMenuRoute => GoRouteData.$route(
path: '/bangs',
name: 'BangRoute',
diff --git a/app/lib/domain/entities/profile.dart b/app/lib/domain/entities/profile.dart
index 37014b32..8f2fdaac 100644
--- a/app/lib/domain/entities/profile.dart
+++ b/app/lib/domain/entities/profile.dart
@@ -22,6 +22,7 @@ import 'package:fast_equatable/fast_equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:uuid/uuid_value.dart';
import 'package:weblibre/core/uuid.dart';
+import 'package:weblibre/features/user/data/models/auth_settings.dart';
part 'profile.g.dart';
@@ -31,19 +32,31 @@ class Profile with FastEquatable {
@CopyWithField(immutable: true)
final String id;
final String name;
+ final AuthSettings authSettings;
late final uuidValue = UuidValue.fromString(id);
static String getNewProfileId() => uuid.v7();
- Profile({required this.id, required this.name});
+ Profile({
+ required this.id,
+ required this.name,
+ AuthSettings? authSettings,
+ }) : authSettings = authSettings ?? AuthSettings.withDefaults();
- factory Profile.create({required String name}) {
- return Profile(id: getNewProfileId(), name: name);
+ factory Profile.create({
+ required String name,
+ AuthSettings? authSettings,
+ }) {
+ return Profile(
+ id: getNewProfileId(),
+ name: name,
+ authSettings: authSettings,
+ );
}
@override
- List