jazz-tools 0.19.15 → 0.19.17
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/.svelte-kit/__package__/tests/media/image.svelte.test.js +4 -1
- package/.turbo/turbo-build.log +60 -60
- package/CHANGELOG.md +19 -0
- package/dist/{chunk-R3KIZG4P.js → chunk-OH2GW5WP.js} +24 -8
- package/dist/{chunk-R3KIZG4P.js.map → chunk-OH2GW5WP.js.map} +1 -1
- package/dist/index.js +86 -54
- package/dist/index.js.map +1 -1
- package/dist/react-native/index.js +18 -17
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native-core/ReactNativeSessionProvider.d.ts.map +1 -1
- package/dist/react-native-core/index.js +18 -17
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/svelte/tests/media/image.svelte.test.js +4 -1
- package/dist/testing.js +1 -1
- package/dist/tools/auth/clerk/getClerkUsername.d.ts +2 -2
- package/dist/tools/auth/clerk/getClerkUsername.d.ts.map +1 -1
- package/dist/tools/auth/clerk/index.d.ts +5 -4
- package/dist/tools/auth/clerk/index.d.ts.map +1 -1
- package/dist/tools/auth/clerk/tests/isClerkAuthStateEqual.test.d.ts +2 -0
- package/dist/tools/auth/clerk/tests/isClerkAuthStateEqual.test.d.ts.map +1 -0
- package/dist/tools/auth/clerk/tests/isClerkCredentials.test.d.ts +2 -0
- package/dist/tools/auth/clerk/tests/isClerkCredentials.test.d.ts.map +1 -0
- package/dist/tools/auth/clerk/types.d.ts +62 -19
- package/dist/tools/auth/clerk/types.d.ts.map +1 -1
- package/dist/tools/implementation/ContextManager.d.ts +10 -0
- package/dist/tools/implementation/ContextManager.d.ts.map +1 -1
- package/package.json +5 -6
- package/src/react/tests/media/image.test.tsx +5 -1
- package/src/react-native-core/ReactNativeSessionProvider.ts +24 -24
- package/src/svelte/tests/media/image.svelte.test.ts +5 -1
- package/src/tools/auth/clerk/getClerkUsername.ts +13 -20
- package/src/tools/auth/clerk/index.ts +35 -28
- package/src/tools/auth/clerk/tests/JazzClerkAuth.test.ts +105 -33
- package/src/tools/auth/clerk/tests/getClerkUsername.test.ts +25 -45
- package/src/tools/auth/clerk/tests/isClerkAuthStateEqual.test.ts +128 -0
- package/src/tools/auth/clerk/tests/{types.test.ts → isClerkCredentials.test.ts} +4 -2
- package/src/tools/auth/clerk/types.ts +66 -28
- package/src/tools/implementation/ContextManager.ts +28 -7
- package/src/tools/tests/ContextManager.test.ts +16 -0
- package/dist/tools/auth/clerk/tests/types.test.d.ts +0 -2
- package/dist/tools/auth/clerk/tests/types.test.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isClerkAuthStateEqual.test.d.ts","sourceRoot":"","sources":["../../../../../src/tools/auth/clerk/tests/isClerkAuthStateEqual.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isClerkCredentials.test.d.ts","sourceRoot":"","sources":["../../../../../src/tools/auth/clerk/tests/isClerkCredentials.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,25 +1,66 @@
|
|
|
1
|
-
import { AgentSecret } from "cojson";
|
|
2
|
-
import {
|
|
1
|
+
import { type AgentSecret } from "cojson";
|
|
2
|
+
import { z } from "zod/v4";
|
|
3
|
+
declare const ClerkUserSchema: z.ZodObject<{
|
|
4
|
+
fullName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
5
|
+
username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
6
|
+
firstName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
7
|
+
lastName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
8
|
+
id: z.ZodOptional<z.ZodString>;
|
|
9
|
+
primaryEmailAddress: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
10
|
+
emailAddress: z.ZodNullable<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>>>;
|
|
12
|
+
unsafeMetadata: z.ZodUnion<readonly [z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
13
|
+
jazzAccountID: z.ZodString;
|
|
14
|
+
jazzAccountSecret: z.ZodString;
|
|
15
|
+
jazzAccountSeed: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
16
|
+
}, z.core.$strip>]>;
|
|
17
|
+
update: z.ZodFunction<z.ZodTuple<readonly [z.ZodObject<{
|
|
18
|
+
unsafeMetadata: z.ZodObject<{
|
|
19
|
+
jazzAccountID: z.ZodString;
|
|
20
|
+
jazzAccountSecret: z.ZodString;
|
|
21
|
+
jazzAccountSeed: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
}, z.core.$strip>], null>, z.ZodPromise<z.ZodUnknown>>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
export declare const ClerkEventSchema: z.ZodObject<{
|
|
26
|
+
user: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
27
|
+
fullName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
28
|
+
username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
29
|
+
firstName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
30
|
+
lastName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
31
|
+
id: z.ZodOptional<z.ZodString>;
|
|
32
|
+
primaryEmailAddress: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
33
|
+
emailAddress: z.ZodNullable<z.ZodString>;
|
|
34
|
+
}, z.core.$strip>>>;
|
|
35
|
+
unsafeMetadata: z.ZodUnion<readonly [z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
|
|
36
|
+
jazzAccountID: z.ZodString;
|
|
37
|
+
jazzAccountSecret: z.ZodString;
|
|
38
|
+
jazzAccountSeed: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
39
|
+
}, z.core.$strip>]>;
|
|
40
|
+
update: z.ZodFunction<z.ZodTuple<readonly [z.ZodObject<{
|
|
41
|
+
unsafeMetadata: z.ZodObject<{
|
|
42
|
+
jazzAccountID: z.ZodString;
|
|
43
|
+
jazzAccountSecret: z.ZodString;
|
|
44
|
+
jazzAccountSeed: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
}, z.core.$strip>], null>, z.ZodPromise<z.ZodUnknown>>;
|
|
47
|
+
}, z.core.$strip>>>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
export type ClerkEventSchema = z.infer<typeof ClerkEventSchema>;
|
|
50
|
+
export type ClerkUser = z.infer<typeof ClerkUserSchema>;
|
|
51
|
+
type PermissiveClerkUser = Omit<ClerkUser, "unsafeMetadata" | "update"> & {
|
|
52
|
+
unsafeMetadata: Record<string, unknown>;
|
|
53
|
+
update: (args: {
|
|
54
|
+
unsafeMetadata: Record<string, unknown>;
|
|
55
|
+
}) => Promise<unknown>;
|
|
56
|
+
};
|
|
3
57
|
export type MinimalClerkClient = {
|
|
4
|
-
user:
|
|
5
|
-
unsafeMetadata: Record<string, any>;
|
|
6
|
-
fullName: string | null;
|
|
7
|
-
username: string | null;
|
|
8
|
-
firstName: string | null;
|
|
9
|
-
lastName: string | null;
|
|
10
|
-
id: string;
|
|
11
|
-
primaryEmailAddress: {
|
|
12
|
-
emailAddress: string | null;
|
|
13
|
-
} | null;
|
|
14
|
-
update: (args: {
|
|
15
|
-
unsafeMetadata: Record<string, any>;
|
|
16
|
-
}) => Promise<unknown>;
|
|
17
|
-
} | null | undefined;
|
|
58
|
+
user: PermissiveClerkUser | null | undefined;
|
|
18
59
|
signOut: () => Promise<void>;
|
|
19
60
|
addListener: (listener: (data: unknown) => void) => void;
|
|
20
61
|
};
|
|
21
62
|
export type ClerkCredentials = {
|
|
22
|
-
jazzAccountID:
|
|
63
|
+
jazzAccountID: string;
|
|
23
64
|
jazzAccountSecret: AgentSecret;
|
|
24
65
|
jazzAccountSeed?: number[];
|
|
25
66
|
};
|
|
@@ -27,6 +68,8 @@ export type ClerkCredentials = {
|
|
|
27
68
|
* Checks if the Clerk user metadata contains the necessary credentials for Jazz auth.
|
|
28
69
|
* **Note**: It does not validate the credentials, only checks if the necessary fields are present in the metadata object.
|
|
29
70
|
*/
|
|
30
|
-
export declare function isClerkCredentials(data:
|
|
31
|
-
|
|
71
|
+
export declare function isClerkCredentials(data: Record<string, unknown> | undefined): data is ClerkCredentials;
|
|
72
|
+
type ClerkUserWithUnsafeMetadata = Pick<ClerkUser, "unsafeMetadata"> | null | undefined;
|
|
73
|
+
export declare function isClerkAuthStateEqual(previousUser: ClerkUserWithUnsafeMetadata, newUser: ClerkUserWithUnsafeMetadata): boolean;
|
|
74
|
+
export {};
|
|
32
75
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/tools/auth/clerk/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/tools/auth/clerk/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAQ3B,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;iBAoBnB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;iBAE3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAGxD,KAAK,mBAAmB,GAAG,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,QAAQ,CAAC,GAAG;IACxE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,IAAI,EAAE;QACb,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACzC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,WAAW,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACxC,IAAI,IAAI,gBAAgB,CAE1B;AAED,KAAK,2BAA2B,GAC5B,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,GACjC,IAAI,GACJ,SAAS,CAAC;AAEd,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,2BAA2B,EACzC,OAAO,EAAE,2BAA2B,WAkBrC"}
|
|
@@ -60,6 +60,16 @@ export declare class JazzContextManager<Acc extends Account, P extends JazzConte
|
|
|
60
60
|
getAuthSecretStorage(): AuthSecretStorage;
|
|
61
61
|
getAuthenticatingAccountID(): string | null;
|
|
62
62
|
getSubscriptionScopeCache(): SubscriptionCache;
|
|
63
|
+
/**
|
|
64
|
+
* Flag to indicate if a logout operation is currently in progress.
|
|
65
|
+
* Used to prevent concurrent logout attempts or double-logout issues.
|
|
66
|
+
* Set to true when logout starts, reset to false once all logout logic runs.
|
|
67
|
+
*/
|
|
68
|
+
loggingOut: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Handles the logout process.
|
|
71
|
+
* Uses the loggingOut flag to ensure only one logout can happen at a time.
|
|
72
|
+
*/
|
|
63
73
|
logOut: () => Promise<void>;
|
|
64
74
|
done: () => void;
|
|
65
75
|
shouldMigrateAnonymousAccount: () => Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextManager.d.ts","sourceRoot":"","sources":["../../../src/tools/implementation/ContextManager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ContextManager.d.ts","sourceRoot":"","sources":["../../../src/tools/implementation/ContextManager.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
},
|
|
206
206
|
"type": "module",
|
|
207
207
|
"license": "MIT",
|
|
208
|
-
"version": "0.19.
|
|
208
|
+
"version": "0.19.17",
|
|
209
209
|
"dependencies": {
|
|
210
210
|
"@manuscripts/prosemirror-recreate-steps": "^0.1.4",
|
|
211
211
|
"@scure/base": "1.2.1",
|
|
@@ -222,9 +222,9 @@
|
|
|
222
222
|
"prosemirror-transform": "^1.9.0",
|
|
223
223
|
"use-sync-external-store": "^1.5.0",
|
|
224
224
|
"zod": "4.1.11",
|
|
225
|
-
"cojson": "0.19.
|
|
226
|
-
"cojson-storage-indexeddb": "0.19.
|
|
227
|
-
"cojson-transport-ws": "0.19.
|
|
225
|
+
"cojson": "0.19.17",
|
|
226
|
+
"cojson-storage-indexeddb": "0.19.17",
|
|
227
|
+
"cojson-transport-ws": "0.19.17"
|
|
228
228
|
},
|
|
229
229
|
"devDependencies": {
|
|
230
230
|
"@scure/bip39": "^1.3.0",
|
|
@@ -237,7 +237,6 @@
|
|
|
237
237
|
"@types/react": "19.1.0",
|
|
238
238
|
"@types/react-dom": "19.1.0",
|
|
239
239
|
"@types/use-sync-external-store": "^1.5.0",
|
|
240
|
-
"@vitest/browser": "^3.2.4",
|
|
241
240
|
"libsql": "^0.5.13",
|
|
242
241
|
"msw": "^2.10.3",
|
|
243
242
|
"oauth2-mock-server": "^8.1.0",
|
|
@@ -246,7 +245,7 @@
|
|
|
246
245
|
"react-error-boundary": "^6.0.0",
|
|
247
246
|
"tsup": "8.5.0",
|
|
248
247
|
"typescript": "5.6.2",
|
|
249
|
-
"vitest": "
|
|
248
|
+
"vitest": "4.0.16",
|
|
250
249
|
"ws": "^8.14.2"
|
|
251
250
|
},
|
|
252
251
|
"peerDependencies": {
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// @vitest-environment happy-dom
|
|
2
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import { Account, FileStream, ImageDefinition } from "../../../";
|
|
4
4
|
import { Image } from "../../media/image";
|
|
5
5
|
import { createJazzTestAccount } from "../../testing";
|
|
6
6
|
import { render, screen, waitFor } from "../testUtils";
|
|
7
7
|
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
vi.clearAllMocks();
|
|
10
|
+
});
|
|
11
|
+
|
|
8
12
|
describe("Image", async () => {
|
|
9
13
|
const account = await createJazzTestAccount({
|
|
10
14
|
isCurrentActiveAccount: true,
|
|
@@ -16,6 +16,23 @@ export class ReactNativeSessionProvider implements SessionProvider {
|
|
|
16
16
|
const kvStore = KvStoreContext.getInstance().getStorage();
|
|
17
17
|
const existingSession = await kvStore.get(accountID as string);
|
|
18
18
|
|
|
19
|
+
if (!existingSession) {
|
|
20
|
+
const newSessionID = crypto.newRandomSessionID(
|
|
21
|
+
accountID as RawAccountID | AgentID,
|
|
22
|
+
);
|
|
23
|
+
await kvStore.set(accountID, newSessionID);
|
|
24
|
+
lockedSessions.add(newSessionID);
|
|
25
|
+
|
|
26
|
+
console.log("Created new session", newSessionID);
|
|
27
|
+
|
|
28
|
+
return Promise.resolve({
|
|
29
|
+
sessionID: newSessionID,
|
|
30
|
+
sessionDone: () => {
|
|
31
|
+
lockedSessions.delete(newSessionID);
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
19
36
|
// Check if the session is already in use, should happen only if the dev
|
|
20
37
|
// mounts multiple providers at the same time
|
|
21
38
|
if (lockedSessions.has(existingSession as SessionID)) {
|
|
@@ -31,33 +48,13 @@ export class ReactNativeSessionProvider implements SessionProvider {
|
|
|
31
48
|
});
|
|
32
49
|
}
|
|
33
50
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
lockedSessions.add(existingSession as SessionID);
|
|
37
|
-
return Promise.resolve({
|
|
38
|
-
sessionID: existingSession as SessionID,
|
|
39
|
-
sessionDone: () => {
|
|
40
|
-
lockedSessions.delete(existingSession as SessionID);
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// We need to provide this for backwards compatibility with the old session provider
|
|
46
|
-
// With the current session provider we should never get here because:
|
|
47
|
-
// - New accounts provide their session and go through the persistSession method
|
|
48
|
-
// - Existing accounts should already have a session
|
|
49
|
-
const newSessionID = crypto.newRandomSessionID(
|
|
50
|
-
accountID as RawAccountID | AgentID,
|
|
51
|
-
);
|
|
52
|
-
await kvStore.set(accountID, newSessionID);
|
|
53
|
-
lockedSessions.add(newSessionID);
|
|
54
|
-
|
|
55
|
-
console.error("Created new session", newSessionID);
|
|
51
|
+
console.log("Using existing session", existingSession);
|
|
52
|
+
lockedSessions.add(existingSession as SessionID);
|
|
56
53
|
|
|
57
54
|
return Promise.resolve({
|
|
58
|
-
sessionID:
|
|
55
|
+
sessionID: existingSession as SessionID,
|
|
59
56
|
sessionDone: () => {
|
|
60
|
-
lockedSessions.delete(
|
|
57
|
+
lockedSessions.delete(existingSession as SessionID);
|
|
61
58
|
},
|
|
62
59
|
});
|
|
63
60
|
}
|
|
@@ -69,6 +66,9 @@ export class ReactNativeSessionProvider implements SessionProvider {
|
|
|
69
66
|
const kvStore = KvStoreContext.getInstance().getStorage();
|
|
70
67
|
await kvStore.set(accountID, sessionID);
|
|
71
68
|
lockedSessions.add(sessionID);
|
|
69
|
+
|
|
70
|
+
console.log("Persisted session", sessionID);
|
|
71
|
+
|
|
72
72
|
return Promise.resolve({
|
|
73
73
|
sessionDone: () => {
|
|
74
74
|
lockedSessions.delete(sessionID);
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
// @vitest-environment happy-dom
|
|
2
2
|
import { FileStream, ImageDefinition } from "jazz-tools";
|
|
3
3
|
import { createJazzTestAccount } from "jazz-tools/testing";
|
|
4
|
-
import { describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
5
|
import Image from "../../media/image.svelte";
|
|
6
6
|
import type { ImageProps } from "../../media/image.types.js";
|
|
7
7
|
import { render, screen, waitFor } from "../testUtils";
|
|
8
8
|
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
vi.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
|
|
9
13
|
describe("Image", async () => {
|
|
10
14
|
const account = await createJazzTestAccount({
|
|
11
15
|
isCurrentActiveAccount: true,
|
|
@@ -1,36 +1,29 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ClerkUser } from "./types.js";
|
|
2
2
|
|
|
3
|
-
export function getClerkUsername(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!clerkClient.user) {
|
|
7
|
-
return null;
|
|
3
|
+
export function getClerkUsername(user: ClerkUser) {
|
|
4
|
+
if (user.fullName) {
|
|
5
|
+
return user.fullName;
|
|
8
6
|
}
|
|
9
7
|
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (clerkClient.user.firstName) {
|
|
15
|
-
if (clerkClient.user.lastName) {
|
|
16
|
-
return `${clerkClient.user.firstName} ${clerkClient.user.lastName}`;
|
|
8
|
+
if (user.firstName) {
|
|
9
|
+
if (user.lastName) {
|
|
10
|
+
return `${user.firstName} ${user.lastName}`;
|
|
17
11
|
}
|
|
18
12
|
|
|
19
|
-
return
|
|
13
|
+
return user.firstName;
|
|
20
14
|
}
|
|
21
15
|
|
|
22
|
-
if (
|
|
23
|
-
return
|
|
16
|
+
if (user.username) {
|
|
17
|
+
return user.username;
|
|
24
18
|
}
|
|
25
19
|
|
|
26
|
-
if (
|
|
27
|
-
const emailUsername =
|
|
28
|
-
clerkClient.user.primaryEmailAddress.emailAddress.split("@")[0];
|
|
20
|
+
if (user.primaryEmailAddress?.emailAddress) {
|
|
21
|
+
const emailUsername = user.primaryEmailAddress.emailAddress.split("@")[0];
|
|
29
22
|
|
|
30
23
|
if (emailUsername) {
|
|
31
24
|
return emailUsername;
|
|
32
25
|
}
|
|
33
26
|
}
|
|
34
27
|
|
|
35
|
-
return
|
|
28
|
+
return user.id;
|
|
36
29
|
}
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
import { getClerkUsername } from "./getClerkUsername.js";
|
|
8
8
|
import {
|
|
9
9
|
ClerkCredentials,
|
|
10
|
+
ClerkEventSchema,
|
|
11
|
+
ClerkUser,
|
|
10
12
|
MinimalClerkClient,
|
|
11
13
|
isClerkAuthStateEqual,
|
|
12
14
|
isClerkCredentials,
|
|
@@ -53,29 +55,36 @@ export class JazzClerkAuth {
|
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
private isFirstCall = true;
|
|
58
|
+
private previousUser: Pick<ClerkUser, "unsafeMetadata"> | null = null;
|
|
56
59
|
|
|
57
60
|
registerListener(clerkClient: MinimalClerkClient) {
|
|
58
|
-
|
|
59
|
-
clerkClient.user ?? null;
|
|
61
|
+
this.previousUser = ClerkEventSchema.parse(clerkClient).user ?? null;
|
|
60
62
|
|
|
61
63
|
// Need to use addListener because the clerk user object is not updated when the user logs in
|
|
62
64
|
return clerkClient.addListener((event) => {
|
|
63
|
-
const
|
|
65
|
+
const parsedEvent = ClerkEventSchema.safeParse(event);
|
|
64
66
|
|
|
65
|
-
if (!
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
if (!parsedEvent.success) {
|
|
68
|
+
console.error("Invalid Clerk event", parsedEvent.error);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const user = parsedEvent.data.user ?? null;
|
|
73
|
+
|
|
74
|
+
if (!isClerkAuthStateEqual(this.previousUser, user) || this.isFirstCall) {
|
|
75
|
+
this.previousUser = user;
|
|
76
|
+
this.onClerkUserChange(user);
|
|
68
77
|
this.isFirstCall = false;
|
|
69
78
|
}
|
|
70
79
|
});
|
|
71
80
|
}
|
|
72
81
|
|
|
73
|
-
onClerkUserChange = async (
|
|
82
|
+
onClerkUserChange = async (clerkUser: ClerkUser | null | undefined) => {
|
|
74
83
|
const isAuthenticated = this.authSecretStorage.isAuthenticated;
|
|
75
84
|
|
|
76
85
|
// LogOut is driven by Clerk. The framework adapters will need to pass `logOutReplacement` to the `JazzProvider`
|
|
77
86
|
// to make the logOut work correctly.
|
|
78
|
-
if (!
|
|
87
|
+
if (!clerkUser) {
|
|
79
88
|
if (isAuthenticated) {
|
|
80
89
|
this.authSecretStorage.clear();
|
|
81
90
|
await this.logOut();
|
|
@@ -85,22 +94,15 @@ export class JazzClerkAuth {
|
|
|
85
94
|
|
|
86
95
|
if (isAuthenticated) return;
|
|
87
96
|
|
|
88
|
-
|
|
89
|
-
.
|
|
90
|
-
|
|
91
|
-
if (!clerkCredentials.jazzAccountID) {
|
|
92
|
-
await this.signIn(clerkClient);
|
|
97
|
+
if (!clerkUser.unsafeMetadata.jazzAccountID) {
|
|
98
|
+
await this.signIn(clerkUser);
|
|
93
99
|
} else {
|
|
94
|
-
await this.logIn(
|
|
100
|
+
await this.logIn(clerkUser);
|
|
95
101
|
}
|
|
96
102
|
};
|
|
97
103
|
|
|
98
|
-
logIn = async (
|
|
99
|
-
|
|
100
|
-
throw new Error("Not signed in on Clerk");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const clerkCredentials = clerkClient.user.unsafeMetadata;
|
|
104
|
+
logIn = async (clerkUser: ClerkUser) => {
|
|
105
|
+
const clerkCredentials = clerkUser.unsafeMetadata;
|
|
104
106
|
if (!isClerkCredentials(clerkCredentials)) {
|
|
105
107
|
throw new Error("No credentials found on Clerk");
|
|
106
108
|
}
|
|
@@ -126,7 +128,7 @@ export class JazzClerkAuth {
|
|
|
126
128
|
);
|
|
127
129
|
};
|
|
128
130
|
|
|
129
|
-
signIn = async (
|
|
131
|
+
signIn = async (clerkUser: ClerkUser) => {
|
|
130
132
|
const credentials = await this.authSecretStorage.get();
|
|
131
133
|
|
|
132
134
|
if (!credentials) {
|
|
@@ -137,12 +139,17 @@ export class JazzClerkAuth {
|
|
|
137
139
|
? Array.from(credentials.secretSeed)
|
|
138
140
|
: undefined;
|
|
139
141
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
const clerkCredentials = {
|
|
143
|
+
jazzAccountID: credentials.accountID,
|
|
144
|
+
jazzAccountSecret: credentials.accountSecret,
|
|
145
|
+
jazzAccountSeed,
|
|
146
|
+
};
|
|
147
|
+
// user.update will cause the Clerk user change listener to fire; updating this.previousUser beforehand
|
|
148
|
+
// ensures the listener sees the new credentials and does not trigger an unnecessary logIn operation
|
|
149
|
+
this.previousUser = { unsafeMetadata: clerkCredentials };
|
|
150
|
+
|
|
151
|
+
await clerkUser.update({
|
|
152
|
+
unsafeMetadata: clerkCredentials,
|
|
146
153
|
});
|
|
147
154
|
|
|
148
155
|
const currentAccount = await Account.getMe().$jazz.ensureLoaded({
|
|
@@ -151,7 +158,7 @@ export class JazzClerkAuth {
|
|
|
151
158
|
},
|
|
152
159
|
});
|
|
153
160
|
|
|
154
|
-
const username = getClerkUsername(
|
|
161
|
+
const username = getClerkUsername(clerkUser);
|
|
155
162
|
|
|
156
163
|
if (username) {
|
|
157
164
|
currentAccount.profile.$jazz.set("name", username);
|