jazz-tools 0.17.14 → 0.18.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.
- package/.svelte-kit/__package__/jazz.class.svelte.js +1 -1
- package/.svelte-kit/__package__/media/image.svelte +3 -9
- package/.svelte-kit/__package__/media/image.svelte.d.ts +1 -6
- package/.svelte-kit/__package__/media/image.svelte.d.ts.map +1 -1
- package/.svelte-kit/__package__/media/image.types.d.ts +7 -0
- package/.svelte-kit/__package__/media/image.types.d.ts.map +1 -0
- package/.svelte-kit/__package__/media/image.types.js +1 -0
- package/.svelte-kit/__package__/tests/media/image.svelte.test.js +31 -31
- package/.turbo/turbo-build.log +60 -46
- package/CHANGELOG.md +41 -0
- package/dist/better-auth/auth/client.d.ts +29 -0
- package/dist/better-auth/auth/client.d.ts.map +1 -0
- package/dist/better-auth/auth/client.js +127 -0
- package/dist/better-auth/auth/client.js.map +1 -0
- package/dist/better-auth/auth/react.d.ts +2170 -0
- package/dist/better-auth/auth/react.d.ts.map +1 -0
- package/dist/better-auth/auth/react.js +40 -0
- package/dist/better-auth/auth/react.js.map +1 -0
- package/dist/better-auth/auth/server.d.ts +14 -0
- package/dist/better-auth/auth/server.d.ts.map +1 -0
- package/dist/better-auth/auth/server.js +198 -0
- package/dist/better-auth/auth/server.js.map +1 -0
- package/dist/better-auth/auth/tests/client.test.d.ts +2 -0
- package/dist/better-auth/auth/tests/client.test.d.ts.map +1 -0
- package/dist/better-auth/auth/tests/server.test.d.ts +2 -0
- package/dist/better-auth/auth/tests/server.test.d.ts.map +1 -0
- package/dist/browser/index.js +2 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/{chunk-LZOF6WP5.js → chunk-IERUTUXB.js} +1336 -1017
- package/dist/chunk-IERUTUXB.js.map +1 -0
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/dist/inspector/{custom-element-ZSNTCECD.js → custom-element-WCY6D3QJ.js} +3 -3
- package/dist/inspector/{custom-element-ZSNTCECD.js.map → custom-element-WCY6D3QJ.js.map} +1 -1
- package/dist/inspector/index.js +1 -1
- package/dist/inspector/index.js.map +1 -1
- package/dist/inspector/register-custom-element.js +1 -1
- package/dist/media/{chunk-E5J3WLQW.js → chunk-KR2V6X2N.js} +14 -9
- package/dist/media/chunk-KR2V6X2N.js.map +1 -0
- package/dist/media/create-image.d.ts +6 -6
- package/dist/media/index.browser.d.ts +6 -6
- package/dist/media/index.browser.js +1 -1
- package/dist/media/index.d.ts +1 -1
- package/dist/media/index.js +1 -1
- package/dist/media/index.native.d.ts +6 -6
- package/dist/media/index.native.js +1 -1
- package/dist/media/utils.d.ts.map +1 -1
- package/dist/prosemirror/index.js +2 -2
- package/dist/prosemirror/index.js.map +1 -1
- package/dist/react/index.js +7 -5
- package/dist/react/index.js.map +1 -1
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +4675 -23
- package/dist/react-core/index.js.map +1 -1
- package/dist/react-native-core/index.js +1 -1
- package/dist/react-native-core/index.js.map +1 -1
- package/dist/svelte/jazz.class.svelte.js +1 -1
- package/dist/svelte/media/image.svelte +3 -9
- package/dist/svelte/media/image.svelte.d.ts +1 -6
- package/dist/svelte/media/image.svelte.d.ts.map +1 -1
- package/dist/svelte/media/image.types.d.ts +7 -0
- package/dist/svelte/media/image.types.d.ts.map +1 -0
- package/dist/svelte/media/image.types.js +1 -0
- package/dist/svelte/tests/media/image.svelte.test.js +31 -31
- package/dist/testing.js +18 -14
- package/dist/testing.js.map +1 -1
- package/dist/tools/coValues/CoFieldInit.d.ts +13 -0
- package/dist/tools/coValues/CoFieldInit.d.ts.map +1 -0
- package/dist/tools/coValues/CoValueBase.d.ts +18 -15
- package/dist/tools/coValues/CoValueBase.d.ts.map +1 -1
- package/dist/tools/coValues/account.d.ts +101 -46
- package/dist/tools/coValues/account.d.ts.map +1 -1
- package/dist/tools/coValues/coFeed.d.ts +78 -62
- package/dist/tools/coValues/coFeed.d.ts.map +1 -1
- package/dist/tools/coValues/coList.d.ts +212 -99
- package/dist/tools/coValues/coList.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +210 -192
- package/dist/tools/coValues/coMap.d.ts.map +1 -1
- package/dist/tools/coValues/coPlainText.d.ts +30 -22
- package/dist/tools/coValues/coPlainText.d.ts.map +1 -1
- package/dist/tools/coValues/deepLoading.d.ts +13 -13
- package/dist/tools/coValues/deepLoading.d.ts.map +1 -1
- package/dist/tools/coValues/extensions/imageDef.d.ts +1 -1
- package/dist/tools/coValues/group.d.ts +32 -32
- package/dist/tools/coValues/group.d.ts.map +1 -1
- package/dist/tools/coValues/inbox.d.ts.map +1 -1
- package/dist/tools/coValues/interfaces.d.ts +18 -17
- package/dist/tools/coValues/interfaces.d.ts.map +1 -1
- package/dist/tools/coValues/profile.d.ts +6 -5
- package/dist/tools/coValues/profile.d.ts.map +1 -1
- package/dist/tools/coValues/schemaUnion.d.ts +3 -3
- package/dist/tools/coValues/schemaUnion.d.ts.map +1 -1
- package/dist/tools/exports.d.ts +1 -1
- package/dist/tools/exports.d.ts.map +1 -1
- package/dist/tools/implementation/anonymousJazzAgent.d.ts +2 -1
- package/dist/tools/implementation/anonymousJazzAgent.d.ts.map +1 -1
- package/dist/tools/implementation/schema.d.ts +5 -5
- package/dist/tools/implementation/schema.d.ts.map +1 -1
- package/dist/tools/implementation/symbols.d.ts +2 -0
- package/dist/tools/implementation/symbols.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts +2 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/AccountSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts +6 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts +8 -3
- package/dist/tools/implementation/zodSchema/schemaTypes/CoListSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts +12 -7
- package/dist/tools/implementation/zodSchema/schemaTypes/CoMapSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts +13 -7
- package/dist/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts +11 -2
- package/dist/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts +4 -0
- package/dist/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts +4 -0
- package/dist/tools/implementation/zodSchema/schemaTypes/RichTextSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/{CoFieldInit.d.ts → CoFieldSchemaInit.d.ts} +7 -7
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldSchemaInit.d.ts.map +1 -0
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts +4 -4
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts +4 -4
- package/dist/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts +3 -3
- package/dist/tools/implementation/zodSchema/zodCo.d.ts.map +1 -1
- package/dist/tools/internal.d.ts +2 -1
- package/dist/tools/internal.d.ts.map +1 -1
- package/dist/tools/lib/migration.d.ts +1 -1
- package/dist/tools/lib/migration.d.ts.map +1 -1
- package/dist/tools/subscribe/SubscriptionScope.d.ts.map +1 -1
- package/dist/tools/subscribe/index.d.ts +1 -1
- package/dist/tools/subscribe/index.d.ts.map +1 -1
- package/dist/tools/subscribe/utils.d.ts +2 -2
- package/dist/tools/subscribe/utils.d.ts.map +1 -1
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/tests/utils.d.ts +2 -6
- package/dist/tools/tests/utils.d.ts.map +1 -1
- package/dist/worker/index.js +3 -3
- package/dist/worker/index.js.map +1 -1
- package/package.json +23 -4
- package/src/better-auth/auth/client.ts +169 -0
- package/src/better-auth/auth/react.tsx +105 -0
- package/src/better-auth/auth/server.ts +250 -0
- package/src/better-auth/auth/tests/client.test.ts +249 -0
- package/src/better-auth/auth/tests/server.test.ts +226 -0
- package/src/browser/auth/PasskeyAuth.ts +2 -2
- package/src/browser/createBrowserContext.ts +2 -2
- package/src/browser/tests/PasskeyAuth.test.ts +2 -2
- package/src/inspector/custom-element.tsx +2 -2
- package/src/inspector/viewer/new-app.tsx +1 -1
- package/src/media/create-image.test.ts +7 -7
- package/src/media/create-image.ts +5 -3
- package/src/media/index.ts +1 -1
- package/src/media/utils.test.ts +72 -66
- package/src/media/utils.ts +9 -6
- package/src/prosemirror/lib/plugin.ts +1 -1
- package/src/prosemirror/lib/sync.ts +1 -1
- package/src/prosemirror/tests/plugin.test.ts +4 -4
- package/src/react/media/image.tsx +2 -2
- package/src/react/tests/media/image.test.tsx +52 -32
- package/src/react-core/hooks.ts +11 -5
- package/src/react-core/tests/useAccount.test.ts +16 -22
- package/src/react-core/tests/useCoState.test.ts +19 -19
- package/src/react-core/tests/useInboxSender.test.ts +5 -2
- package/src/react-core/tests/usePassPhraseAuth.test.ts +6 -6
- package/src/react-native-core/media/image.tsx +1 -1
- package/src/svelte/jazz.class.svelte.ts +1 -1
- package/src/svelte/media/image.svelte +3 -9
- package/src/svelte/media/image.types.ts +7 -0
- package/src/svelte/tests/media/image.svelte.test.ts +34 -32
- package/src/tools/auth/DemoAuth.ts +2 -2
- package/src/tools/auth/PassphraseAuth.ts +2 -2
- package/src/tools/auth/clerk/index.ts +2 -2
- package/src/tools/auth/clerk/tests/JazzClerkAuth.test.ts +1 -1
- package/src/tools/coValues/CoFieldInit.ts +20 -0
- package/src/tools/coValues/CoValueBase.ts +40 -60
- package/src/tools/coValues/account.ts +311 -232
- package/src/tools/coValues/coFeed.ts +185 -153
- package/src/tools/coValues/coList.ts +507 -334
- package/src/tools/coValues/coMap.ts +434 -286
- package/src/tools/coValues/coPlainText.ts +94 -110
- package/src/tools/coValues/deepLoading.ts +13 -13
- package/src/tools/coValues/group.ts +100 -114
- package/src/tools/coValues/inbox.ts +16 -14
- package/src/tools/coValues/interfaces.ts +49 -31
- package/src/tools/coValues/profile.ts +8 -6
- package/src/tools/coValues/request.ts +9 -9
- package/src/tools/coValues/schemaUnion.ts +11 -5
- package/src/tools/exports.ts +1 -1
- package/src/tools/implementation/ContextManager.ts +4 -4
- package/src/tools/implementation/anonymousJazzAgent.ts +2 -1
- package/src/tools/implementation/createContext.ts +1 -1
- package/src/tools/implementation/devtoolsFormatters.ts +9 -9
- package/src/tools/implementation/invites.ts +2 -2
- package/src/tools/implementation/schema.ts +7 -7
- package/src/tools/implementation/symbols.ts +3 -0
- package/src/tools/implementation/zodSchema/schemaTypes/AccountSchema.ts +2 -2
- package/src/tools/implementation/zodSchema/schemaTypes/CoFeedSchema.ts +11 -2
- package/src/tools/implementation/zodSchema/schemaTypes/CoListSchema.ts +18 -7
- package/src/tools/implementation/zodSchema/schemaTypes/CoMapSchema.ts +17 -7
- package/src/tools/implementation/zodSchema/schemaTypes/CoRecordSchema.ts +20 -11
- package/src/tools/implementation/zodSchema/schemaTypes/FileStreamSchema.ts +19 -2
- package/src/tools/implementation/zodSchema/schemaTypes/PlainTextSchema.ts +6 -0
- package/src/tools/implementation/zodSchema/schemaTypes/RichTextSchema.ts +6 -0
- package/src/tools/implementation/zodSchema/typeConverters/{CoFieldInit.ts → CoFieldSchemaInit.ts} +11 -11
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchema.ts +4 -4
- package/src/tools/implementation/zodSchema/typeConverters/InstanceOfSchemaCoValuesNullable.ts +4 -4
- package/src/tools/implementation/zodSchema/zodCo.ts +3 -3
- package/src/tools/internal.ts +2 -1
- package/src/tools/lib/migration.ts +5 -5
- package/src/tools/subscribe/SubscriptionScope.ts +32 -24
- package/src/tools/subscribe/index.ts +4 -4
- package/src/tools/subscribe/utils.ts +11 -11
- package/src/tools/testing.ts +17 -13
- package/src/tools/tests/ContextManager.test.ts +70 -59
- package/src/tools/tests/PassphraseAuth.test.ts +2 -2
- package/src/tools/tests/account.test.ts +188 -67
- package/src/tools/tests/coDiscriminatedUnion.test-d.ts +12 -6
- package/src/tools/tests/coDiscriminatedUnion.test.ts +26 -17
- package/src/tools/tests/coFeed.test-d.ts +18 -17
- package/src/tools/tests/coFeed.test.ts +108 -97
- package/src/tools/tests/coList.test-d.ts +18 -23
- package/src/tools/tests/coList.test.ts +350 -165
- package/src/tools/tests/coMap.record.test-d.ts +9 -13
- package/src/tools/tests/coMap.record.test.ts +37 -23
- package/src/tools/tests/coMap.test-d.ts +43 -21
- package/src/tools/tests/coMap.test.ts +459 -182
- package/src/tools/tests/coOptional.test.ts +28 -13
- package/src/tools/tests/coPlainText.test.ts +15 -15
- package/src/tools/tests/createContext.test.ts +14 -14
- package/src/tools/tests/deepLoading.test.ts +95 -94
- package/src/tools/tests/exportImport.test.ts +61 -41
- package/src/tools/tests/groupsAndAccounts.test.ts +333 -116
- package/src/tools/tests/inbox.test.ts +22 -17
- package/src/tools/tests/interfaces.test.ts +12 -11
- package/src/tools/tests/invites.test.ts +6 -4
- package/src/tools/tests/load.test.ts +20 -18
- package/src/tools/tests/patterns/notifications.test.ts +7 -7
- package/src/tools/tests/patterns/quest.test.ts +3 -3
- package/src/tools/tests/patterns/requestToJoin.test.ts +22 -22
- package/src/tools/tests/request.test.ts +38 -39
- package/src/tools/tests/schemaUnion.test.ts +64 -10
- package/src/tools/tests/subscribe.test.ts +64 -64
- package/src/tools/tests/testing.test.ts +7 -11
- package/src/tools/tests/utils.ts +3 -3
- package/src/tools/tests/zod.test.ts +3 -3
- package/src/worker/index.ts +3 -3
- package/tsup.config.ts +9 -0
- package/dist/chunk-LZOF6WP5.js.map +0 -1
- package/dist/media/chunk-E5J3WLQW.js.map +0 -1
- package/dist/tools/implementation/zodSchema/typeConverters/CoFieldInit.d.ts.map +0 -1
@@ -0,0 +1,249 @@
|
|
1
|
+
import { createAuthClient } from "better-auth/client";
|
2
|
+
import type { Account, AuthSecretStorage } from "jazz-tools";
|
3
|
+
import {
|
4
|
+
TestJazzContextManager,
|
5
|
+
setActiveAccount,
|
6
|
+
setupJazzTestSync,
|
7
|
+
} from "jazz-tools/testing";
|
8
|
+
import { assert, beforeEach, describe, expect, it, vi } from "vitest";
|
9
|
+
import { jazzPluginClient } from "../client.js";
|
10
|
+
|
11
|
+
describe("auth client", () => {
|
12
|
+
let account: Account;
|
13
|
+
let jazzContextManager: TestJazzContextManager<Account>;
|
14
|
+
let authSecretStorage: AuthSecretStorage;
|
15
|
+
let authClient: ReturnType<
|
16
|
+
typeof createAuthClient<{
|
17
|
+
plugins: ReturnType<typeof jazzPluginClient>[];
|
18
|
+
}>
|
19
|
+
>;
|
20
|
+
let customFetchImpl = vi.fn();
|
21
|
+
|
22
|
+
beforeEach(async () => {
|
23
|
+
account = await setupJazzTestSync();
|
24
|
+
setActiveAccount(account);
|
25
|
+
|
26
|
+
jazzContextManager = TestJazzContextManager.fromAccountOrGuest(account);
|
27
|
+
authSecretStorage = jazzContextManager.getAuthSecretStorage();
|
28
|
+
|
29
|
+
// start a new context
|
30
|
+
await jazzContextManager.createContext({});
|
31
|
+
|
32
|
+
authClient = createAuthClient({
|
33
|
+
baseURL: "http://localhost:3000",
|
34
|
+
plugins: [jazzPluginClient()],
|
35
|
+
fetchOptions: {
|
36
|
+
customFetchImpl,
|
37
|
+
},
|
38
|
+
});
|
39
|
+
|
40
|
+
const context = jazzContextManager.getCurrentValue();
|
41
|
+
assert(context, "Jazz context is not available");
|
42
|
+
authClient.jazz.setJazzContext(context);
|
43
|
+
authClient.jazz.setAuthSecretStorage(authSecretStorage);
|
44
|
+
|
45
|
+
customFetchImpl.mockReset();
|
46
|
+
});
|
47
|
+
|
48
|
+
it("should send Jazz credentials over signup", async () => {
|
49
|
+
const credentials = await authSecretStorage.get();
|
50
|
+
expect(authSecretStorage.isAuthenticated).toBe(false);
|
51
|
+
assert(credentials, "Jazz credentials are not available");
|
52
|
+
|
53
|
+
customFetchImpl.mockResolvedValue(
|
54
|
+
new Response(
|
55
|
+
JSON.stringify({
|
56
|
+
token: "6diDScDDcLJLl3sxAEestZz63mrw9Azy",
|
57
|
+
user: {
|
58
|
+
id: "S6SDKApdnh746gUnP3zujzsEY53tjuTm",
|
59
|
+
email: "test@jazz.dev",
|
60
|
+
name: "Matteo",
|
61
|
+
image: null,
|
62
|
+
emailVerified: false,
|
63
|
+
createdAt: new Date(),
|
64
|
+
updatedAt: new Date(),
|
65
|
+
},
|
66
|
+
jazzAuth: {
|
67
|
+
accountID: credentials.accountID,
|
68
|
+
secretSeed: credentials.secretSeed,
|
69
|
+
accountSecret: credentials.accountSecret,
|
70
|
+
},
|
71
|
+
}),
|
72
|
+
),
|
73
|
+
);
|
74
|
+
|
75
|
+
// Sign up
|
76
|
+
await authClient.signUp.email({
|
77
|
+
email: "test@jazz.dev",
|
78
|
+
password: "12345678",
|
79
|
+
name: "Matteo",
|
80
|
+
});
|
81
|
+
|
82
|
+
expect(customFetchImpl).toHaveBeenCalledTimes(1);
|
83
|
+
expect(customFetchImpl.mock.calls[0]![0].toString()).toBe(
|
84
|
+
"http://localhost:3000/api/auth/sign-up/email",
|
85
|
+
);
|
86
|
+
|
87
|
+
// Verify the credentials have been injected in the request body
|
88
|
+
expect(
|
89
|
+
customFetchImpl.mock.calls[0]![1].headers.get("x-jazz-auth")!,
|
90
|
+
).toEqual(
|
91
|
+
JSON.stringify({
|
92
|
+
accountID: credentials!.accountID,
|
93
|
+
secretSeed: credentials!.secretSeed,
|
94
|
+
accountSecret: credentials!.accountSecret,
|
95
|
+
}),
|
96
|
+
);
|
97
|
+
|
98
|
+
expect(authSecretStorage.isAuthenticated).toBe(true);
|
99
|
+
|
100
|
+
// Verify the profile name has been updated
|
101
|
+
const context = jazzContextManager.getCurrentValue();
|
102
|
+
assert(context && "me" in context);
|
103
|
+
expect(context.me.$jazz.id).toBe(credentials!.accountID);
|
104
|
+
});
|
105
|
+
|
106
|
+
it("should become logged in Jazz credentials after sign-in", async () => {
|
107
|
+
const credentials = await jazzContextManager.getAuthSecretStorage().get();
|
108
|
+
|
109
|
+
// Log out from initial context
|
110
|
+
await jazzContextManager.logOut();
|
111
|
+
expect(authSecretStorage.isAuthenticated).toBe(false);
|
112
|
+
|
113
|
+
customFetchImpl.mockResolvedValue(
|
114
|
+
new Response(
|
115
|
+
JSON.stringify({
|
116
|
+
user: {
|
117
|
+
id: "123",
|
118
|
+
email: "test@jazz.dev",
|
119
|
+
name: "Matteo",
|
120
|
+
},
|
121
|
+
jazzAuth: {
|
122
|
+
accountID: credentials!.accountID,
|
123
|
+
secretSeed: credentials!.secretSeed,
|
124
|
+
accountSecret: credentials!.accountSecret,
|
125
|
+
provider: "better-auth",
|
126
|
+
},
|
127
|
+
}),
|
128
|
+
),
|
129
|
+
);
|
130
|
+
|
131
|
+
// Retrieve the BetterAuth session and trigger the authentication
|
132
|
+
await authClient.signIn.email({
|
133
|
+
email: "test@jazz.dev",
|
134
|
+
password: "12345678",
|
135
|
+
});
|
136
|
+
|
137
|
+
expect(customFetchImpl).toHaveBeenCalledTimes(1);
|
138
|
+
expect(customFetchImpl.mock.calls[0]![0].toString()).toBe(
|
139
|
+
"http://localhost:3000/api/auth/sign-in/email",
|
140
|
+
);
|
141
|
+
|
142
|
+
expect(authSecretStorage.isAuthenticated).toBe(true);
|
143
|
+
|
144
|
+
const newContext = jazzContextManager.getCurrentValue()!;
|
145
|
+
expect("me" in newContext).toBe(true);
|
146
|
+
expect(await authSecretStorage.get()).toMatchObject({
|
147
|
+
accountID: credentials!.accountID,
|
148
|
+
provider: "better-auth",
|
149
|
+
});
|
150
|
+
});
|
151
|
+
|
152
|
+
it("should logout from Jazz after BetterAuth sign-out", async () => {
|
153
|
+
const credentials = await authSecretStorage.get();
|
154
|
+
expect(authSecretStorage.isAuthenticated).toBe(false);
|
155
|
+
customFetchImpl.mockResolvedValueOnce(
|
156
|
+
new Response(
|
157
|
+
JSON.stringify({
|
158
|
+
token: "6diDScDDcLJLl3sxAEestZz63mrw9Azy",
|
159
|
+
user: {
|
160
|
+
id: "S6SDKApdnh746gUnP3zujzsEY53tjuTm",
|
161
|
+
email: "test@jazz.dev",
|
162
|
+
name: "Matteo",
|
163
|
+
image: null,
|
164
|
+
emailVerified: false,
|
165
|
+
createdAt: new Date(),
|
166
|
+
updatedAt: new Date(),
|
167
|
+
},
|
168
|
+
jazzAuth: {
|
169
|
+
accountID: credentials!.accountID,
|
170
|
+
secretSeed: credentials!.secretSeed,
|
171
|
+
accountSecret: credentials!.accountSecret,
|
172
|
+
provider: "better-auth",
|
173
|
+
},
|
174
|
+
}),
|
175
|
+
),
|
176
|
+
);
|
177
|
+
|
178
|
+
// 1. Sign up
|
179
|
+
await authClient.signUp.email({
|
180
|
+
email: "test@jazz.dev",
|
181
|
+
password: "12345678",
|
182
|
+
name: "Matteo",
|
183
|
+
});
|
184
|
+
|
185
|
+
expect(authSecretStorage.isAuthenticated).toBe(true);
|
186
|
+
|
187
|
+
// 2. Sign out
|
188
|
+
customFetchImpl.mockResolvedValueOnce(
|
189
|
+
new Response(JSON.stringify({ success: true })),
|
190
|
+
);
|
191
|
+
|
192
|
+
await authClient.signOut();
|
193
|
+
|
194
|
+
expect(authSecretStorage.isAuthenticated).toBe(false);
|
195
|
+
|
196
|
+
const anonymousCredentials = await authSecretStorage.get();
|
197
|
+
expect(anonymousCredentials).not.toMatchObject(credentials!);
|
198
|
+
});
|
199
|
+
|
200
|
+
it("should logout from Jazz after BetterAuth user deletion", async () => {
|
201
|
+
const credentials = await authSecretStorage.get();
|
202
|
+
expect(authSecretStorage.isAuthenticated).toBe(false);
|
203
|
+
customFetchImpl.mockResolvedValueOnce(
|
204
|
+
new Response(
|
205
|
+
JSON.stringify({
|
206
|
+
token: "6diDScDDcLJLl3sxAEestZz63mrw9Azy",
|
207
|
+
user: {
|
208
|
+
id: "S6SDKApdnh746gUnP3zujzsEY53tjuTm",
|
209
|
+
email: "test@jazz.dev",
|
210
|
+
name: "Matteo",
|
211
|
+
image: null,
|
212
|
+
emailVerified: false,
|
213
|
+
createdAt: new Date(),
|
214
|
+
updatedAt: new Date(),
|
215
|
+
},
|
216
|
+
jazzAuth: {
|
217
|
+
accountID: credentials!.accountID,
|
218
|
+
secretSeed: credentials!.secretSeed,
|
219
|
+
accountSecret: credentials!.accountSecret,
|
220
|
+
provider: "better-auth",
|
221
|
+
},
|
222
|
+
}),
|
223
|
+
),
|
224
|
+
);
|
225
|
+
|
226
|
+
// 1. Sign up
|
227
|
+
await authClient.signUp.email({
|
228
|
+
email: "test@jazz.dev",
|
229
|
+
password: "12345678",
|
230
|
+
name: "Matteo",
|
231
|
+
});
|
232
|
+
|
233
|
+
expect(authSecretStorage.isAuthenticated).toBe(true);
|
234
|
+
|
235
|
+
// 2. Delete user
|
236
|
+
customFetchImpl.mockResolvedValueOnce(
|
237
|
+
new Response(JSON.stringify({ success: true })),
|
238
|
+
);
|
239
|
+
|
240
|
+
await authClient.deleteUser();
|
241
|
+
|
242
|
+
expect(authSecretStorage.isAuthenticated).toBe(false);
|
243
|
+
|
244
|
+
const anonymousCredentials = await authSecretStorage.get();
|
245
|
+
expect(anonymousCredentials).not.toMatchObject(credentials!);
|
246
|
+
});
|
247
|
+
|
248
|
+
it.todo("should logout from Better Auth after Jazz's log-out");
|
249
|
+
});
|
@@ -0,0 +1,226 @@
|
|
1
|
+
import { betterAuth } from "better-auth";
|
2
|
+
import { memoryAdapter } from "better-auth/adapters/memory";
|
3
|
+
import { beforeEach, describe, expect, it, vi, type Mock } from "vitest";
|
4
|
+
import { jazzPlugin } from "../server.js";
|
5
|
+
|
6
|
+
describe("Better Auth - Signup and Login Tests", () => {
|
7
|
+
let auth: ReturnType<typeof betterAuth>;
|
8
|
+
let accountCreationSpy: Mock;
|
9
|
+
let verificationCreationSpy: Mock;
|
10
|
+
|
11
|
+
beforeEach(() => {
|
12
|
+
accountCreationSpy = vi.fn();
|
13
|
+
verificationCreationSpy = vi.fn();
|
14
|
+
|
15
|
+
// Create auth instance with in-memory database
|
16
|
+
auth = betterAuth({
|
17
|
+
database: memoryAdapter({
|
18
|
+
user: [],
|
19
|
+
session: [],
|
20
|
+
verification: [],
|
21
|
+
account: [],
|
22
|
+
}),
|
23
|
+
plugins: [jazzPlugin()],
|
24
|
+
emailAndPassword: {
|
25
|
+
enabled: true,
|
26
|
+
requireEmailVerification: false, // Disable for testing
|
27
|
+
},
|
28
|
+
socialProviders: {
|
29
|
+
github: {
|
30
|
+
clientId: "123",
|
31
|
+
clientSecret: "123",
|
32
|
+
},
|
33
|
+
},
|
34
|
+
databaseHooks: {
|
35
|
+
user: {
|
36
|
+
create: {
|
37
|
+
after: accountCreationSpy,
|
38
|
+
},
|
39
|
+
},
|
40
|
+
verification: {
|
41
|
+
create: {
|
42
|
+
after: verificationCreationSpy,
|
43
|
+
},
|
44
|
+
},
|
45
|
+
},
|
46
|
+
session: {
|
47
|
+
expiresIn: 60 * 60 * 24 * 7, // 7 days
|
48
|
+
},
|
49
|
+
});
|
50
|
+
});
|
51
|
+
|
52
|
+
describe("User Registration (Signup)", () => {
|
53
|
+
it("should successfully register a new user with email and password", async () => {
|
54
|
+
const userData = {
|
55
|
+
name: "test",
|
56
|
+
email: "test@example.com",
|
57
|
+
password: "securePassword123",
|
58
|
+
};
|
59
|
+
|
60
|
+
const jazzAuth = {
|
61
|
+
accountID: "123",
|
62
|
+
secretSeed: [1, 2, 3],
|
63
|
+
accountSecret: "123",
|
64
|
+
provider: "better-auth",
|
65
|
+
};
|
66
|
+
|
67
|
+
const result = await auth.api.signUpEmail({
|
68
|
+
body: userData,
|
69
|
+
headers: {
|
70
|
+
"x-jazz-auth": JSON.stringify(jazzAuth),
|
71
|
+
},
|
72
|
+
});
|
73
|
+
|
74
|
+
expect(result).toBeDefined();
|
75
|
+
expect(result).toMatchObject({
|
76
|
+
user: {
|
77
|
+
id: expect.any(String),
|
78
|
+
email: userData.email,
|
79
|
+
name: userData.name,
|
80
|
+
image: undefined,
|
81
|
+
emailVerified: false,
|
82
|
+
createdAt: expect.any(Date),
|
83
|
+
updatedAt: expect.any(Date),
|
84
|
+
},
|
85
|
+
jazzAuth: jazzAuth,
|
86
|
+
});
|
87
|
+
|
88
|
+
const res = await (await auth.$context).adapter.findOne({
|
89
|
+
model: "user",
|
90
|
+
where: [
|
91
|
+
{
|
92
|
+
field: "id",
|
93
|
+
value: result.user.id,
|
94
|
+
},
|
95
|
+
],
|
96
|
+
});
|
97
|
+
|
98
|
+
expect(res).toMatchObject({
|
99
|
+
id: result.user.id,
|
100
|
+
accountID: "123",
|
101
|
+
encryptedCredentials: expect.any(String),
|
102
|
+
});
|
103
|
+
});
|
104
|
+
|
105
|
+
it("should fail to register user without account ID", async () => {
|
106
|
+
const userData = {
|
107
|
+
name: "test",
|
108
|
+
email: "email@email.it",
|
109
|
+
password: "securePassword123",
|
110
|
+
};
|
111
|
+
|
112
|
+
await expect(
|
113
|
+
auth.api.signUpEmail({
|
114
|
+
body: userData,
|
115
|
+
}),
|
116
|
+
).rejects.toThrow("JazzAuth is required");
|
117
|
+
|
118
|
+
expect(accountCreationSpy).toHaveBeenCalledTimes(0);
|
119
|
+
});
|
120
|
+
|
121
|
+
it("should have AccountID in the registration hook", async () => {
|
122
|
+
const userData = {
|
123
|
+
name: "test",
|
124
|
+
email: "email@email.it",
|
125
|
+
password: "securePassword123",
|
126
|
+
};
|
127
|
+
|
128
|
+
const jazzAuth = {
|
129
|
+
accountID: "123",
|
130
|
+
secretSeed: [1, 2, 3],
|
131
|
+
accountSecret: "123",
|
132
|
+
provider: "better-auth",
|
133
|
+
};
|
134
|
+
|
135
|
+
await auth.api.signUpEmail({
|
136
|
+
body: userData,
|
137
|
+
headers: {
|
138
|
+
"x-jazz-auth": JSON.stringify(jazzAuth),
|
139
|
+
},
|
140
|
+
});
|
141
|
+
|
142
|
+
expect(accountCreationSpy).toHaveBeenCalledTimes(1);
|
143
|
+
expect(accountCreationSpy).toHaveBeenCalledWith(
|
144
|
+
// user
|
145
|
+
expect.objectContaining({ accountID: "123" }),
|
146
|
+
// context
|
147
|
+
expect.any(Object),
|
148
|
+
);
|
149
|
+
});
|
150
|
+
});
|
151
|
+
|
152
|
+
describe("User login (Signin)", () => {
|
153
|
+
it("should successfully login a new user with email and password", async () => {
|
154
|
+
const userData = {
|
155
|
+
name: "test",
|
156
|
+
email: "test@example.com",
|
157
|
+
password: "securePassword123",
|
158
|
+
};
|
159
|
+
|
160
|
+
const jazzAuth = {
|
161
|
+
accountID: "123",
|
162
|
+
secretSeed: [1, 2, 3],
|
163
|
+
accountSecret: "123",
|
164
|
+
provider: "better-auth",
|
165
|
+
};
|
166
|
+
|
167
|
+
await auth.api.signUpEmail({
|
168
|
+
body: userData,
|
169
|
+
headers: {
|
170
|
+
"x-jazz-auth": JSON.stringify(jazzAuth),
|
171
|
+
},
|
172
|
+
});
|
173
|
+
|
174
|
+
const result = await auth.api.signInEmail({
|
175
|
+
body: {
|
176
|
+
email: userData.email,
|
177
|
+
password: userData.password,
|
178
|
+
},
|
179
|
+
});
|
180
|
+
|
181
|
+
expect(result).toBeDefined();
|
182
|
+
expect(result).toMatchObject({
|
183
|
+
user: {
|
184
|
+
id: expect.any(String),
|
185
|
+
email: userData.email,
|
186
|
+
name: userData.name,
|
187
|
+
image: undefined,
|
188
|
+
emailVerified: false,
|
189
|
+
createdAt: expect.any(Date),
|
190
|
+
updatedAt: expect.any(Date),
|
191
|
+
},
|
192
|
+
jazzAuth: jazzAuth,
|
193
|
+
});
|
194
|
+
});
|
195
|
+
});
|
196
|
+
|
197
|
+
describe("Social Login", () => {
|
198
|
+
it("should store jazzAuth in verification table when using social provider", async () => {
|
199
|
+
await auth.api.signInSocial({
|
200
|
+
body: {
|
201
|
+
provider: "github",
|
202
|
+
callbackURL: "http://localhost:3000/api/auth/sign-in/social/callback",
|
203
|
+
},
|
204
|
+
headers: {
|
205
|
+
"x-jazz-auth": JSON.stringify({
|
206
|
+
accountID: "123",
|
207
|
+
secretSeed: [1, 2, 3],
|
208
|
+
accountSecret: "123",
|
209
|
+
}),
|
210
|
+
},
|
211
|
+
});
|
212
|
+
|
213
|
+
expect(verificationCreationSpy).toHaveBeenCalledTimes(1);
|
214
|
+
expect(verificationCreationSpy).toHaveBeenCalledWith(
|
215
|
+
expect.objectContaining({
|
216
|
+
value: expect.stringContaining('"accountID":"123"'),
|
217
|
+
}),
|
218
|
+
expect.any(Object),
|
219
|
+
);
|
220
|
+
});
|
221
|
+
|
222
|
+
it.todo(
|
223
|
+
"should create a new account with jazz auth when using social provider",
|
224
|
+
);
|
225
|
+
});
|
226
|
+
});
|
@@ -82,14 +82,14 @@ export class BrowserPasskeyAuth {
|
|
82
82
|
username,
|
83
83
|
});
|
84
84
|
|
85
|
-
const currentAccount = await Account.getMe().ensureLoaded({
|
85
|
+
const currentAccount = await Account.getMe().$jazz.ensureLoaded({
|
86
86
|
resolve: {
|
87
87
|
profile: true,
|
88
88
|
},
|
89
89
|
});
|
90
90
|
|
91
91
|
if (username.trim().length !== 0) {
|
92
|
-
currentAccount.profile.name
|
92
|
+
currentAccount.profile.$jazz.set("name", username);
|
93
93
|
}
|
94
94
|
|
95
95
|
await this.authSecretStorage.set({
|
@@ -272,7 +272,7 @@ export function createInviteLink<C extends CoValue>(
|
|
272
272
|
valueHint,
|
273
273
|
}: { baseURL?: string; valueHint?: string } = {},
|
274
274
|
): string {
|
275
|
-
const coValueCore = value.
|
275
|
+
const coValueCore = value.$jazz.raw.core;
|
276
276
|
let currentCoValue = coValueCore;
|
277
277
|
|
278
278
|
while (currentCoValue.verified.header.ruleset.type === "ownedByGroup") {
|
@@ -289,7 +289,7 @@ export function createInviteLink<C extends CoValue>(
|
|
289
289
|
const inviteSecret = group.createInvite(role);
|
290
290
|
|
291
291
|
return `${baseURL}#/invite/${valueHint ? valueHint + "/" : ""}${
|
292
|
-
value.id
|
292
|
+
value.$jazz.id
|
293
293
|
}/${inviteSecret}`;
|
294
294
|
}
|
295
295
|
|
@@ -198,7 +198,7 @@ describe("BrowserPasskeyAuth", () => {
|
|
198
198
|
|
199
199
|
await auth.signUp("");
|
200
200
|
|
201
|
-
const currentAccount = await Account.getMe().ensureLoaded({
|
201
|
+
const currentAccount = await Account.getMe().$jazz.ensureLoaded({
|
202
202
|
resolve: {
|
203
203
|
profile: true,
|
204
204
|
},
|
@@ -230,7 +230,7 @@ describe("BrowserPasskeyAuth", () => {
|
|
230
230
|
|
231
231
|
await auth.signUp("testuser");
|
232
232
|
|
233
|
-
const currentAccount = await Account.getMe().ensureLoaded({
|
233
|
+
const currentAccount = await Account.getMe().$jazz.ensureLoaded({
|
234
234
|
resolve: {
|
235
235
|
profile: true,
|
236
236
|
},
|
@@ -53,8 +53,8 @@ export class JazzInspectorElement extends HTMLElement {
|
|
53
53
|
|
54
54
|
this.root?.render(
|
55
55
|
<JazzInspectorInternal
|
56
|
-
localNode={this.account.
|
57
|
-
accountId={this.account.
|
56
|
+
localNode={this.account.$jazz.localNode}
|
57
|
+
accountId={this.account.$jazz.raw.id}
|
58
58
|
/>,
|
59
59
|
);
|
60
60
|
}
|
@@ -10,7 +10,7 @@ describe("createImage", async () => {
|
|
10
10
|
const getPlaceholderBase64 = vi.fn();
|
11
11
|
const createFileStreamFromSource = vi
|
12
12
|
.fn()
|
13
|
-
.mockResolvedValue(FileStream.create({ owner: account
|
13
|
+
.mockResolvedValue(FileStream.create({ owner: account }));
|
14
14
|
const resize = vi.fn();
|
15
15
|
|
16
16
|
const createImage = createImageFactory({
|
@@ -33,7 +33,7 @@ describe("createImage", async () => {
|
|
33
33
|
getImageSize.mockResolvedValue({ width: 1, height: 1 });
|
34
34
|
|
35
35
|
const image = await createImage(imageBlob, {
|
36
|
-
owner: account
|
36
|
+
owner: account,
|
37
37
|
placeholder: false,
|
38
38
|
progressive: false,
|
39
39
|
});
|
@@ -60,7 +60,7 @@ describe("createImage", async () => {
|
|
60
60
|
);
|
61
61
|
|
62
62
|
const image = await createImage(imageBlob, {
|
63
|
-
owner: account
|
63
|
+
owner: account,
|
64
64
|
placeholder: "blur",
|
65
65
|
progressive: false,
|
66
66
|
});
|
@@ -83,7 +83,7 @@ describe("createImage", async () => {
|
|
83
83
|
resize.mockResolvedValue(new Blob([White1920], { type: "image/png" }));
|
84
84
|
|
85
85
|
const image = await createImage(imageBlob, {
|
86
|
-
owner: account
|
86
|
+
owner: account,
|
87
87
|
placeholder: false,
|
88
88
|
progressive: false,
|
89
89
|
maxSize: 256,
|
@@ -109,7 +109,7 @@ describe("createImage", async () => {
|
|
109
109
|
getImageSize.mockResolvedValue({ width: 1, height: 1 });
|
110
110
|
|
111
111
|
const image = await createImage(imageBlob, {
|
112
|
-
owner: account
|
112
|
+
owner: account,
|
113
113
|
placeholder: false,
|
114
114
|
progressive: false,
|
115
115
|
maxSize: 256,
|
@@ -136,7 +136,7 @@ describe("createImage", async () => {
|
|
136
136
|
resize.mockResolvedValue(new Blob([White1920], { type: "image/png" }));
|
137
137
|
|
138
138
|
const image = await createImage(imageBlob, {
|
139
|
-
owner: account
|
139
|
+
owner: account,
|
140
140
|
progressive: true,
|
141
141
|
placeholder: false,
|
142
142
|
});
|
@@ -164,7 +164,7 @@ describe("createImage", async () => {
|
|
164
164
|
resize.mockResolvedValue(new Blob([White1920], { type: "image/png" }));
|
165
165
|
|
166
166
|
const image = await createImage(imageBlob, {
|
167
|
-
owner: account
|
167
|
+
owner: account,
|
168
168
|
maxSize: 256,
|
169
169
|
placeholder: false,
|
170
170
|
progressive: true,
|
@@ -137,7 +137,7 @@ async function createImage(
|
|
137
137
|
* On the client side, the image will be loaded progressively, starting from the smallest size and increasing the size until the original size is reached.
|
138
138
|
*/
|
139
139
|
if (options?.progressive) {
|
140
|
-
imageCoValue.progressive
|
140
|
+
imageCoValue.$jazz.set("progressive", true);
|
141
141
|
|
142
142
|
const resizes = ([256, 1024, 2048] as const).filter(
|
143
143
|
(s) =>
|
@@ -153,8 +153,10 @@ async function createImage(
|
|
153
153
|
);
|
154
154
|
|
155
155
|
const blob = await impl.resize(imageBlobOrFile, width, height);
|
156
|
-
imageCoValue
|
157
|
-
|
156
|
+
imageCoValue.$jazz.set(
|
157
|
+
`${width}x${height}`,
|
158
|
+
await impl.createFileStreamFromSource(blob, options?.owner),
|
159
|
+
);
|
158
160
|
}
|
159
161
|
}
|
160
162
|
|
package/src/media/index.ts
CHANGED
@@ -27,7 +27,7 @@ export { createImageFactory };
|
|
27
27
|
* // Creates ImageDefinition with a blurry placeholder, limited to 1024px
|
28
28
|
* // on the longest side, and multiple resolutions automatically
|
29
29
|
* const image = await createImage(file, {
|
30
|
-
* owner: me.
|
30
|
+
* owner: me.$jazz.owner,
|
31
31
|
* maxSize: 1024,
|
32
32
|
* placeholder: "blur",
|
33
33
|
* progressive: true,
|