onNavigation method
clients will call resolver.next(true --> default)
to continue
navigation or resolver.next(false)
to abort navigation
example
Implementation
@override
void onNavigation(NavigationResolver resolver, StackRouter router) async {
// final authBloc = await GetIt.instance.get<AuthenticationBasicBloc>();
// the navigation is paused until resolver.next() is called with either
// true to resume/continue navigation or false to abort navigation
if (authBloc.state.authenticated && !authBloc.state.authenticationData!.expired) {
// if user is authenticated we continue
return resolver.next(true);
// lets check if the session has expired
} else if (authBloc.state.authenticated && authBloc.state.authenticationData!.expired) {
// let's try to force a fetch user so it triggers a refresh session if necessary
authBloc.fetchUser();
// if the user configured the refreshApiEndpoint, lets wait for it to return a refreshed session or failure
if (authBloc.config.refreshTokenAPIendpoint != null || authBloc.config.customRefreshTokenCallback != null) {
final result = await authBloc.eventsReplay
.where(
(event) {
return event is RefreshTokenSuccess || event is RefreshTokenFailure;
},
)
.map((event) {
return true;
})
.timeout(const Duration(seconds: 10))
// lets give it a moment so the bloc/service set the new session on state
.delay(const Duration(milliseconds: 200))
// do nothing on error we still be checking if session have changed
.onErrorReturn(false)
.first;
if ((authBloc.state.authenticationData?.expired ?? true)) {
// lets try to refresh
resolver.next(false);
return onUnauthorized?.call(router);
} else {
return resolver.next(true);
}
} else {
resolver.next(false);
return onUnauthorized?.call(router);
}
} else {
resolver.next(false);
// we redirect the user to our login page
return onUnauthorized?.call(router);
}
}