-
Notifications
You must be signed in to change notification settings - Fork 43
/
async_auth_store.dart
109 lines (90 loc) · 2.72 KB
/
async_auth_store.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import "dart:convert";
import "auth_store.dart";
import "dtos/admin_model.dart";
import "dtos/record_model.dart";
import "sync_queue.dart";
typedef SaveFunc = Future<void> Function(String data);
typedef ClearFunc = Future<void> Function();
/// AsyncAuthStore is a pluggable AuthStore implementation that
/// could be used with any external async persistent layer
/// (shared_preferences, hive, local file, etc.).
///
/// Below is an example using `SharedPreferences`:
///
/// ```dart
/// final prefs = await SharedPreferences.getInstance();
///
/// final store = AsyncAuthStore(
/// save: (String data) async => prefs.setString('pb_auth', data),
/// initial: prefs.getString('pb_auth'),
/// );
///
/// final pb = PocketBase('http://example.com', authStore: store);
/// ```
class AsyncAuthStore extends AuthStore {
/// Async function that is called every time when the auth
/// store state needs to be persisted.
late final SaveFunc saveFunc;
/// An optional async function that is called every time when
/// the auth store needs to be cleared.
///
/// If not explicitly set, `saveFunc` with empty data will be used.
late final ClearFunc? clearFunc;
// encoded data keys
final String _tokenKey = "token";
final String _modelKey = "model";
AsyncAuthStore({
required SaveFunc save,
String? initial, // initial data to load into the store
ClearFunc? clear,
}) {
saveFunc = save;
clearFunc = clear;
_loadInitial(initial);
}
final _queue = SyncQueue();
@override
void save(
String newToken,
dynamic /* RecordModel|AdminModel|null */ newModel,
) {
super.save(newToken, newModel);
final encoded = jsonEncode({_tokenKey: token, _modelKey: model});
_queue.enqueue(() => saveFunc(encoded));
}
@override
void clear() {
super.clear();
if (clearFunc == null) {
_queue.enqueue(() => saveFunc(""));
} else {
_queue.enqueue(() => clearFunc!());
}
}
void _loadInitial(String? initial) {
if (initial == null || initial.isEmpty) {
return;
}
var decoded = <String, dynamic>{};
try {
final raw = jsonDecode(initial);
if (raw is Map<String, dynamic>) {
decoded = raw;
}
} catch (_) {
return;
}
final token = decoded[_tokenKey] as String? ?? "";
final rawModel = decoded[_modelKey] as Map<String, dynamic>? ?? {};
dynamic model;
if (rawModel.containsKey("collectionId") ||
rawModel.containsKey("collectionName") ||
rawModel.containsKey("verified") ||
rawModel.containsKey("emailVisibility")) {
model = RecordModel.fromJson(rawModel);
} else if (rawModel.containsKey("id")) {
model = AdminModel.fromJson(rawModel);
}
save(token, model);
}
}