235 lines
6.2 KiB
Dart
235 lines
6.2 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:helpers/helpers/print.dart';
|
|
import 'package:jwt_decoder/jwt_decoder.dart';
|
|
import 'package:rluv/global/store.dart';
|
|
|
|
import '../models/token.dart';
|
|
|
|
final tokenProvider = StateProvider<Token?>((ref) {
|
|
final jwt = ref.watch(jwtProvider);
|
|
printLime('Current token: $jwt');
|
|
if (jwt == null) return null;
|
|
try {
|
|
return Token.fromJson(JwtDecoder.decode(jwt));
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
});
|
|
|
|
final jwtProvider = StateNotifierProvider<_JwtNotifier, String?>((ref) {
|
|
final prefs = ref.watch(prefsProvider);
|
|
final jwt = prefs?.getString('jwt');
|
|
return _JwtNotifier(ref, jwt);
|
|
});
|
|
|
|
class _JwtNotifier extends StateNotifier<String?> {
|
|
_JwtNotifier(this.ref, String? jwt) : super(null) {
|
|
if (jwt != null) {
|
|
setToken(jwt);
|
|
}
|
|
}
|
|
|
|
final StateNotifierProviderRef ref;
|
|
|
|
void setToken(String jwt) {
|
|
state = jwt;
|
|
printCyan('Loaded jwt into client: $jwt');
|
|
ref.read(prefsProvider)?.setString('jwt', jwt);
|
|
}
|
|
|
|
void revokeToken() {
|
|
printCyan('jwt token revoked');
|
|
state = null;
|
|
ref.read(prefsProvider)?.remove('jwt');
|
|
}
|
|
}
|
|
|
|
final apiProvider = StateNotifierProvider<_ApiNotifier, Dio>((ref) {
|
|
return _ApiNotifier(ref, Dio());
|
|
});
|
|
|
|
class _ApiNotifier extends StateNotifier<Dio> {
|
|
_ApiNotifier(this.ref, this.dio) : super(dio) {
|
|
// dio.options.baseUrl = "https://fe7d-136-36-2-234.ngrok-free.app";
|
|
// dio.options.baseUrl = "http://localhost:8081/";
|
|
dio.options.baseUrl = "https://rluv.fosscat.com/";
|
|
dio.interceptors.addAll([
|
|
InterceptorsWrapper(onRequest:
|
|
(RequestOptions options, RequestInterceptorHandler handler) {
|
|
final jwt = ref.read(jwtProvider);
|
|
if (jwt != null) {
|
|
options.headers['token'] = jwt;
|
|
}
|
|
return handler.next(options);
|
|
}, onResponse: (Response response, ResponseInterceptorHandler handler) {
|
|
if (response.statusCode != null) {
|
|
if (response.statusCode == 200) {
|
|
try {
|
|
if ((response.data as Map<String, dynamic>)
|
|
.containsKey('success')) {
|
|
if (!response.data['success']) return handler.next(response);
|
|
}
|
|
if ((response.data as Map<String, dynamic>)
|
|
.containsKey('token')) {
|
|
final jwt = response.data['token'];
|
|
if (jwt != null) {
|
|
ref.read(jwtProvider.notifier).setToken(jwt);
|
|
// ref.read(tokenProvider.notifier).state =
|
|
// Token.fromJson(jwtData);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
printRed('Error in interceptor for token: $err');
|
|
return handler.next(response);
|
|
}
|
|
}
|
|
}
|
|
return handler.next(response);
|
|
}, onError: (DioException err, ErrorInterceptorHandler handler) {
|
|
if (err.response?.statusCode == 403) {
|
|
ref.read(jwtProvider.notifier).revokeToken();
|
|
}
|
|
}),
|
|
_LoggingInterceptor(),
|
|
]);
|
|
}
|
|
|
|
final Dio dio;
|
|
final StateNotifierProviderRef ref;
|
|
|
|
Future<Map<String, dynamic>?> get(String path) async {
|
|
try {
|
|
final res = await dio.get(path);
|
|
|
|
if (res.data != null) {
|
|
return res.data as Map<String, dynamic>;
|
|
}
|
|
return null;
|
|
} catch (err) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>?> put(
|
|
{required String path, Object? data}) async {
|
|
try {
|
|
final res = await dio.put(path, data: data);
|
|
|
|
if (res.data != null) {
|
|
return res.data as Map<String, dynamic>;
|
|
}
|
|
return null;
|
|
} catch (err) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>?> post(
|
|
{required String path, Object? data}) async {
|
|
try {
|
|
final res = await dio.post(path, data: data);
|
|
|
|
if (res.data != null) {
|
|
return res.data as Map<String, dynamic>;
|
|
}
|
|
return null;
|
|
} catch (err) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>?> delete(
|
|
{required String path, Object? data}) async {
|
|
try {
|
|
final res = await dio.delete(path, data: data);
|
|
|
|
if (res.data != null) {
|
|
return res.data as Map<String, dynamic>;
|
|
}
|
|
return null;
|
|
} catch (err) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
class _LoggingInterceptor extends Interceptor {
|
|
_LoggingInterceptor();
|
|
|
|
@override
|
|
Future onRequest(
|
|
RequestOptions options, RequestInterceptorHandler handler) async {
|
|
logPrint('///*** REQUEST ***\\\\\\');
|
|
printKV('URI', options.uri);
|
|
printKV('METHOD', options.method);
|
|
logPrint('HEADERS:');
|
|
options.headers.forEach((key, v) => printKV(' - $key', v));
|
|
logPrint('BODY:');
|
|
printJson(options.data);
|
|
|
|
return handler.next(options);
|
|
}
|
|
|
|
@override
|
|
void onError(DioException err, ErrorInterceptorHandler handler) {
|
|
printRed('///*** ERROR RESPONSE ***\\\\\\');
|
|
logPrint('URI: ${err.requestOptions.uri}');
|
|
if (err.response != null) {
|
|
logPrint('STATUS CODE: ${err.response?.statusCode?.toString()}');
|
|
}
|
|
logPrint('$err');
|
|
if (err.response != null) {
|
|
printKV('REDIRECT', err.response?.realUri ?? '');
|
|
logPrint('BODY:');
|
|
printJson(err.response?.data);
|
|
}
|
|
return handler.next(err);
|
|
}
|
|
|
|
@override
|
|
Future onResponse(
|
|
Response response, ResponseInterceptorHandler handler) async {
|
|
logPrint('///*** RESPONSE ***\\\\\\');
|
|
printKV('URI', response.requestOptions.uri);
|
|
printKV('STATUS CODE', response.statusCode ?? '');
|
|
// printKV('REDIRECT', response.isRedirect);
|
|
logPrint('BODY:');
|
|
printJson(response.data);
|
|
|
|
return handler.next(response);
|
|
}
|
|
|
|
void printKV(String key, Object v) {
|
|
if (kDebugMode) {
|
|
printOrange('$key: $v');
|
|
}
|
|
}
|
|
|
|
void printJson(dynamic s) {
|
|
try {
|
|
final data = (s as Map<String, dynamic>?);
|
|
if (kDebugMode) {
|
|
if (data == null) {
|
|
printAmber({});
|
|
return;
|
|
}
|
|
JsonEncoder encoder = const JsonEncoder.withIndent(' ');
|
|
String prettyprint = encoder.convert(s);
|
|
printAmber(prettyprint);
|
|
}
|
|
} catch (_) {
|
|
printAmber(s);
|
|
}
|
|
}
|
|
|
|
void logPrint(String s) {
|
|
if (kDebugMode) {
|
|
printOrange(s);
|
|
}
|
|
}
|
|
}
|