jazz-react-auth-clerk 0.9.23 → 0.10.1

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > jazz-react-auth-clerk@0.9.23 build /home/runner/work/jazz/jazz/packages/jazz-react-auth-clerk
2
+ > jazz-react-auth-clerk@0.10.1 build /home/runner/_work/jazz/jazz/packages/jazz-react-auth-clerk
3
3
  > rm -rf ./dist && tsc --sourceMap --outDir dist
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # jazz-browser-media-images
2
2
 
3
+ ## 0.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [5a63cba]
8
+ - Updated dependencies [5a63cba]
9
+ - jazz-tools@0.10.1
10
+ - cojson@0.10.1
11
+ - jazz-auth-clerk@0.10.1
12
+ - jazz-react@0.10.1
13
+
14
+ ## 0.10.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 498954f: Introducing the new auth system!
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies [b426342]
23
+ - Updated dependencies [498954f]
24
+ - Updated dependencies [8217981]
25
+ - Updated dependencies [d42c2aa]
26
+ - Updated dependencies [dd03464]
27
+ - Updated dependencies [b426342]
28
+ - Updated dependencies [ac3d9fa]
29
+ - Updated dependencies [610543c]
30
+ - cojson@0.10.0
31
+ - jazz-auth-clerk@0.10.0
32
+ - jazz-react@0.10.0
33
+ - jazz-tools@0.10.0
34
+
3
35
  ## 0.9.23
4
36
 
5
37
  ### Patch Changes
