♻️ Replace storage token engine to prevent some platform specific issue
This commit is contained in:
@ -1,11 +1,12 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dio_smart_retry/dio_smart_retry.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:surface/providers/adapters/sn_network_universal.dart';
|
||||
import 'package:synchronized/synchronized.dart';
|
||||
|
||||
const kAtkStoreKey = 'nex_user_atk';
|
||||
const kRtkStoreKey = 'nex_user_rtk';
|
||||
@ -23,7 +24,6 @@ class SnNetworkProvider {
|
||||
late Dio client;
|
||||
|
||||
late final SharedPreferences _prefs;
|
||||
late final FlutterSecureStorage _storage = FlutterSecureStorage();
|
||||
|
||||
SnNetworkProvider() {
|
||||
client = Dio();
|
||||
@ -62,9 +62,19 @@ class SnNetworkProvider {
|
||||
});
|
||||
}
|
||||
|
||||
final tkLock = Lock();
|
||||
|
||||
Completer<String?>? _refreshCompleter;
|
||||
|
||||
Future<String?> getFreshAtk() async {
|
||||
if (_refreshCompleter != null) {
|
||||
return await _refreshCompleter!.future;
|
||||
} else {
|
||||
_refreshCompleter = Completer<String?>();
|
||||
}
|
||||
|
||||
try {
|
||||
var atk = await _storage.read(key: kAtkStoreKey);
|
||||
var atk = _prefs.getString(kAtkStoreKey);
|
||||
if (atk != null) {
|
||||
final atkParts = atk.split('.');
|
||||
if (atkParts.length != 3) {
|
||||
@ -94,13 +104,18 @@ class SnNetworkProvider {
|
||||
}
|
||||
|
||||
if (atk != null) {
|
||||
_refreshCompleter!.complete(atk);
|
||||
return atk;
|
||||
} else {
|
||||
log('Access token refresh failed...');
|
||||
_refreshCompleter!.complete(null);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
log('Failed to authenticate user: $err');
|
||||
_refreshCompleter!.completeError(err);
|
||||
} finally {
|
||||
_refreshCompleter = null;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -111,22 +126,18 @@ class SnNetworkProvider {
|
||||
return '${client.options.baseUrl}/cgi/uc/attachments/$ky';
|
||||
}
|
||||
|
||||
Future<void> setTokenPair(String atk, String rtk) async {
|
||||
await Future.wait([
|
||||
_storage.write(key: kAtkStoreKey, value: atk),
|
||||
_storage.write(key: kRtkStoreKey, value: rtk),
|
||||
]);
|
||||
void setTokenPair(String atk, String rtk) {
|
||||
_prefs.setString(kAtkStoreKey, atk);
|
||||
_prefs.setString(kRtkStoreKey, rtk);
|
||||
}
|
||||
|
||||
Future<void> clearTokenPair() async {
|
||||
await Future.wait([
|
||||
_storage.delete(key: kAtkStoreKey),
|
||||
_storage.delete(key: kRtkStoreKey),
|
||||
]);
|
||||
void clearTokenPair() {
|
||||
_prefs.remove(kAtkStoreKey);
|
||||
_prefs.remove(kRtkStoreKey);
|
||||
}
|
||||
|
||||
Future<String?> refreshToken() async {
|
||||
final rtk = await _storage.read(key: kRtkStoreKey);
|
||||
final rtk = _prefs.getString(kRtkStoreKey);
|
||||
if (rtk == null) return null;
|
||||
|
||||
final dio = Dio();
|
||||
@ -139,7 +150,7 @@ class SnNetworkProvider {
|
||||
|
||||
final atk = resp.data['access_token'];
|
||||
final nRtk = resp.data['refresh_token'];
|
||||
await setTokenPair(atk, nRtk);
|
||||
setTokenPair(atk, nRtk);
|
||||
|
||||
return atk;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/types/account.dart';
|
||||
|
||||
@ -11,14 +11,17 @@ class UserProvider extends ChangeNotifier {
|
||||
SnAccount? user;
|
||||
|
||||
late final SnNetworkProvider _sn;
|
||||
late final FlutterSecureStorage _storage = FlutterSecureStorage();
|
||||
|
||||
Future<String?> get atk => _storage.read(key: kAtkStoreKey);
|
||||
Future<String?> get atk async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString(kAtkStoreKey);
|
||||
}
|
||||
|
||||
UserProvider(BuildContext context) {
|
||||
_sn = context.read<SnNetworkProvider>();
|
||||
|
||||
_storage.read(key: kAtkStoreKey).then((value) {
|
||||
SharedPreferences.getInstance().then((prefs) {
|
||||
final value = prefs.getString(kAtkStoreKey);
|
||||
isAuthorized = value != null;
|
||||
notifyListeners();
|
||||
refreshUser().then((value) {
|
||||
@ -41,7 +44,7 @@ class UserProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void logoutUser() async {
|
||||
await _sn.clearTokenPair();
|
||||
_sn.clearTokenPair();
|
||||
isAuthorized = false;
|
||||
user = null;
|
||||
notifyListeners();
|
||||
|
@ -151,7 +151,7 @@ class _LoginCheckScreenState extends State<_LoginCheckScreen> {
|
||||
});
|
||||
final atk = tokenResp.data['access_token'];
|
||||
final rtk = tokenResp.data['refresh_token'];
|
||||
await sn.setTokenPair(atk, rtk);
|
||||
sn.setTokenPair(atk, rtk);
|
||||
if (!mounted) return;
|
||||
final user = context.read<UserProvider>();
|
||||
final userinfo = await user.refreshUser();
|
||||
|
@ -74,6 +74,15 @@ class _PostSearchScreenState extends State<PostSearchScreen> {
|
||||
if (mounted) setState(() => _isBusy = false);
|
||||
}
|
||||
|
||||
void _showAdvancedSearchTune() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => Column(
|
||||
children: [],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const labelShadows = <Shadow>[
|
||||
@ -87,11 +96,17 @@ class _PostSearchScreenState extends State<PostSearchScreen> {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('screenPostSearch').tr(),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Symbols.tune),
|
||||
onPressed: _showAdvancedSearchTune,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
InfiniteList(
|
||||
padding: const EdgeInsets.only(top: 96),
|
||||
padding: const EdgeInsets.only(top: 100),
|
||||
itemCount: _posts.length,
|
||||
isLoading: _isBusy,
|
||||
hasReachedMax: _postCount != null && _posts.length >= _postCount!,
|
||||
|
Reference in New Issue
Block a user