jazz-react-native 0.9.23 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +22 -0
- package/dist/ReactNativeContextManager.js +38 -0
- package/dist/ReactNativeContextManager.js.map +1 -0
- package/dist/auth/DemoAuthUI.js +45 -101
- package/dist/auth/DemoAuthUI.js.map +1 -1
- package/dist/auth/auth.js +1 -0
- package/dist/auth/auth.js.map +1 -1
- package/dist/hooks.js +1 -1
- package/dist/hooks.js.map +1 -1
- package/dist/platform.js +120 -40
- package/dist/platform.js.map +1 -1
- package/dist/provider.js +39 -64
- package/dist/provider.js.map +1 -1
- package/package.json +6 -6
- package/src/ReactNativeContextManager.ts +70 -0
- package/src/auth/DemoAuthUI.tsx +71 -165
- package/src/auth/auth.ts +1 -0
- package/src/hooks.tsx +9 -1
- package/src/platform.ts +161 -86
- package/src/provider.tsx +66 -89
- package/dist/auth/DemoAuthMethod.js +0 -182
- package/dist/auth/DemoAuthMethod.js.map +0 -1
- package/dist/createWebSocketPeerWithReconnection.js +0 -58
- package/dist/createWebSocketPeerWithReconnection.js.map +0 -1
- package/dist/tests/DemoAuthMethod.test.js +0 -207
- package/dist/tests/DemoAuthMethod.test.js.map +0 -1
- package/dist/tests/createWebSocketPeerWithReconnection.test.js +0 -106
- package/dist/tests/createWebSocketPeerWithReconnection.test.js.map +0 -1
- package/src/auth/DemoAuthMethod.ts +0 -259
- package/src/createWebSocketPeerWithReconnection.ts +0 -79
- package/src/tests/DemoAuthMethod.test.ts +0 -309
- package/src/tests/createWebSocketPeerWithReconnection.test.ts +0 -163
package/src/platform.ts
CHANGED
@@ -2,79 +2,51 @@ import { SQLiteStorage } from "cojson-storage-rn-sqlite";
|
|
2
2
|
import {
|
3
3
|
Account,
|
4
4
|
AgentID,
|
5
|
-
|
6
|
-
|
5
|
+
AuthCredentials,
|
6
|
+
AuthSecretStorage,
|
7
7
|
CoValue,
|
8
8
|
CoValueClass,
|
9
9
|
CryptoProvider,
|
10
10
|
ID,
|
11
|
+
NewAccountProps,
|
11
12
|
SessionID,
|
13
|
+
SyncConfig,
|
12
14
|
createInviteLink as baseCreateInviteLink,
|
15
|
+
createAnonymousJazzContext,
|
13
16
|
createJazzContext,
|
14
17
|
} from "jazz-tools";
|
15
18
|
|
16
|
-
import
|
17
|
-
|
18
|
-
export { RNDemoAuth } from "./auth/DemoAuthMethod.js";
|
19
|
+
import NetInfo from "@react-native-community/netinfo";
|
20
|
+
import { LocalNode, Peer, RawAccountID } from "cojson";
|
19
21
|
|
22
|
+
import { WebSocketPeerWithReconnection } from "cojson-transport-ws";
|
20
23
|
import { PureJSCrypto } from "cojson/native";
|
21
|
-
import { createWebSocketPeerWithReconnection } from "./createWebSocketPeerWithReconnection.js";
|
22
24
|
import type { RNQuickCrypto } from "./crypto/RNQuickCrypto.js";
|
23
25
|
import { ExpoSecureStoreAdapter } from "./storage/expo-secure-store-adapter.js";
|
24
26
|
import { KvStoreContext } from "./storage/kv-store-context.js";
|
25
27
|
|
26
|
-
/** @category Context Creation */
|
27
|
-
export type ReactNativeContext<Acc extends Account> = {
|
28
|
-
me: Acc;
|
29
|
-
logOut: () => void;
|
30
|
-
// TODO: Symbol.dispose?
|
31
|
-
done: () => void;
|
32
|
-
};
|
33
|
-
|
34
|
-
export type ReactNativeGuestContext = {
|
35
|
-
guest: AnonymousJazzAgent;
|
36
|
-
logOut: () => void;
|
37
|
-
done: () => void;
|
38
|
-
};
|
39
|
-
|
40
|
-
export type ReactNativeContextOptions<Acc extends Account> = {
|
41
|
-
auth: AuthMethod;
|
42
|
-
AccountSchema: CoValueClass<Acc> & {
|
43
|
-
fromNode: (typeof Account)["fromNode"];
|
44
|
-
};
|
45
|
-
} & BaseReactNativeContextOptions;
|
46
|
-
|
47
28
|
export type BaseReactNativeContextOptions = {
|
48
|
-
|
29
|
+
sync: SyncConfig;
|
49
30
|
reconnectionTimeout?: number;
|
50
31
|
storage?: "sqlite" | "disabled";
|
51
32
|
CryptoProvider?: typeof PureJSCrypto | typeof RNQuickCrypto;
|
33
|
+
authSecretStorage: AuthSecretStorage;
|
52
34
|
};
|
53
35
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
export async function createJazzRNContext<Acc extends Account>(
|
62
|
-
options: ReactNativeContextOptions<Acc> | BaseReactNativeContextOptions,
|
63
|
-
): Promise<ReactNativeContext<Acc> | ReactNativeGuestContext>;
|
64
|
-
export async function createJazzRNContext<Acc extends Account>(
|
65
|
-
options: ReactNativeContextOptions<Acc> | BaseReactNativeContextOptions,
|
66
|
-
): Promise<ReactNativeContext<Acc> | ReactNativeGuestContext> {
|
67
|
-
const websocketPeer = createWebSocketPeerWithReconnection(
|
68
|
-
options.peer,
|
69
|
-
options.reconnectionTimeout,
|
70
|
-
(peer) => {
|
71
|
-
node.syncManager.addPeer(peer);
|
72
|
-
},
|
73
|
-
);
|
36
|
+
class ReactNativeWebSocketPeerWithReconnection extends WebSocketPeerWithReconnection {
|
37
|
+
onNetworkChange(callback: (connected: boolean) => void): () => void {
|
38
|
+
return NetInfo.addEventListener((state) =>
|
39
|
+
callback(state.isConnected ?? false),
|
40
|
+
);
|
41
|
+
}
|
42
|
+
}
|
74
43
|
|
44
|
+
async function setupPeers(options: BaseReactNativeContextOptions) {
|
75
45
|
const CryptoProvider = options.CryptoProvider || PureJSCrypto;
|
46
|
+
const crypto = await CryptoProvider.create();
|
47
|
+
let node: LocalNode | undefined = undefined;
|
76
48
|
|
77
|
-
const peersToLoadFrom = [
|
49
|
+
const peersToLoadFrom: Peer[] = [];
|
78
50
|
|
79
51
|
if (options.storage === "sqlite") {
|
80
52
|
const storage = await SQLiteStorage.asPeer({
|
@@ -84,44 +56,147 @@ export async function createJazzRNContext<Acc extends Account>(
|
|
84
56
|
peersToLoadFrom.push(storage);
|
85
57
|
}
|
86
58
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
59
|
+
if (options.sync.when === "never") {
|
60
|
+
return {
|
61
|
+
toggleNetwork: () => {},
|
62
|
+
peersToLoadFrom,
|
63
|
+
setNode: () => {},
|
64
|
+
crypto,
|
65
|
+
};
|
66
|
+
}
|
67
|
+
|
68
|
+
const wsPeer = new ReactNativeWebSocketPeerWithReconnection({
|
69
|
+
peer: options.sync.peer,
|
70
|
+
reconnectionTimeout: options.reconnectionTimeout,
|
71
|
+
addPeer: (peer) => {
|
72
|
+
if (node) {
|
73
|
+
node.syncManager.addPeer(peer);
|
74
|
+
} else {
|
75
|
+
peersToLoadFrom.push(peer);
|
76
|
+
}
|
77
|
+
},
|
78
|
+
removePeer: (peer) => {
|
79
|
+
peersToLoadFrom.splice(peersToLoadFrom.indexOf(peer), 1);
|
80
|
+
},
|
81
|
+
});
|
82
|
+
|
83
|
+
function toggleNetwork(enabled: boolean) {
|
84
|
+
if (enabled) {
|
85
|
+
wsPeer.enable();
|
86
|
+
} else {
|
87
|
+
wsPeer.disable();
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
function setNode(value: LocalNode) {
|
92
|
+
node = value;
|
93
|
+
}
|
94
|
+
|
95
|
+
if (options.sync.when === "always" || !options.sync.when) {
|
96
|
+
toggleNetwork(true);
|
97
|
+
}
|
98
|
+
|
99
|
+
return {
|
100
|
+
toggleNetwork,
|
101
|
+
peersToLoadFrom,
|
102
|
+
setNode,
|
103
|
+
crypto,
|
104
|
+
};
|
105
|
+
}
|
106
|
+
|
107
|
+
export async function createJazzReactNativeGuestContext(
|
108
|
+
options: BaseReactNativeContextOptions,
|
109
|
+
) {
|
110
|
+
const { toggleNetwork, peersToLoadFrom, setNode, crypto } =
|
111
|
+
await setupPeers(options);
|
112
|
+
|
113
|
+
const context = await createAnonymousJazzContext({
|
114
|
+
crypto,
|
115
|
+
peersToLoadFrom,
|
116
|
+
});
|
117
|
+
|
118
|
+
setNode(context.agent.node);
|
119
|
+
|
120
|
+
options.authSecretStorage.emitUpdate(null);
|
121
|
+
|
122
|
+
return {
|
123
|
+
guest: context.agent,
|
124
|
+
node: context.agent.node,
|
125
|
+
done: () => {
|
126
|
+
// TODO: Sync all the covalues before closing the connection & context
|
127
|
+
toggleNetwork(false);
|
128
|
+
context.done();
|
129
|
+
},
|
130
|
+
logOut: () => {
|
131
|
+
return context.logOut();
|
132
|
+
},
|
133
|
+
};
|
134
|
+
}
|
135
|
+
|
136
|
+
export type ReactNativeContextOptions<Acc extends Account> = {
|
137
|
+
credentials?: AuthCredentials;
|
138
|
+
AccountSchema?: CoValueClass<Acc> & {
|
139
|
+
fromNode: (typeof Account)["fromNode"];
|
140
|
+
};
|
141
|
+
newAccountProps?: NewAccountProps;
|
142
|
+
defaultProfileName?: string;
|
143
|
+
} & BaseReactNativeContextOptions;
|
144
|
+
|
145
|
+
export async function createJazzReactNativeContext<Acc extends Account>(
|
146
|
+
options: ReactNativeContextOptions<Acc>,
|
147
|
+
) {
|
148
|
+
const { toggleNetwork, peersToLoadFrom, setNode, crypto } =
|
149
|
+
await setupPeers(options);
|
150
|
+
|
151
|
+
let unsubscribeAuthUpdate = () => {};
|
152
|
+
|
153
|
+
if (options.sync.when === "signedUp") {
|
154
|
+
const authSecretStorage = options.authSecretStorage;
|
155
|
+
const credentials = options.credentials ?? (await authSecretStorage.get());
|
156
|
+
|
157
|
+
// To update the internal state with the current credentials
|
158
|
+
authSecretStorage.emitUpdate(credentials);
|
159
|
+
|
160
|
+
function handleAuthUpdate(isAuthenticated: boolean) {
|
161
|
+
if (isAuthenticated) {
|
162
|
+
toggleNetwork(true);
|
163
|
+
} else {
|
164
|
+
toggleNetwork(false);
|
114
165
|
}
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
166
|
+
}
|
167
|
+
|
168
|
+
unsubscribeAuthUpdate = authSecretStorage.onUpdate(handleAuthUpdate);
|
169
|
+
handleAuthUpdate(authSecretStorage.isAuthenticated);
|
170
|
+
}
|
171
|
+
|
172
|
+
const context = await createJazzContext({
|
173
|
+
credentials: options.credentials,
|
174
|
+
newAccountProps: options.newAccountProps,
|
175
|
+
peersToLoadFrom,
|
176
|
+
crypto,
|
177
|
+
defaultProfileName: options.defaultProfileName,
|
178
|
+
AccountSchema: options.AccountSchema,
|
179
|
+
sessionProvider: provideLockSession,
|
180
|
+
authSecretStorage: options.authSecretStorage,
|
181
|
+
});
|
182
|
+
|
183
|
+
setNode(context.node);
|
184
|
+
|
185
|
+
return {
|
186
|
+
me: context.account,
|
187
|
+
node: context.node,
|
188
|
+
authSecretStorage: context.authSecretStorage,
|
189
|
+
done: () => {
|
190
|
+
// TODO: Sync all the covalues before closing the connection & context
|
191
|
+
toggleNetwork(false);
|
192
|
+
unsubscribeAuthUpdate();
|
193
|
+
context.done();
|
194
|
+
},
|
195
|
+
logOut: () => {
|
196
|
+
unsubscribeAuthUpdate();
|
197
|
+
return context.logOut();
|
198
|
+
},
|
199
|
+
};
|
125
200
|
}
|
126
201
|
|
127
202
|
/** @category Auth Providers */
|
package/src/provider.tsx
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
import {
|
2
|
-
import { Account,
|
3
|
-
import React, {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
|
7
|
-
|
8
|
-
} from "./platform.js";
|
1
|
+
import { JazzAuthContext, JazzContext } from "jazz-react-core";
|
2
|
+
import { Account, JazzContextType, KvStore } from "jazz-tools";
|
3
|
+
import React, { useEffect, useRef } from "react";
|
4
|
+
import { JazzContextManagerProps } from "./ReactNativeContextManager.js";
|
5
|
+
import { ReactNativeContextManager } from "./ReactNativeContextManager.js";
|
6
|
+
import { setupKvStore } from "./platform.js";
|
7
|
+
|
9
8
|
export interface Register {}
|
10
9
|
|
11
10
|
export type RegisteredAccount = Register extends { Account: infer Acc }
|
@@ -14,104 +13,82 @@ export type RegisteredAccount = Register extends { Account: infer Acc }
|
|
14
13
|
|
15
14
|
export type JazzProviderProps<Acc extends Account = RegisteredAccount> = {
|
16
15
|
children: React.ReactNode;
|
17
|
-
|
18
|
-
|
19
|
-
AccountSchema?: AccountClass<Acc>;
|
20
|
-
CryptoProvider?: BaseReactNativeContextOptions["CryptoProvider"];
|
21
|
-
storage?: BaseReactNativeContextOptions["storage"];
|
22
|
-
};
|
16
|
+
kvStore?: KvStore;
|
17
|
+
} & JazzContextManagerProps<Acc>;
|
23
18
|
|
24
19
|
/** @category Context & Hooks */
|
25
20
|
export function JazzProvider<Acc extends Account = RegisteredAccount>({
|
26
21
|
children,
|
27
|
-
|
28
|
-
|
29
|
-
AccountSchema = Account as unknown as AccountClass<Acc>,
|
30
|
-
CryptoProvider,
|
22
|
+
guestMode,
|
23
|
+
sync,
|
31
24
|
storage,
|
25
|
+
AccountSchema,
|
26
|
+
defaultProfileName,
|
27
|
+
onLogOut,
|
28
|
+
kvStore,
|
29
|
+
onAnonymousAccountDiscarded,
|
32
30
|
}: JazzProviderProps<Acc>) {
|
33
|
-
|
34
|
-
|
35
|
-
const [sessionCount, setSessionCount] = useState(0);
|
36
|
-
|
37
|
-
const effectExecuted = useRef(false);
|
38
|
-
effectExecuted.current = false;
|
39
|
-
|
40
|
-
useEffect(() => {
|
41
|
-
// Avoid double execution of the effect in development mode for easier debugging.
|
42
|
-
if (process.env.NODE_ENV === "development") {
|
43
|
-
if (effectExecuted.current) {
|
44
|
-
return;
|
45
|
-
}
|
46
|
-
effectExecuted.current = true;
|
31
|
+
setupKvStore(kvStore);
|
47
32
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
// So we mark it as done in the subsequent execution.
|
52
|
-
const previousContext = ctx;
|
53
|
-
|
54
|
-
if (previousContext) {
|
55
|
-
previousContext.done();
|
56
|
-
}
|
57
|
-
}
|
58
|
-
|
59
|
-
async function createContext() {
|
60
|
-
const currentContext = await createJazzRNContext<Acc>(
|
61
|
-
auth === "guest"
|
62
|
-
? {
|
63
|
-
peer,
|
64
|
-
CryptoProvider,
|
65
|
-
storage,
|
66
|
-
}
|
67
|
-
: {
|
68
|
-
AccountSchema,
|
69
|
-
auth: auth,
|
70
|
-
peer,
|
71
|
-
CryptoProvider,
|
72
|
-
storage,
|
73
|
-
},
|
74
|
-
);
|
75
|
-
|
76
|
-
const logOut = () => {
|
77
|
-
currentContext.logOut();
|
78
|
-
setCtx(undefined);
|
79
|
-
setSessionCount(sessionCount + 1);
|
33
|
+
const [contextManager] = React.useState(
|
34
|
+
() => new ReactNativeContextManager<Acc>(),
|
35
|
+
);
|
80
36
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
37
|
+
const onAnonymousAccountDiscardedRefCallback = useRefCallback(
|
38
|
+
onAnonymousAccountDiscarded,
|
39
|
+
);
|
40
|
+
const onLogOutRefCallback = useRefCallback(onLogOut);
|
41
|
+
|
42
|
+
const value = React.useSyncExternalStore<JazzContextType<Acc> | undefined>(
|
43
|
+
React.useCallback(
|
44
|
+
(callback) => {
|
45
|
+
const props = {
|
46
|
+
AccountSchema,
|
47
|
+
guestMode,
|
48
|
+
sync,
|
49
|
+
storage,
|
50
|
+
defaultProfileName,
|
51
|
+
onLogOut: onLogOutRefCallback,
|
52
|
+
onAnonymousAccountDiscarded: onAnonymousAccountDiscardedRefCallback,
|
53
|
+
};
|
54
|
+
if (contextManager.propsChanged(props)) {
|
55
|
+
contextManager.createContext(props).catch((error) => {
|
56
|
+
console.log(error.stack);
|
57
|
+
console.error("Error creating Jazz context:", error);
|
58
|
+
});
|
85
59
|
}
|
86
|
-
};
|
87
|
-
|
88
|
-
setCtx({
|
89
|
-
...currentContext,
|
90
|
-
AccountSchema,
|
91
|
-
logOut,
|
92
|
-
});
|
93
|
-
|
94
|
-
return currentContext;
|
95
|
-
}
|
96
|
-
|
97
|
-
const promise = createContext();
|
98
60
|
|
99
|
-
|
100
|
-
|
101
|
-
|
61
|
+
return contextManager.subscribe(callback);
|
62
|
+
},
|
63
|
+
[sync, guestMode].concat(storage as any),
|
64
|
+
),
|
65
|
+
() => contextManager.getCurrentValue(),
|
66
|
+
() => contextManager.getCurrentValue(),
|
67
|
+
);
|
102
68
|
|
69
|
+
useEffect(() => {
|
103
70
|
// In development mode we don't return a cleanup function because otherwise
|
104
71
|
// the double effect execution would mark the context as done immediately.
|
105
|
-
if (process.env.NODE_ENV === "development")
|
106
|
-
return;
|
107
|
-
}
|
72
|
+
if (process.env.NODE_ENV === "development") return;
|
108
73
|
|
109
74
|
return () => {
|
110
|
-
|
75
|
+
contextManager.done();
|
111
76
|
};
|
112
|
-
}, [
|
77
|
+
}, []);
|
113
78
|
|
114
79
|
return (
|
115
|
-
<JazzContext.Provider value={
|
80
|
+
<JazzContext.Provider value={value}>
|
81
|
+
<JazzAuthContext.Provider value={contextManager.getAuthSecretStorage()}>
|
82
|
+
{value && children}
|
83
|
+
</JazzAuthContext.Provider>
|
84
|
+
</JazzContext.Provider>
|
116
85
|
);
|
117
86
|
}
|
87
|
+
|
88
|
+
function useRefCallback<T extends (...args: any[]) => any>(callback?: T) {
|
89
|
+
const callbackRef = React.useRef(callback);
|
90
|
+
callbackRef.current = callback;
|
91
|
+
return useRef(
|
92
|
+
(...args: Parameters<T>): ReturnType<T> => callbackRef.current?.(...args),
|
93
|
+
).current;
|
94
|
+
}
|
@@ -1,182 +0,0 @@
|
|
1
|
-
import { KvStoreContext } from "../storage/kv-store-context.js";
|
2
|
-
const localStorageKey = "demo-auth-logged-in-secret";
|
3
|
-
export function encodeUsername(username) {
|
4
|
-
return btoa(username)
|
5
|
-
.replace(/=/g, "-")
|
6
|
-
.replace(/\+/g, "_")
|
7
|
-
.replace(/\//g, ".");
|
8
|
-
}
|
9
|
-
function getUserStorageKey(username) {
|
10
|
-
return `demo-auth-existing-users-${encodeUsername(username)}`;
|
11
|
-
}
|
12
|
-
function getLegacyUserStorageKey(username) {
|
13
|
-
return `demo-auth-existing-users-${username}`;
|
14
|
-
}
|
15
|
-
async function getStorageVersion(kvStore) {
|
16
|
-
try {
|
17
|
-
const version = await kvStore.get("demo-auth-storage-version");
|
18
|
-
return version ? parseInt(version) : 1;
|
19
|
-
}
|
20
|
-
catch (error) {
|
21
|
-
return 1;
|
22
|
-
}
|
23
|
-
}
|
24
|
-
async function setStorageVersion(kvStore, version) {
|
25
|
-
await kvStore.set("demo-auth-storage-version", version.toString());
|
26
|
-
}
|
27
|
-
async function getExistingUsers(kvStore) {
|
28
|
-
const existingUsers = await kvStore.get("demo-auth-existing-users");
|
29
|
-
return existingUsers ? existingUsers.split(",") : [];
|
30
|
-
}
|
31
|
-
async function addUserToExistingUsers(username, kvStore) {
|
32
|
-
const existingUsers = await getExistingUsers(kvStore);
|
33
|
-
if (existingUsers.includes(username)) {
|
34
|
-
return;
|
35
|
-
}
|
36
|
-
await kvStore.set("demo-auth-existing-users", existingUsers.concat(username).join(","));
|
37
|
-
}
|
38
|
-
/**
|
39
|
-
* Migrates existing users keys to use a base64 encoded username.
|
40
|
-
*
|
41
|
-
* This is done to avoid issues with special characters in the username.
|
42
|
-
*/
|
43
|
-
async function migrateExistingUsersKeys(kvStore) {
|
44
|
-
if ((await getStorageVersion(kvStore)) >= 2) {
|
45
|
-
return;
|
46
|
-
}
|
47
|
-
await setStorageVersion(kvStore, 2);
|
48
|
-
const existingUsers = await getExistingUsers(kvStore);
|
49
|
-
for (const existingUsername of existingUsers) {
|
50
|
-
const legacyKey = getLegacyUserStorageKey(existingUsername);
|
51
|
-
const storageData = await kvStore.get(legacyKey);
|
52
|
-
if (storageData) {
|
53
|
-
await kvStore.set(getUserStorageKey(existingUsername), storageData);
|
54
|
-
await kvStore.delete(legacyKey);
|
55
|
-
}
|
56
|
-
}
|
57
|
-
}
|
58
|
-
export class RNDemoAuth {
|
59
|
-
driver;
|
60
|
-
kvStore;
|
61
|
-
constructor(driver, kvStore) {
|
62
|
-
this.driver = driver;
|
63
|
-
this.kvStore = kvStore;
|
64
|
-
}
|
65
|
-
static async init(driver, seedAccounts, store) {
|
66
|
-
let kvStore = store;
|
67
|
-
const kvStoreContext = KvStoreContext.getInstance();
|
68
|
-
if (!kvStoreContext.isInitialized()) {
|
69
|
-
if (!kvStore) {
|
70
|
-
const { ExpoSecureStoreAdapter } = await import("../storage/expo-secure-store-adapter.js");
|
71
|
-
kvStoreContext.initialize(new ExpoSecureStoreAdapter());
|
72
|
-
}
|
73
|
-
else {
|
74
|
-
kvStoreContext.initialize(kvStore);
|
75
|
-
}
|
76
|
-
}
|
77
|
-
kvStore = kvStoreContext.getStorage();
|
78
|
-
await migrateExistingUsersKeys(kvStore);
|
79
|
-
for (const [name, credentials] of Object.entries(seedAccounts || {})) {
|
80
|
-
const storageData = JSON.stringify(credentials);
|
81
|
-
await addUserToExistingUsers(name, kvStore);
|
82
|
-
await kvStore.set(getUserStorageKey(name), storageData);
|
83
|
-
}
|
84
|
-
return new RNDemoAuth(driver, kvStore);
|
85
|
-
}
|
86
|
-
async start() {
|
87
|
-
try {
|
88
|
-
if (await this.kvStore.get(localStorageKey)) {
|
89
|
-
const localStorageData = JSON.parse((await this.kvStore.get(localStorageKey)) ?? "{}");
|
90
|
-
const accountID = localStorageData.accountID;
|
91
|
-
const secret = localStorageData.accountSecret;
|
92
|
-
return {
|
93
|
-
type: "existing",
|
94
|
-
credentials: { accountID, secret },
|
95
|
-
onSuccess: () => {
|
96
|
-
this.driver.onSignedIn({ logOut });
|
97
|
-
},
|
98
|
-
onError: (error) => {
|
99
|
-
this.kvStore.delete(localStorageKey);
|
100
|
-
this.driver.onError(error);
|
101
|
-
},
|
102
|
-
logOut: async () => {
|
103
|
-
void (await this.kvStore.delete(localStorageKey));
|
104
|
-
},
|
105
|
-
};
|
106
|
-
}
|
107
|
-
else {
|
108
|
-
return new Promise((resolve) => {
|
109
|
-
this.driver.onReady({
|
110
|
-
// @ts-expect-error asd
|
111
|
-
signUp: (username) => {
|
112
|
-
resolve({
|
113
|
-
type: "new",
|
114
|
-
creationProps: { name: username },
|
115
|
-
saveCredentials: async (credentials) => {
|
116
|
-
const storageData = JSON.stringify({
|
117
|
-
accountID: credentials.accountID,
|
118
|
-
accountSecret: credentials.secret,
|
119
|
-
});
|
120
|
-
const existingUsernames = await getExistingUsers(this.kvStore);
|
121
|
-
// Determine if the username already exists and generate a unique username
|
122
|
-
let uniqueUsername = username;
|
123
|
-
let counter = 1;
|
124
|
-
while (existingUsernames.includes(uniqueUsername)) {
|
125
|
-
counter++;
|
126
|
-
uniqueUsername = `${username}-${counter}`;
|
127
|
-
}
|
128
|
-
// Save credentials using the unique username
|
129
|
-
await this.kvStore.set(localStorageKey, storageData);
|
130
|
-
await this.kvStore.set(getUserStorageKey(uniqueUsername), storageData);
|
131
|
-
await addUserToExistingUsers(uniqueUsername, this.kvStore);
|
132
|
-
},
|
133
|
-
onSuccess: () => {
|
134
|
-
this.driver.onSignedIn({ logOut });
|
135
|
-
},
|
136
|
-
onError: (error) => {
|
137
|
-
this.driver.onError(error);
|
138
|
-
},
|
139
|
-
logOut: async () => {
|
140
|
-
void (await this.kvStore.delete(localStorageKey));
|
141
|
-
},
|
142
|
-
});
|
143
|
-
},
|
144
|
-
getExistingUsers: async () => {
|
145
|
-
return await getExistingUsers(this.kvStore);
|
146
|
-
},
|
147
|
-
logInAs: async (existingUser) => {
|
148
|
-
const storageData = JSON.parse((await this.kvStore.get(getUserStorageKey(existingUser))) ??
|
149
|
-
"{}");
|
150
|
-
await this.kvStore.set(localStorageKey, JSON.stringify(storageData));
|
151
|
-
resolve({
|
152
|
-
type: "existing",
|
153
|
-
credentials: {
|
154
|
-
accountID: storageData.accountID,
|
155
|
-
secret: storageData.accountSecret,
|
156
|
-
},
|
157
|
-
onSuccess: () => {
|
158
|
-
this.driver.onSignedIn({ logOut });
|
159
|
-
},
|
160
|
-
onError: (error) => {
|
161
|
-
this.driver.onError(error);
|
162
|
-
},
|
163
|
-
logOut: async () => {
|
164
|
-
void (await this.kvStore.delete(localStorageKey));
|
165
|
-
},
|
166
|
-
});
|
167
|
-
},
|
168
|
-
});
|
169
|
-
});
|
170
|
-
}
|
171
|
-
}
|
172
|
-
catch (error) {
|
173
|
-
console.error("error", error);
|
174
|
-
throw error;
|
175
|
-
}
|
176
|
-
}
|
177
|
-
}
|
178
|
-
async function logOut() {
|
179
|
-
const kvStore = KvStoreContext.getInstance().getStorage();
|
180
|
-
void (await kvStore.delete(localStorageKey));
|
181
|
-
}
|
182
|
-
//# sourceMappingURL=DemoAuthMethod.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"DemoAuthMethod.js","sourceRoot":"","sources":["../../src/auth/DemoAuthMethod.ts"],"names":[],"mappings":"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"}
|