jazz-tools 0.18.0 → 0.18.2
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 +44 -30
- package/CHANGELOG.md +20 -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/{chunk-HJ3GTGY7.js → chunk-IERUTUXB.js} +18 -1
- package/dist/chunk-IERUTUXB.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/react-core/index.js +17 -0
- package/dist/react-core/index.js.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/tools/coValues/account.d.ts +1 -0
- package/dist/tools/coValues/account.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +10 -0
- package/dist/tools/coValues/coMap.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodCo.d.ts +1 -1
- package/dist/tools/testing.d.ts.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/tools/coValues/account.ts +5 -0
- package/src/tools/coValues/coMap.ts +14 -0
- package/src/tools/implementation/zodSchema/zodCo.ts +1 -1
- package/src/tools/tests/ContextManager.test.ts +2 -2
- package/src/tools/tests/account.test.ts +51 -0
- package/src/tools/tests/coMap.test.ts +99 -0
- package/src/tools/tests/patterns/notifications.test.ts +1 -1
- package/src/tools/tests/testing.test.ts +2 -2
- package/tsup.config.ts +9 -0
- package/dist/chunk-HJ3GTGY7.js.map +0 -1
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../../src/better-auth/auth/react.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,iBAAiB,EAIvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,iBAAiB,EAAiB,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,KAAK,UAAU,GAAG,UAAU,CAC1B,OAAO,gBAAgB,CAAC;IACtB,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;CAChD,CAAC,CACH,CAAC;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;6BA+E8jc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAk7yW,CAAC;+BAAyD,CAAC;gCAA0D,CAAC;6BAAuD,CAAC;;;;;;;;;;;;;;;;;;;;;;;qBAA9K,CAAC;2BAAyD,CAAC;4BAA0D,CAAC;yBAAuD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAjmzW,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;qBAAs6qe,CAAC;2BAAyD,CAAC;4BAA0D,CAAC;sBAAoD,CAAC;;;;;;;;;;;;;;;;;;;;iBAA3K,CAAC;uBAAyD,CAAC;wBAA0D,CAAC;kBAAoD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAllre,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAAsp+f,CAAC;iBAAmC,CAAC;iBAA0C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAAvu+f,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAAD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAAx9a,CAAC;mBAA+C,CAAC;eAAqC,CAAC;;;;;iBAAyW,CAAC;iBAAuC,CAAC;;YAA2D,CAAC;gBAA2C,CAAC;gBAA+C,CAAC;gBAA+C,CAAC;sBAA4C,CAAC;cAA4C,CAAC;cAAkD,CAAC;eAAmC,CAAC;mBAA4G,CAAC;yBAA6B,CAAC;;eAAiD,CAAC;;;aAAqH,CAAC;YAAmC,CAAC;;;;;;;;;;;;YAA+iB,CAAC;aAAoB,CAAC;cAAqB,CAAC;cAAqB,CAAC;;aAAsG,CAAC;oBAAoE,CAAC;cAAoC,CAAC;mBAAqG,CAAC;yBAA6E,CAAC;;;uBAA0F,CAAC;+GAA6K,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;UA/Et/F,CAAC;AAElE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,gBAAgB,GACjB,EAAE,iBAAiB,CAAC;IACnB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC,6BAmBD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,+BAA+B,GAC1C,CAAC,SACG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GACjD,gBAAgB,SAEb;IAAE,gBAAgB,EAAE,UAAU,CAAA;CAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,4CAS/D,CAAC"}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
// src/better-auth/auth/react.tsx
|
4
|
+
import {
|
5
|
+
JazzReactProvider,
|
6
|
+
useAuthSecretStorage,
|
7
|
+
useJazzContext
|
8
|
+
} from "jazz-tools/react";
|
9
|
+
import { useEffect } from "react";
|
10
|
+
import { createContext } from "react";
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
12
|
+
var AuthContext = createContext(null);
|
13
|
+
function AuthProvider({
|
14
|
+
children,
|
15
|
+
betterAuthClient
|
16
|
+
}) {
|
17
|
+
const context = useJazzContext();
|
18
|
+
const authSecretStorage = useAuthSecretStorage();
|
19
|
+
if (betterAuthClient.jazz === void 0) {
|
20
|
+
throw new Error(
|
21
|
+
"Better Auth client has been initialized without the jazzPluginClient"
|
22
|
+
);
|
23
|
+
}
|
24
|
+
useEffect(() => {
|
25
|
+
betterAuthClient.jazz.setJazzContext(context);
|
26
|
+
betterAuthClient.jazz.setAuthSecretStorage(authSecretStorage);
|
27
|
+
return betterAuthClient.useSession.subscribe(() => {
|
28
|
+
});
|
29
|
+
}, [betterAuthClient, context, authSecretStorage]);
|
30
|
+
return children;
|
31
|
+
}
|
32
|
+
var JazzReactProviderWithBetterAuth = (props) => {
|
33
|
+
return /* @__PURE__ */ jsx(JazzReactProvider, { ...props, children: /* @__PURE__ */ jsx(AuthProvider, { betterAuthClient: props.betterAuthClient, children: props.children }) });
|
34
|
+
};
|
35
|
+
export {
|
36
|
+
AuthContext,
|
37
|
+
AuthProvider,
|
38
|
+
JazzReactProviderWithBetterAuth
|
39
|
+
};
|
40
|
+
//# sourceMappingURL=react.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../../src/better-auth/auth/react.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ClientOptions } from \"better-auth\";\nimport { createAuthClient } from \"better-auth/client\";\nimport type {\n Account,\n AccountClass,\n AnyAccountSchema,\n CoValueFromRaw,\n} from \"jazz-tools\";\nimport {\n type JazzProviderProps,\n JazzReactProvider,\n useAuthSecretStorage,\n useJazzContext,\n} from \"jazz-tools/react\";\nimport { useEffect } from \"react\";\nimport { type PropsWithChildren, createContext } from \"react\";\nimport { jazzPluginClient } from \"./client.js\";\n\ntype AuthClient = ReturnType<\n typeof createAuthClient<{\n plugins: [ReturnType<typeof jazzPluginClient>];\n }>\n>;\n\nexport const AuthContext = createContext<AuthClient | null>(null);\n\n/**\n * @param props.children - The children to render.\n * @param props.betterAuthClient - The BetterAuth client with the Jazz plugin.\n *\n * @example\n * ```ts\n * const betterAuthClient = createAuthClient({\n * plugins: [\n * jazzPluginClient(),\n * ],\n * });\n *\n * <AuthProvider betterAuthClient={betterAuthClient}>\n * <App />\n * </AuthProvider>\n * ```\n */\nexport function AuthProvider({\n children,\n betterAuthClient,\n}: PropsWithChildren<{\n betterAuthClient: AuthClient;\n}>) {\n const context = useJazzContext();\n const authSecretStorage = useAuthSecretStorage();\n\n if (betterAuthClient.jazz === undefined) {\n throw new Error(\n \"Better Auth client has been initialized without the jazzPluginClient\",\n );\n }\n\n useEffect(() => {\n betterAuthClient.jazz.setJazzContext(context);\n betterAuthClient.jazz.setAuthSecretStorage(authSecretStorage);\n\n // We need to subscribe to the session to let the plugin keep sync Jazz's and BetterAuth's session\n return betterAuthClient.useSession.subscribe(() => {});\n }, [betterAuthClient, context, authSecretStorage]);\n\n return children;\n}\n\n/**\n * @param props - The props for the JazzReactProvider.\n * @param props.betterAuth - The options for the BetterAuth client.\n * @returns The JazzReactProvider with the BetterAuth plugin.\n *\n * @example\n * ```ts\n * <JazzReactProviderWithBetterAuth\n * betterAuth={{\n * baseURL: \"http://localhost:3000\",\n * }}\n * sync={{\n * peer: \"ws://localhost:4200\",\n * }}\n * >\n * <App />\n * </JazzReactProviderWithBetterAuth>\n * ```\n */\nexport const JazzReactProviderWithBetterAuth = <\n S extends\n | (AccountClass<Account> & CoValueFromRaw<Account>)\n | AnyAccountSchema,\n>(\n props: { betterAuthClient: AuthClient } & JazzProviderProps<S>,\n) => {\n return (\n <JazzReactProvider {...props}>\n <AuthProvider betterAuthClient={props.betterAuthClient}>\n {props.children}\n </AuthProvider>\n </JazzReactProvider>\n );\n};\n"],"mappings":";;;AAUA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAiC,qBAAqB;AAkFhD;AAzEC,IAAM,cAAc,cAAiC,IAAI;AAmBzD,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AACF,GAEI;AACF,QAAM,UAAU,eAAe;AAC/B,QAAM,oBAAoB,qBAAqB;AAE/C,MAAI,iBAAiB,SAAS,QAAW;AACvC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,YAAU,MAAM;AACd,qBAAiB,KAAK,eAAe,OAAO;AAC5C,qBAAiB,KAAK,qBAAqB,iBAAiB;AAG5D,WAAO,iBAAiB,WAAW,UAAU,MAAM;AAAA,IAAC,CAAC;AAAA,EACvD,GAAG,CAAC,kBAAkB,SAAS,iBAAiB,CAAC;AAEjD,SAAO;AACT;AAqBO,IAAM,kCAAkC,CAK7C,UACG;AACH,SACE,oBAAC,qBAAmB,GAAG,OACrB,8BAAC,gBAAa,kBAAkB,MAAM,kBACnC,gBAAM,UACT,GACF;AAEJ;","names":[]}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { BetterAuthPlugin } from "better-auth/plugins";
|
2
|
+
/**
|
3
|
+
* @returns The BetterAuth server plugin.
|
4
|
+
*
|
5
|
+
* @example
|
6
|
+
* ```ts
|
7
|
+
* const auth = betterAuth({
|
8
|
+
* plugins: [jazzPlugin()],
|
9
|
+
* // ... other BetterAuth options
|
10
|
+
* });
|
11
|
+
* ```
|
12
|
+
*/
|
13
|
+
export declare const jazzPlugin: () => BetterAuthPlugin;
|
14
|
+
//# sourceMappingURL=server.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/better-auth/auth/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAwB,MAAM,qBAAqB,CAAC;AAG7E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,QAAO,gBAwL7B,CAAC"}
|
@@ -0,0 +1,198 @@
|
|
1
|
+
// src/better-auth/auth/server.ts
|
2
|
+
import { APIError } from "better-auth/api";
|
3
|
+
import { symmetricDecrypt, symmetricEncrypt } from "better-auth/crypto";
|
4
|
+
import { createAuthMiddleware } from "better-auth/plugins";
|
5
|
+
var jazzPlugin = () => {
|
6
|
+
return {
|
7
|
+
id: "jazz-plugin",
|
8
|
+
schema: {
|
9
|
+
user: {
|
10
|
+
fields: {
|
11
|
+
accountID: {
|
12
|
+
type: "string",
|
13
|
+
required: false,
|
14
|
+
input: false
|
15
|
+
},
|
16
|
+
encryptedCredentials: {
|
17
|
+
type: "string",
|
18
|
+
required: false,
|
19
|
+
input: false,
|
20
|
+
returned: false
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
},
|
25
|
+
init() {
|
26
|
+
return {
|
27
|
+
options: {
|
28
|
+
databaseHooks: {
|
29
|
+
user: {
|
30
|
+
create: {
|
31
|
+
before: async (user, context) => {
|
32
|
+
if (!contextContainsJazzAuth(context)) {
|
33
|
+
throw new APIError(422, {
|
34
|
+
message: "JazzAuth is required"
|
35
|
+
});
|
36
|
+
}
|
37
|
+
return {
|
38
|
+
data: {
|
39
|
+
accountID: context?.jazzAuth?.accountID,
|
40
|
+
encryptedCredentials: context?.jazzAuth?.encryptedCredentials
|
41
|
+
}
|
42
|
+
};
|
43
|
+
}
|
44
|
+
}
|
45
|
+
},
|
46
|
+
verification: {
|
47
|
+
create: {
|
48
|
+
before: async (verification, context) => {
|
49
|
+
if (contextContainsJazzAuth(context)) {
|
50
|
+
const parsed = JSON.parse(verification.value);
|
51
|
+
const newValue = JSON.stringify({
|
52
|
+
...parsed,
|
53
|
+
jazzAuth: context.jazzAuth
|
54
|
+
});
|
55
|
+
return {
|
56
|
+
data: {
|
57
|
+
value: newValue
|
58
|
+
}
|
59
|
+
};
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
};
|
67
|
+
},
|
68
|
+
hooks: {
|
69
|
+
before: [
|
70
|
+
/**
|
71
|
+
* If the client sends a x-jazz-auth header,
|
72
|
+
* we encrypt the credentials and inject them into the context.
|
73
|
+
*/
|
74
|
+
{
|
75
|
+
matcher: (context) => {
|
76
|
+
return !!context.headers?.get("x-jazz-auth");
|
77
|
+
},
|
78
|
+
handler: createAuthMiddleware(async (ctx) => {
|
79
|
+
const jazzAuth = JSON.parse(ctx.headers?.get("x-jazz-auth"));
|
80
|
+
const credentials = {
|
81
|
+
accountID: jazzAuth.accountID,
|
82
|
+
secretSeed: jazzAuth.secretSeed,
|
83
|
+
accountSecret: jazzAuth.accountSecret,
|
84
|
+
// If the provider remains 'anonymous', Jazz will not consider us authenticated later.
|
85
|
+
provider: "better-auth"
|
86
|
+
};
|
87
|
+
const encryptedCredentials = await symmetricEncrypt({
|
88
|
+
key: ctx.context.secret,
|
89
|
+
data: JSON.stringify(credentials)
|
90
|
+
});
|
91
|
+
return {
|
92
|
+
context: {
|
93
|
+
...ctx,
|
94
|
+
jazzAuth: {
|
95
|
+
accountID: jazzAuth.accountID,
|
96
|
+
encryptedCredentials
|
97
|
+
}
|
98
|
+
}
|
99
|
+
};
|
100
|
+
})
|
101
|
+
},
|
102
|
+
/**
|
103
|
+
* /callback is the endpoint that BetterAuth uses to authenticate the user coming from a social provider.
|
104
|
+
* 1. Catch the state
|
105
|
+
* 2. Find the verification value
|
106
|
+
* 3. If the verification value contains a jazzAuth, inject into the context to have it in case of registration.
|
107
|
+
*/
|
108
|
+
{
|
109
|
+
matcher: (context) => {
|
110
|
+
return context.path.startsWith("/callback");
|
111
|
+
},
|
112
|
+
handler: createAuthMiddleware(async (ctx) => {
|
113
|
+
const state = ctx.query?.state || ctx.body?.state;
|
114
|
+
const data = await ctx.context.adapter.findOne({
|
115
|
+
model: ctx.context.tables.verification.modelName,
|
116
|
+
where: [
|
117
|
+
{
|
118
|
+
field: "identifier",
|
119
|
+
operator: "eq",
|
120
|
+
value: state
|
121
|
+
}
|
122
|
+
],
|
123
|
+
select: ["value"]
|
124
|
+
});
|
125
|
+
if (!data) {
|
126
|
+
throw new APIError(404, {
|
127
|
+
message: "Verification not found"
|
128
|
+
});
|
129
|
+
}
|
130
|
+
const parsed = JSON.parse(data.value);
|
131
|
+
if (parsed && "jazzAuth" in parsed) {
|
132
|
+
ctx.context.jazzAuth = parsed.jazzAuth;
|
133
|
+
} else {
|
134
|
+
throw new APIError(404, {
|
135
|
+
message: "JazzAuth not found in verification value"
|
136
|
+
});
|
137
|
+
}
|
138
|
+
})
|
139
|
+
}
|
140
|
+
],
|
141
|
+
after: [
|
142
|
+
/**
|
143
|
+
* This middleware is used to extract the jazzAuth from the user and return it in the response.
|
144
|
+
* It is used in the following endpoints that return the user:
|
145
|
+
* - /sign-up/email
|
146
|
+
* - /sign-in/email
|
147
|
+
* - /get-session
|
148
|
+
*/
|
149
|
+
{
|
150
|
+
matcher: (context) => {
|
151
|
+
return context.path.startsWith("/sign-up") || context.path.startsWith("/sign-in") || context.path.startsWith("/get-session");
|
152
|
+
},
|
153
|
+
handler: createAuthMiddleware({}, async (ctx) => {
|
154
|
+
const returned = ctx.context.returned;
|
155
|
+
if (!returned?.user?.id) {
|
156
|
+
return;
|
157
|
+
}
|
158
|
+
const jazzAuth = await extractJazzAuth(returned.user.id, ctx);
|
159
|
+
return ctx.json({
|
160
|
+
...returned,
|
161
|
+
jazzAuth
|
162
|
+
});
|
163
|
+
})
|
164
|
+
}
|
165
|
+
]
|
166
|
+
}
|
167
|
+
};
|
168
|
+
};
|
169
|
+
function contextContainsJazzAuth(ctx) {
|
170
|
+
return !!ctx && typeof ctx === "object" && "jazzAuth" in ctx;
|
171
|
+
}
|
172
|
+
async function extractJazzAuth(userId, ctx) {
|
173
|
+
const user = await ctx.context.adapter.findOne({
|
174
|
+
model: ctx.context.tables.user.modelName,
|
175
|
+
where: [
|
176
|
+
{
|
177
|
+
field: "id",
|
178
|
+
operator: "eq",
|
179
|
+
value: userId
|
180
|
+
}
|
181
|
+
],
|
182
|
+
select: ["accountID", "encryptedCredentials"]
|
183
|
+
});
|
184
|
+
if (!user) {
|
185
|
+
return;
|
186
|
+
}
|
187
|
+
const jazzAuth = JSON.parse(
|
188
|
+
await symmetricDecrypt({
|
189
|
+
key: ctx.context.secret,
|
190
|
+
data: user.encryptedCredentials
|
191
|
+
})
|
192
|
+
);
|
193
|
+
return jazzAuth;
|
194
|
+
}
|
195
|
+
export {
|
196
|
+
jazzPlugin
|
197
|
+
};
|
198
|
+
//# sourceMappingURL=server.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../../src/better-auth/auth/server.ts"],"sourcesContent":["import { AuthContext, MiddlewareContext, MiddlewareOptions } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport { symmetricDecrypt, symmetricEncrypt } from \"better-auth/crypto\";\nimport { BetterAuthPlugin, createAuthMiddleware } from \"better-auth/plugins\";\nimport type { Account, AuthCredentials, ID } from \"jazz-tools\";\n\n/**\n * @returns The BetterAuth server plugin.\n *\n * @example\n * ```ts\n * const auth = betterAuth({\n * plugins: [jazzPlugin()],\n * // ... other BetterAuth options\n * });\n * ```\n */\nexport const jazzPlugin = (): BetterAuthPlugin => {\n return {\n id: \"jazz-plugin\",\n schema: {\n user: {\n fields: {\n accountID: {\n type: \"string\",\n required: false,\n input: false,\n },\n encryptedCredentials: {\n type: \"string\",\n required: false,\n input: false,\n returned: false,\n },\n },\n },\n },\n\n init() {\n return {\n options: {\n databaseHooks: {\n user: {\n create: {\n before: async (user, context) => {\n // If the user is created without a jazzAuth, it will throw an error.\n if (!contextContainsJazzAuth(context)) {\n throw new APIError(422, {\n message: \"JazzAuth is required\",\n });\n }\n // Decorate the user with the jazz's credentials.\n return {\n data: {\n accountID: context?.jazzAuth?.accountID,\n encryptedCredentials:\n context?.jazzAuth?.encryptedCredentials,\n },\n };\n },\n },\n },\n verification: {\n create: {\n before: async (verification, context) => {\n // If a jazzAuth is provided, save it for later usage.\n if (contextContainsJazzAuth(context)) {\n const parsed = JSON.parse(verification.value);\n const newValue = JSON.stringify({\n ...parsed,\n jazzAuth: context.jazzAuth,\n });\n\n return {\n data: {\n value: newValue,\n },\n };\n }\n },\n },\n },\n },\n },\n };\n },\n\n hooks: {\n before: [\n /**\n * If the client sends a x-jazz-auth header,\n * we encrypt the credentials and inject them into the context.\n */\n {\n matcher: (context) => {\n return !!context.headers?.get(\"x-jazz-auth\");\n },\n handler: createAuthMiddleware(async (ctx) => {\n const jazzAuth = JSON.parse(ctx.headers?.get(\"x-jazz-auth\")!);\n\n const credentials: AuthCredentials = {\n accountID: jazzAuth.accountID as ID<Account>,\n secretSeed: jazzAuth.secretSeed,\n accountSecret: jazzAuth.accountSecret as any,\n // If the provider remains 'anonymous', Jazz will not consider us authenticated later.\n provider: \"better-auth\",\n };\n\n const encryptedCredentials = await symmetricEncrypt({\n key: ctx.context.secret,\n data: JSON.stringify(credentials),\n });\n\n return {\n context: {\n ...ctx,\n jazzAuth: {\n accountID: jazzAuth.accountID,\n encryptedCredentials: encryptedCredentials,\n },\n },\n };\n }),\n },\n\n /**\n * /callback is the endpoint that BetterAuth uses to authenticate the user coming from a social provider.\n * 1. Catch the state\n * 2. Find the verification value\n * 3. If the verification value contains a jazzAuth, inject into the context to have it in case of registration.\n */\n {\n matcher: (context) => {\n return context.path.startsWith(\"/callback\");\n },\n handler: createAuthMiddleware(async (ctx) => {\n const state = ctx.query?.state || ctx.body?.state;\n\n const data = await ctx.context.adapter.findOne<{ value: string }>({\n model: ctx.context.tables.verification!.modelName,\n where: [\n {\n field: \"identifier\",\n operator: \"eq\",\n value: state,\n },\n ],\n select: [\"value\"],\n });\n\n // if not found, the social plugin will throw later anyway\n if (!data) {\n throw new APIError(404, {\n message: \"Verification not found\",\n });\n }\n\n const parsed = JSON.parse(data.value);\n\n if (parsed && \"jazzAuth\" in parsed) {\n ctx.context.jazzAuth = parsed.jazzAuth;\n } else {\n throw new APIError(404, {\n message: \"JazzAuth not found in verification value\",\n });\n }\n }),\n },\n ],\n after: [\n /**\n * This middleware is used to extract the jazzAuth from the user and return it in the response.\n * It is used in the following endpoints that return the user:\n * - /sign-up/email\n * - /sign-in/email\n * - /get-session\n */\n {\n matcher: (context) => {\n return (\n context.path.startsWith(\"/sign-up\") ||\n context.path.startsWith(\"/sign-in\") ||\n context.path.startsWith(\"/get-session\")\n );\n },\n handler: createAuthMiddleware({}, async (ctx) => {\n const returned = ctx.context.returned as any;\n if (!returned?.user?.id) {\n return;\n }\n const jazzAuth = await extractJazzAuth(returned.user.id, ctx);\n\n return ctx.json({\n ...returned,\n jazzAuth: jazzAuth,\n });\n }),\n },\n ],\n },\n };\n};\n\nfunction contextContainsJazzAuth(ctx: unknown): ctx is {\n jazzAuth: {\n accountID: string;\n encryptedCredentials: string;\n };\n} {\n return !!ctx && typeof ctx === \"object\" && \"jazzAuth\" in ctx;\n}\n\nasync function extractJazzAuth(\n userId: string,\n ctx: MiddlewareContext<\n MiddlewareOptions,\n AuthContext & {\n returned?: unknown;\n responseHeaders?: Headers;\n }\n >,\n) {\n const user = await ctx.context.adapter.findOne<{\n accountID: string;\n encryptedCredentials: string;\n }>({\n model: ctx.context.tables.user!.modelName,\n where: [\n {\n field: \"id\",\n operator: \"eq\",\n value: userId,\n },\n ],\n select: [\"accountID\", \"encryptedCredentials\"],\n });\n\n if (!user) {\n return;\n }\n\n const jazzAuth = JSON.parse(\n await symmetricDecrypt({\n key: ctx.context.secret,\n data: user.encryptedCredentials,\n }),\n );\n\n return jazzAuth;\n}\n"],"mappings":"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","names":[]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../../../src/better-auth/auth/tests/client.test.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../../../src/better-auth/auth/tests/server.test.ts"],"names":[],"mappings":""}
|
@@ -476,6 +476,19 @@ var CoMapJazzApi = class extends CoValueJazzApi {
|
|
476
476
|
get owner() {
|
477
477
|
return getCoValueOwner(this.coMap);
|
478
478
|
}
|
479
|
+
/**
|
480
|
+
* Check if a key is defined in the CoMap.
|
481
|
+
*
|
482
|
+
* This check does not load the referenced value or validate permissions.
|
483
|
+
*
|
484
|
+
* @param key The key to check
|
485
|
+
* @returns True if the key is defined, false otherwise
|
486
|
+
* @category Content
|
487
|
+
*/
|
488
|
+
has(key) {
|
489
|
+
const entry = this.raw.getRaw(key);
|
490
|
+
return entry?.change !== void 0 && entry.change.op !== "del";
|
491
|
+
}
|
479
492
|
/**
|
480
493
|
* Set a value on the CoMap
|
481
494
|
*
|
@@ -2299,6 +2312,10 @@ var AccountJazzApi = class extends CoValueJazzApi {
|
|
2299
2312
|
this.raw.set(key, refId, "trusting");
|
2300
2313
|
}
|
2301
2314
|
}
|
2315
|
+
has(key) {
|
2316
|
+
const entry = this.raw.getRaw(key);
|
2317
|
+
return entry?.change !== void 0 && entry.change.op !== "del";
|
2318
|
+
}
|
2302
2319
|
/**
|
2303
2320
|
* Get the descriptor for a given key
|
2304
2321
|
* @internal
|
@@ -5714,4 +5731,4 @@ export {
|
|
5714
5731
|
JazzContextManager
|
5715
5732
|
};
|
5716
5733
|
/* istanbul ignore file -- @preserve */
|
5717
|
-
//# sourceMappingURL=chunk-
|
5734
|
+
//# sourceMappingURL=chunk-IERUTUXB.js.map
|