Redirect to onboarding on invalid token

This commit is contained in:
Juan Gilsanz Polo
2024-02-25 04:58:59 +01:00
parent bbfcec67cc
commit 3ea55dfaa4
10 changed files with 82 additions and 17 deletions

View File

@@ -4,9 +4,9 @@
/// To regenerate, run: `dart run slang` /// To regenerate, run: `dart run slang`
/// ///
/// Locales: 2 /// Locales: 2
/// Strings: 232 (116 per locale) /// Strings: 234 (117 per locale)
/// ///
/// Built on 2024-02-25 at 03:19 UTC /// Built on 2024-02-25 at 03:56 UTC
// coverage:ignore-file // coverage:ignore-file
// ignore_for_file: type=lint // ignore_for_file: type=lint
@@ -171,6 +171,7 @@ class _StringsGenericEn {
String get close => 'Close'; String get close => 'Close';
String get error => 'Error'; String get error => 'Error';
String get optional => 'Optional'; String get optional => 'Optional';
String get authTokenNotValid => 'Your authorization token is not valid anymore. Please, reauthenticate.';
} }
// Path: onboarding // Path: onboarding
@@ -463,6 +464,7 @@ class _StringsGenericEs implements _StringsGenericEn {
@override String get close => 'Cerrar'; @override String get close => 'Cerrar';
@override String get error => 'Error'; @override String get error => 'Error';
@override String get optional => 'Opcional'; @override String get optional => 'Opcional';
@override String get authTokenNotValid => 'Su token de autorización ya no es válido. Por favor, vuelva a autenticarse.';
} }
// Path: onboarding // Path: onboarding
@@ -721,6 +723,7 @@ extension on Translations {
case 'generic.close': return 'Close'; case 'generic.close': return 'Close';
case 'generic.error': return 'Error'; case 'generic.error': return 'Error';
case 'generic.optional': return 'Optional'; case 'generic.optional': return 'Optional';
case 'generic.authTokenNotValid': return 'Your authorization token is not valid anymore. Please, reauthenticate.';
case 'onboarding.title': return 'Welcome to Linkdy'; case 'onboarding.title': return 'Welcome to Linkdy';
case 'onboarding.subtitle': return 'An application to manage your bookmarks.'; case 'onboarding.subtitle': return 'An application to manage your bookmarks.';
case 'onboarding.start': return 'Start'; case 'onboarding.start': return 'Start';
@@ -845,6 +848,7 @@ extension on _StringsEs {
case 'generic.close': return 'Cerrar'; case 'generic.close': return 'Cerrar';
case 'generic.error': return 'Error'; case 'generic.error': return 'Error';
case 'generic.optional': return 'Opcional'; case 'generic.optional': return 'Opcional';
case 'generic.authTokenNotValid': return 'Su token de autorización ya no es válido. Por favor, vuelva a autenticarse.';
case 'onboarding.title': return 'Bienvenido a Linkdy'; case 'onboarding.title': return 'Bienvenido a Linkdy';
case 'onboarding.subtitle': return 'Una aplicación para gestionar tus enlaces favoritos.'; case 'onboarding.subtitle': return 'Una aplicación para gestionar tus enlaces favoritos.';
case 'onboarding.start': return 'Comenzar'; case 'onboarding.start': return 'Comenzar';

View File

@@ -6,7 +6,8 @@
"save": "Save", "save": "Save",
"close": "Close", "close": "Close",
"error": "Error", "error": "Error",
"optional": "Optional" "optional": "Optional",
"authTokenNotValid": "Your authorization token is not valid anymore. Please, reauthenticate."
}, },
"onboarding": { "onboarding": {
"title": "Welcome to Linkdy", "title": "Welcome to Linkdy",

View File

@@ -6,7 +6,8 @@
"save": "Guardar", "save": "Guardar",
"close": "Cerrar", "close": "Cerrar",
"error": "Error", "error": "Error",
"optional": "Opcional" "optional": "Opcional",
"authTokenNotValid": "Su token de autorización ya no es válido. Por favor, vuelva a autenticarse."
}, },
"onboarding": { "onboarding": {
"title": "Bienvenido a Linkdy", "title": "Bienvenido a Linkdy",

View File

@@ -1,8 +1,10 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:linkdy/providers/server_instances_provider.dart'; import 'package:linkdy/providers/server_instances_provider.dart';
import 'package:linkdy/providers/dio_interceptor.provider.dart';
import 'package:linkdy/services/api_client.dart'; import 'package:linkdy/services/api_client.dart';
import 'package:linkdy/utils/api_base_url.dart'; import 'package:linkdy/utils/api_base_url.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'api_client_provider.g.dart'; part 'api_client_provider.g.dart';
@@ -13,16 +15,17 @@ class ApiClient extends _$ApiClient {
final savedInstances = ref.watch(serverInstancesProvider); final savedInstances = ref.watch(serverInstancesProvider);
if (savedInstances.isNotEmpty) { if (savedInstances.isNotEmpty) {
final instance = savedInstances[0]; final instance = savedInstances[0];
return ApiClientService( final dio = Dio(
serverInstance: instance,
dioInstance: Dio(
BaseOptions( BaseOptions(
baseUrl: apiBaseUrl(instance), baseUrl: apiBaseUrl(instance),
headers: { headers: {
"Authorization": "Token ${instance.token}", "Authorization": "Token ${instance.token}",
}, },
), ),
), )..interceptors.add(ref.watch(dioInterceptorProvider));
return ApiClientService(
serverInstance: instance,
dioInstance: dio,
); );
} }
return null; return null;

View File

@@ -6,7 +6,7 @@ part of 'api_client_provider.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$apiClientHash() => r'd26f8058edfc47acd2e01f2a9bcbf64102b51212'; String _$apiClientHash() => r'81e911e24bda3baf158a7d583271c4467821b11f';
/// See also [ApiClient]. /// See also [ApiClient].
@ProviderFor(ApiClient) @ProviderFor(ApiClient)

View File

@@ -0,0 +1,31 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:linkdy/i18n/strings.g.dart';
import 'package:linkdy/providers/server_instances_provider.dart';
import 'package:linkdy/router/routes.dart';
import 'package:linkdy/utils/snackbar.dart';
import 'package:linkdy/router/paths.dart';
import 'package:linkdy/providers/api_client_provider.dart';
part 'dio_interceptor.provider.g.dart';
@Riverpod(keepAlive: true)
InterceptorsWrapper dioInterceptor(DioInterceptorRef ref) {
return InterceptorsWrapper(
onError: (error, handler) async {
if (error.response?.statusCode == 401) {
while (GoRouter.of(rootNavigatorKey.currentContext!).canPop() == true) {
GoRouter.of(rootNavigatorKey.currentContext!).pop();
}
GoRouter.of(rootNavigatorKey.currentContext!).pushReplacement(RoutesPaths.onboarding);
ref.read(apiClientProvider.notifier).disconnectApiClient();
ref.read(serverInstancesProvider.notifier).removeServerInstances();
showSnacbkar(label: t.generic.authTokenNotValid, color: Colors.red);
}
handler.next(error);
},
);
}

View File

@@ -0,0 +1,25 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'dio_interceptor.provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$dioInterceptorHash() => r'449d19df5bf143a7e0f92249d99b4d223b2468f3';
/// See also [dioInterceptor].
@ProviderFor(dioInterceptor)
final dioInterceptorProvider = Provider<InterceptorsWrapper>.internal(
dioInterceptor,
name: r'dioInterceptorProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$dioInterceptorHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef DioInterceptorRef = ProviderRef<InterceptorsWrapper>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@@ -5,6 +5,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:linkdy/screens/onboarding/model/connect.model.dart'; import 'package:linkdy/screens/onboarding/model/connect.model.dart';
import 'package:linkdy/providers/dio_interceptor.provider.dart';
import 'package:linkdy/providers/server_instances_provider.dart'; import 'package:linkdy/providers/server_instances_provider.dart';
import 'package:linkdy/utils/api_base_url.dart'; import 'package:linkdy/utils/api_base_url.dart';
import 'package:linkdy/i18n/strings.g.dart'; import 'package:linkdy/i18n/strings.g.dart';
@@ -102,7 +103,7 @@ FutureOr<bool> connectToServer(ConnectToServerRef ref) async {
"Authorization": "Token ${serverInstance.token}", "Authorization": "Token ${serverInstance.token}",
}, },
), ),
), )..interceptors.add(ref.watch(dioInterceptorProvider)),
); );
final processModal = ProcessModal(); final processModal = ProcessModal();

View File

@@ -6,7 +6,7 @@ part of 'connect.provider.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$connectToServerHash() => r'78c2abcf7949674db5961ef644275d27c73bb000'; String _$connectToServerHash() => r'19a35bf2985d18662ce0b7ece8284cb4e83f1529';
/// See also [connectToServer]. /// See also [connectToServer].
@ProviderFor(connectToServer) @ProviderFor(connectToServer)

View File

@@ -64,7 +64,6 @@ class TagBookmarksScreenState extends ConsumerState<TagBookmarksScreen> {
return false; return false;
} }
print(provider.maxNumber);
return Scaffold( return Scaffold(
body: NestedScrollView( body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [ headerSliverBuilder: (context, innerBoxIsScrolled) => [