package/README.md CHANGED
@@ -4,49 +4,39 @@ This package provides a [Clerk-based](https://clerk.com/) authentication strateg
4
4
 
5
5
  ## Usage
6
6
 
7
- `useJazzClerkAuth` is a hook that returns a `JazzAuth` object and a `JazzAuthState` object. Provide a Clerk instance to `useJazzClerkAuth`, and it will return the appropriate `JazzAuth` object. Once authenticated, authentication will persist across page reloads, even if the device is offline.
7
+ The `JazzProviderWithClerk` component is a JazzProvider that automatically handles Clerk authentication.
8
8
 
9
+ Once authenticated, authentication will persist across page reloads, even if the device is offline.
9
10
 
10
11
  See the full [example app](https://github.com/garden-co/jazz/tree/main/examples/clerk) for a complete example.
11
12
 
12
13
  ```tsx
13
- import { ClerkProvider, SignInButton, useClerk } from "@clerk/clerk-react";
14
- import { useJazzClerkAuth } from "jazz-react-auth-clerk";
15
- import { JazzProvider } from "jazz-react";
14
+ import { ClerkProvider, useClerk } from "@clerk/clerk-react";
15
+ import { JazzProviderWithClerk } from "jazz-react-auth-clerk";
16
16
 
17
17
  const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
18
18
 
19
- function JazzAndAuth({ children }: { children: React.ReactNode }) {
19
+ function JazzProvider({ children }: { children: React.ReactNode }) {
20
20
  const clerk = useClerk();
21
- const [auth, state] = useJazzClerkAuth(clerk);
22
21
 
23
22
  return (
24
- <>
25
- {state?.errors?.map((error) => (
26
- <div key={error}>{error}</div>
27
- ))}
28
- {clerk.user && auth ? (
29
- <JazzProvider
30
- auth={auth}
31
- peer="wss://cloud.jazz.tools/?key=your-email-address"
32
- >
33
- {children}
34
- </JazzProvider>
35
- ) : (
36
- <SignInButton />
37
- )}
38
- </>
23
+ <JazzProviderWithClerk
24
+ clerk={clerk}
25
+ sync={{
26
+ peer: "wss://cloud.jazz.tools/?key=your-email-address",
27
+ }}
28
+ >
29
+ {children}
30
+ </JazzProviderWithClerk>
39
31
  );
40
32
  }
41
33
 
42
34
  createRoot(document.getElementById("root")!).render(
43
35
  <StrictMode>
44
36
  <ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
45
- <JazzAndAuth>
37
+ <JazzProvider>
46
38
  <App />
47
- </JazzAndAuth>
39
+ </JazzProvider>
48
40
  </ClerkProvider>
49
41
  </StrictMode>,
50
42
  );
51
-
52
- ```
package/dist/index.js CHANGED
@@ -1,18 +1,28 @@
1
- import { BrowserClerkAuth } from "jazz-browser-auth-clerk";
2
- import { useMemo, useState } from "react";
3
- export function useJazzClerkAuth(clerk) {
4
- const [state, setState] = useState({ errors: [] });
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { JazzClerkAuth } from "jazz-auth-clerk";
3
+ import { JazzProvider, useAuthSecretStorage, useJazzContext, } from "jazz-react";
4
+ import { useEffect, useMemo } from "react";
5
+ function useJazzClerkAuth(clerk) {
6
+ const context = useJazzContext();
7
+ const authSecretStorage = useAuthSecretStorage();
8
+ if ("guest" in context) {
9
+ throw new Error("Clerk auth is not supported in guest mode");
10
+ }
5
11
  const authMethod = useMemo(() => {
6
- return new BrowserClerkAuth({
7
- onError: (error) => {
8
- void clerk.signOut();
9
- setState((state) => ({
10
- ...state,
11
- errors: [...state.errors, error.toString()],
12
- }));
13
- },
14
- }, clerk);
15
- }, [clerk.user]);
16
- return [authMethod, state];
12
+ return new JazzClerkAuth(context.authenticate, authSecretStorage);
13
+ }, []);
14
+ useEffect(() => {
15
+ // Need to use addListener because the clerk user object is not updated when the user logs in
16
+ return clerk.addListener((event) => {
17
+ authMethod.onClerkUserChange(event);
18
+ });
19
+ }, []);
17
20
  }
21
+ function RegisterClerkAuth(props) {
22
+ useJazzClerkAuth(props.clerk);
23
+ return props.children;
24
+ }
25
+ export const JazzProviderWithClerk = (props) => {
26
+ return (_jsx(JazzProvider, { ...props, onLogOut: props.clerk.signOut, children: _jsx(RegisterClerkAuth, { clerk: props.clerk, children: props.children }) }));
27
+ };
18
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAsB,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,UAAU,gBAAgB,CAAC,KAAyB;IACxD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAuB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE;QAC9B,OAAO,IAAI,gBAAgB,CACzB;YACE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjB,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;gBACrB,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACnB,GAAG,KAAK;oBACR,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;iBAC5C,CAAC,CAAC,CAAC;YACN,CAAC;SACF,EACD,KAAK,CACN,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjB,OAAO,CAAC,UAAU,EAAE,KAAK,CAAU,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAA2B,MAAM,iBAAiB,CAAC;AACzE,OAAO,EACL,YAAY,EAEZ,oBAAoB,EACpB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAE3C,SAAS,gBAAgB,CAAC,KAAyB;IACjD,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,iBAAiB,GAAG,oBAAoB,EAAE,CAAC;IAEjD,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE;QAC9B,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACpE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,6FAA6F;QAC7F,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE;YACjC,UAAU,CAAC,iBAAiB,CAAC,KAAyC,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED,SAAS,iBAAiB,CAAC,KAG1B;IACC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE9B,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,KAAwD,EACxD,EAAE;IACF,OAAO,CACL,KAAC,YAAY,OAAK,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,YACpD,KAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAClC,KAAK,CAAC,QAAQ,GACG,GACP,CAChB,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @vitest-environment happy-dom
3
+ import { act, render } from "@testing-library/react";
4
+ import { AuthSecretStorage, InMemoryKVStore, KvStoreContext } from "jazz-tools";
5
+ import { beforeEach, describe, expect, it, vi } from "vitest";
6
+ import { JazzProviderWithClerk } from "../index";
7
+ vi.mock("jazz-react", async (importOriginal) => {
8
+ const { JazzTestProvider, createJazzTestAccount } = await import("jazz-react/testing");
9
+ const account = await createJazzTestAccount({
10
+ isCurrentActiveAccount: true,
11
+ });
12
+ function JazzProvider(props) {
13
+ return (_jsx(JazzTestProvider, { account: account, children: props.children }));
14
+ }
15
+ return {
16
+ ...(await importOriginal()),
17
+ JazzProvider,
18
+ };
19
+ });
20
+ const authSecretStorage = new AuthSecretStorage();
21
+ KvStoreContext.getInstance().initialize(new InMemoryKVStore());
22
+ describe("JazzProviderWithClerk", () => {
23
+ beforeEach(async () => {
24
+ await authSecretStorage.clear();
25
+ });
26
+ const setup = (children = _jsx("div", { "data-testid": "test-child", children: "Test Content" })) => {
27
+ let callbacks = new Set();
28
+ const mockClerk = {
29
+ user: {
30
+ fullName: "Test User",
31
+ unsafeMetadata: {},
32
+ update: vi.fn(),
33
+ },
34
+ signOut: vi.fn().mockImplementation(() => {
35
+ mockClerk.user = null;
36
+ Array.from(callbacks).map((callback) => callback(mockClerk));
37
+ }),
38
+ addListener: vi.fn((callback) => {
39
+ callbacks.add(callback);
40
+ return () => {
41
+ callbacks.delete(callback);
42
+ };
43
+ }),
44
+ };
45
+ const utils = render(_jsx(JazzProviderWithClerk, { clerk: mockClerk, sync: { peer: "wss://test.jazz.tools" }, children: children }));
46
+ return {
47
+ ...utils,
48
+ mockClerk,
49
+ callbacks,
50
+ };
51
+ };
52
+ it("should push the local credentials to clerk", async () => {
53
+ const { mockClerk, callbacks } = setup();
54
+ expect(mockClerk.user?.update).not.toHaveBeenCalled();
55
+ await act(async () => {
56
+ await Promise.all(Array.from(callbacks).map((callback) => callback(mockClerk)));
57
+ });
58
+ expect(mockClerk.user?.update).toHaveBeenCalledWith({
59
+ unsafeMetadata: {
60
+ jazzAccountID: expect.any(String),
61
+ jazzAccountSecret: expect.any(String),
62
+ jazzAccountSeed: expect.any(Array),
63
+ },
64
+ });
65
+ });
66
+ });
67
+ //# sourceMappingURL=JazzProviderWithClerk.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JazzProviderWithClerk.test.js","sourceRoot":"","sources":["../../src/tests/JazzProviderWithClerk.test.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,20 +1,21 @@
1
1
  {
2
2
  "name": "jazz-react-auth-clerk",
3
- "version": "0.9.23",
3
+ "version": "0.10.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "src/index.tsx",
7
7
  "license": "MIT",
8
8
  "dependencies": {
9
- "cojson": "0.9.23",
10
- "jazz-browser-auth-clerk": "0.9.23",
11
- "jazz-react": "0.9.23",
12
- "jazz-tools": "0.9.23"
9
+ "cojson": "0.10.1",
10
+ "jazz-react": "0.10.1",
11
+ "jazz-tools": "0.10.1",
12
+ "jazz-auth-clerk": "0.10.1"
13
13
  },
14
14
  "peerDependencies": {
15
15
  "react": "^18.2.0"
16
16
  },
17
17
  "devDependencies": {
18
+ "@testing-library/react": "^16.1.0",
18
19
  "@types/react": "^18.3.12",
19
20
  "typescript": "~5.6.2"
20
21
  },
package/src/index.tsx CHANGED
@@ -1,23 +1,49 @@
1
- import { BrowserClerkAuth, MinimalClerkClient } from "jazz-browser-auth-clerk";
2
- import { useMemo, useState } from "react";
1
+ import { JazzClerkAuth, type MinimalClerkClient } from "jazz-auth-clerk";
2
+ import {
3
+ JazzProvider,
4
+ JazzProviderProps,
5
+ useAuthSecretStorage,
6
+ useJazzContext,
7
+ } from "jazz-react";
8
+ import { useEffect, useMemo } from "react";
3
9
 
4
- export function useJazzClerkAuth(clerk: MinimalClerkClient) {
5
- const [state, setState] = useState<{ errors: string[] }>({ errors: [] });
10
+ function useJazzClerkAuth(clerk: MinimalClerkClient) {
11
+ const context = useJazzContext();
12
+ const authSecretStorage = useAuthSecretStorage();
13
+
14
+ if ("guest" in context) {
15
+ throw new Error("Clerk auth is not supported in guest mode");
16
+ }
6
17
 
7
18
  const authMethod = useMemo(() => {
8
- return new BrowserClerkAuth(
9
- {
10
- onError: (error) => {
11
- void clerk.signOut();
12
- setState((state) => ({
13
- ...state,
14
- errors: [...state.errors, error.toString()],
15
- }));
16
- },
17
- },
18
- clerk,
19
- );
20
- }, [clerk.user]);
19
+ return new JazzClerkAuth(context.authenticate, authSecretStorage);
20
+ }, []);
21
21
 
22
- return [authMethod, state] as const;
22
+ useEffect(() => {
23
+ // Need to use addListener because the clerk user object is not updated when the user logs in
24
+ return clerk.addListener((event) => {
25
+ authMethod.onClerkUserChange(event as Pick<MinimalClerkClient, "user">);
26
+ });
27
+ }, []);
23
28
  }
29
+
30
+ function RegisterClerkAuth(props: {
31
+ clerk: MinimalClerkClient;
32
+ children: React.ReactNode;
33
+ }) {
34
+ useJazzClerkAuth(props.clerk);
35
+
36
+ return props.children;
37
+ }
38
+
39
+ export const JazzProviderWithClerk = (
40
+ props: { clerk: MinimalClerkClient } & JazzProviderProps,
41
+ ) => {
42
+ return (
43
+ <JazzProvider {...props} onLogOut={props.clerk.signOut}>
44
+ <RegisterClerkAuth clerk={props.clerk}>
45
+ {props.children}
46
+ </RegisterClerkAuth>
47
+ </JazzProvider>
48
+ );
49
+ };
@@ -0,0 +1,97 @@
1
+ // @vitest-environment happy-dom
2
+
3
+ import { act, render, waitFor } from "@testing-library/react";
4
+ import type { MinimalClerkClient } from "jazz-auth-clerk";
5
+ import { AuthSecretStorage, InMemoryKVStore, KvStoreContext } from "jazz-tools";
6
+ import { beforeEach, describe, expect, it, vi } from "vitest";
7
+ import { JazzProviderWithClerk } from "../index";
8
+
9
+ vi.mock("jazz-react", async (importOriginal) => {
10
+ const { JazzTestProvider, createJazzTestAccount } = await import(
11
+ "jazz-react/testing"
12
+ );
13
+
14
+ const account = await createJazzTestAccount({
15
+ isCurrentActiveAccount: true,
16
+ });
17
+
18
+ function JazzProvider(props: { children: React.ReactNode }) {
19
+ return (
20
+ <JazzTestProvider account={account}>{props.children}</JazzTestProvider>
21
+ );
22
+ }
23
+
24
+ return {
25
+ ...(await importOriginal<typeof import("jazz-react")>()),
26
+ JazzProvider,
27
+ };
28
+ });
29
+
30
+ const authSecretStorage = new AuthSecretStorage();
31
+ KvStoreContext.getInstance().initialize(new InMemoryKVStore());
32
+
33
+ describe("JazzProviderWithClerk", () => {
34
+ beforeEach(async () => {
35
+ await authSecretStorage.clear();
36
+ });
37
+
38
+ const setup = (
39
+ children = <div data-testid="test-child">Test Content</div>,
40
+ ) => {
41
+ let callbacks = new Set<(clerk: MinimalClerkClient) => void>();
42
+
43
+ const mockClerk = {
44
+ user: {
45
+ fullName: "Test User",
46
+ unsafeMetadata: {},
47
+ update: vi.fn(),
48
+ },
49
+ signOut: vi.fn().mockImplementation(() => {
50
+ mockClerk.user = null;
51
+ Array.from(callbacks).map((callback) => callback(mockClerk));
52
+ }),
53
+ addListener: vi.fn((callback) => {
54
+ callbacks.add(callback);
55
+
56
+ return () => {
57
+ callbacks.delete(callback);
58
+ };
59
+ }),
60
+ } as unknown as MinimalClerkClient;
61
+
62
+ const utils = render(
63
+ <JazzProviderWithClerk
64
+ clerk={mockClerk}
65
+ sync={{ peer: "wss://test.jazz.tools" }}
66
+ >
67
+ {children}
68
+ </JazzProviderWithClerk>,
69
+ );
70
+
71
+ return {
72
+ ...utils,
73
+ mockClerk,
74
+ callbacks,
75
+ };
76
+ };
77
+
78
+ it("should push the local credentials to clerk", async () => {
79
+ const { mockClerk, callbacks } = setup();
80
+
81
+ expect(mockClerk.user?.update).not.toHaveBeenCalled();
82
+
83
+ await act(async () => {
84
+ await Promise.all(
85
+ Array.from(callbacks).map((callback) => callback(mockClerk)),
86
+ );
87
+ });
88
+
89
+ expect(mockClerk.user?.update).toHaveBeenCalledWith({
90
+ unsafeMetadata: {
91
+ jazzAccountID: expect.any(String),
92
+ jazzAccountSecret: expect.any(String),
93
+ jazzAccountSeed: expect.any(Array),
94
+ },
95
+ });
96
+ });
97
+ });