Keep web account sessions in memory only
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
abstract interface class SessionTokenStore {
|
||||
@@ -25,3 +26,21 @@ class SecureSessionTokenStore implements SessionTokenStore {
|
||||
@override
|
||||
Future<void> delete() => _storage.delete(key: _key);
|
||||
}
|
||||
|
||||
/// Keeps browser sessions in memory only; a reload or tab close signs out.
|
||||
class EphemeralSessionTokenStore implements SessionTokenStore {
|
||||
String? _token;
|
||||
|
||||
@override
|
||||
Future<String?> read() async => _token;
|
||||
|
||||
@override
|
||||
Future<void> write(String token) async => _token = token;
|
||||
|
||||
@override
|
||||
Future<void> delete() async => _token = null;
|
||||
}
|
||||
|
||||
SessionTokenStore createDefaultSessionTokenStore() => kIsWeb
|
||||
? EphemeralSessionTokenStore()
|
||||
: SecureSessionTokenStore();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:file_selector/file_selector.dart';
|
||||
@@ -91,10 +91,12 @@ class AgentToolStep {
|
||||
class ApiRepository {
|
||||
ApiRepository({required String baseUrl, SessionTokenStore? sessionTokenStore})
|
||||
: _baseUrl = baseUrl,
|
||||
_sessionTokenStore = sessionTokenStore ?? SecureSessionTokenStore();
|
||||
_sessionTokenStore =
|
||||
sessionTokenStore ?? createDefaultSessionTokenStore();
|
||||
|
||||
String _baseUrl;
|
||||
final SessionTokenStore _sessionTokenStore;
|
||||
bool get accountSessionPersists => !kIsWeb;
|
||||
String? _accessToken;
|
||||
Future<String>? _loadingLocalSession;
|
||||
Future<void>? _restoringSession;
|
||||
|
||||
@@ -634,9 +634,13 @@ class _ChatPageState extends State<ChatPage> {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
credentials.$1
|
||||
? 'تم إنشاء الحساب وتخزين الجلسة بأمان.'
|
||||
: 'تم تسجيل الدخول وتخزين الجلسة بأمان.',
|
||||
api.accountSessionPersists
|
||||
? credentials.$1
|
||||
? 'تم إنشاء الحساب وتخزين الجلسة بأمان.'
|
||||
: 'تم تسجيل الدخول وتخزين الجلسة بأمان.'
|
||||
: credentials.$1
|
||||
? 'تم إنشاء الحساب. جلسة الويب مؤقتة وستنتهي عند إعادة تحميل الصفحة.'
|
||||
: 'تم تسجيل الدخول. جلسة الويب مؤقتة وستنتهي عند إعادة تحميل الصفحة.',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_app/core/auth/session_token_store.dart';
|
||||
|
||||
void main() {
|
||||
group('EphemeralSessionTokenStore', () {
|
||||
test('keeps the token available only in the running app instance', () async {
|
||||
final store = EphemeralSessionTokenStore();
|
||||
|
||||
expect(await store.read(), isNull);
|
||||
await store.write('test-session-token');
|
||||
expect(await store.read(), 'test-session-token');
|
||||
});
|
||||
|
||||
test('deletes the in-memory token on logout', () async {
|
||||
final store = EphemeralSessionTokenStore();
|
||||
await store.write('test-session-token');
|
||||
|
||||
await store.delete();
|
||||
|
||||
expect(await store.read(), isNull);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user