payload-auth 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +17 -0
- package/dist/authjs/index.d.ts +1 -0
- package/dist/authjs/index.js +3 -0
- package/dist/authjs/index.js.map +1 -0
- package/dist/better-auth/adapter/dev/bin/run.d.ts +1 -0
- package/dist/better-auth/adapter/dev/bin/run.js +64 -0
- package/dist/better-auth/adapter/dev/bin/run.js.map +1 -0
- package/dist/better-auth/adapter/dev/bin/schema.d.ts +22 -0
- package/dist/better-auth/adapter/dev/bin/schema.js +160 -0
- package/dist/better-auth/adapter/dev/bin/schema.js.map +1 -0
- package/dist/better-auth/adapter/dev/collections.d.ts +3 -0
- package/dist/better-auth/adapter/dev/collections.js +212 -0
- package/dist/better-auth/adapter/dev/collections.js.map +1 -0
- package/dist/better-auth/adapter/dev/index.d.ts +3 -0
- package/dist/better-auth/adapter/dev/index.js +168 -0
- package/dist/better-auth/adapter/dev/index.js.map +1 -0
- package/dist/better-auth/adapter/generate-schema/generate-schema-builder.d.ts +23 -0
- package/dist/better-auth/adapter/generate-schema/generate-schema-builder.js +326 -0
- package/dist/better-auth/adapter/generate-schema/generate-schema-builder.js.map +1 -0
- package/dist/better-auth/adapter/generate-schema/get-payload-schema.d.ts +1 -0
- package/dist/better-auth/adapter/generate-schema/get-payload-schema.js +23 -0
- package/dist/better-auth/adapter/generate-schema/get-payload-schema.js.map +1 -0
- package/dist/better-auth/adapter/generate-schema/index.d.ts +4 -0
- package/dist/better-auth/adapter/generate-schema/index.js +19 -0
- package/dist/better-auth/adapter/generate-schema/index.js.map +1 -0
- package/dist/better-auth/adapter/generate-schema/utils.d.ts +2 -0
- package/dist/better-auth/adapter/generate-schema/utils.js +20 -0
- package/dist/better-auth/adapter/generate-schema/utils.js.map +1 -0
- package/dist/better-auth/adapter/index.d.ts +5 -0
- package/dist/better-auth/adapter/index.js +578 -0
- package/dist/better-auth/adapter/index.js.map +1 -0
- package/dist/better-auth/adapter/test/adapter.test.d.ts +1 -0
- package/dist/better-auth/adapter/test/adapter.test.js +181 -0
- package/dist/better-auth/adapter/test/adapter.test.js.map +1 -0
- package/dist/better-auth/adapter/test/better-auth-adapter-test.d.ts +7 -0
- package/dist/better-auth/adapter/test/better-auth-adapter-test.js +425 -0
- package/dist/better-auth/adapter/test/better-auth-adapter-test.js.map +1 -0
- package/dist/better-auth/adapter/test/schema.test.d.ts +1 -0
- package/dist/better-auth/adapter/test/schema.test.js +796 -0
- package/dist/better-auth/adapter/test/schema.test.js.map +1 -0
- package/dist/better-auth/adapter/test/test_payload1/schema.d.ts +23 -0
- package/dist/better-auth/adapter/test/test_payload1/schema.js +177 -0
- package/dist/better-auth/adapter/test/test_payload1/schema.js.map +1 -0
- package/dist/better-auth/adapter/test/test_payload2/schema.d.ts +23 -0
- package/dist/better-auth/adapter/test/test_payload2/schema.js +167 -0
- package/dist/better-auth/adapter/test/test_payload2/schema.js.map +1 -0
- package/dist/better-auth/adapter/test/test_payload3/schema.d.ts +23 -0
- package/dist/better-auth/adapter/test/test_payload3/schema.js +198 -0
- package/dist/better-auth/adapter/test/test_payload3/schema.js.map +1 -0
- package/dist/better-auth/adapter/transform/index.d.ts +16 -0
- package/dist/better-auth/adapter/transform/index.js +252 -0
- package/dist/better-auth/adapter/transform/index.js.map +1 -0
- package/dist/better-auth/adapter/types.d.ts +6 -0
- package/dist/better-auth/adapter/types.js +3 -0
- package/dist/better-auth/adapter/types.js.map +1 -0
- package/dist/better-auth/index.d.ts +6 -0
- package/dist/better-auth/index.js +8 -0
- package/dist/better-auth/index.js.map +1 -0
- package/dist/better-auth/plugin/collections/accounts/hooks/sync-password-to-user.d.ts +7 -0
- package/dist/better-auth/plugin/collections/accounts/hooks/sync-password-to-user.js +47 -0
- package/dist/better-auth/plugin/collections/accounts/hooks/sync-password-to-user.js.map +1 -0
- package/dist/better-auth/plugin/collections/users/endpoints/refresh-token.d.ts +6 -0
- package/dist/better-auth/plugin/collections/users/endpoints/refresh-token.js +106 -0
- package/dist/better-auth/plugin/collections/users/endpoints/refresh-token.js.map +1 -0
- package/dist/better-auth/plugin/collections/users/hooks/after-login.d.ts +11 -0
- package/dist/better-auth/plugin/collections/users/hooks/after-login.js +71 -0
- package/dist/better-auth/plugin/collections/users/hooks/after-login.js.map +1 -0
- package/dist/better-auth/plugin/collections/users/hooks/after-logout.d.ts +6 -0
- package/dist/better-auth/plugin/collections/users/hooks/after-logout.js +49 -0
- package/dist/better-auth/plugin/collections/users/hooks/after-logout.js.map +1 -0
- package/dist/better-auth/plugin/collections/users/hooks/before-login.d.ts +5 -0
- package/dist/better-auth/plugin/collections/users/hooks/before-login.js +18 -0
- package/dist/better-auth/plugin/collections/users/hooks/before-login.js.map +1 -0
- package/dist/better-auth/plugin/collections/users/hooks/clean-up-user-after-delete.d.ts +5 -0
- package/dist/better-auth/plugin/collections/users/hooks/clean-up-user-after-delete.js +33 -0
- package/dist/better-auth/plugin/collections/users/hooks/clean-up-user-after-delete.js.map +1 -0
- package/dist/better-auth/plugin/collections/users/hooks/on-verified-change.d.ts +2 -0
- package/dist/better-auth/plugin/collections/users/hooks/on-verified-change.js +14 -0
- package/dist/better-auth/plugin/collections/users/hooks/on-verified-change.js.map +1 -0
- package/dist/better-auth/plugin/collections/users/hooks/sync-account.d.ts +7 -0
- package/dist/better-auth/plugin/collections/users/hooks/sync-account.js +82 -0
- package/dist/better-auth/plugin/collections/users/hooks/sync-account.js.map +1 -0
- package/dist/better-auth/plugin/helpers/generate-verify-email-url.d.ts +29 -0
- package/dist/better-auth/plugin/helpers/generate-verify-email-url.js +46 -0
- package/dist/better-auth/plugin/helpers/generate-verify-email-url.js.map +1 -0
- package/dist/better-auth/plugin/helpers/get-ip.d.ts +2 -0
- package/dist/better-auth/plugin/helpers/get-ip.js +31 -0
- package/dist/better-auth/plugin/helpers/get-ip.js.map +1 -0
- package/dist/better-auth/plugin/helpers/index.d.ts +1 -0
- package/dist/better-auth/plugin/helpers/index.js +3 -0
- package/dist/better-auth/plugin/helpers/index.js.map +1 -0
- package/dist/better-auth/plugin/helpers/serialize-cookie.d.ts +104 -0
- package/dist/better-auth/plugin/helpers/serialize-cookie.js +186 -0
- package/dist/better-auth/plugin/helpers/serialize-cookie.js.map +1 -0
- package/dist/better-auth/plugin/index.d.ts +7 -0
- package/dist/better-auth/plugin/index.js +64 -0
- package/dist/better-auth/plugin/index.js.map +1 -0
- package/dist/better-auth/plugin/lib/auth-strategy.d.ts +8 -0
- package/dist/better-auth/plugin/lib/auth-strategy.js +48 -0
- package/dist/better-auth/plugin/lib/auth-strategy.js.map +1 -0
- package/dist/better-auth/plugin/lib/build-collection-configs.d.ts +11 -0
- package/dist/better-auth/plugin/lib/build-collection-configs.js +1558 -0
- package/dist/better-auth/plugin/lib/build-collection-configs.js.map +1 -0
- package/dist/better-auth/plugin/lib/config.d.ts +41 -0
- package/dist/better-auth/plugin/lib/config.js +43 -0
- package/dist/better-auth/plugin/lib/config.js.map +1 -0
- package/dist/better-auth/plugin/lib/ensure-password-set-before-create.d.ts +7 -0
- package/dist/better-auth/plugin/lib/ensure-password-set-before-create.js +24 -0
- package/dist/better-auth/plugin/lib/ensure-password-set-before-create.js.map +1 -0
- package/dist/better-auth/plugin/lib/get-payload-auth.d.ts +5 -0
- package/dist/better-auth/plugin/lib/get-payload-auth.js +9 -0
- package/dist/better-auth/plugin/lib/get-payload-auth.js.map +1 -0
- package/dist/better-auth/plugin/lib/get-required-collection-slugs.d.ts +9 -0
- package/dist/better-auth/plugin/lib/get-required-collection-slugs.js +52 -0
- package/dist/better-auth/plugin/lib/get-required-collection-slugs.js.map +1 -0
- package/dist/better-auth/plugin/lib/init-better-auth.d.ts +6 -0
- package/dist/better-auth/plugin/lib/init-better-auth.js +13 -0
- package/dist/better-auth/plugin/lib/init-better-auth.js.map +1 -0
- package/dist/better-auth/plugin/lib/password.d.ts +25 -0
- package/dist/better-auth/plugin/lib/password.js +63 -0
- package/dist/better-auth/plugin/lib/password.js.map +1 -0
- package/dist/better-auth/plugin/lib/payload-access.d.ts +14 -0
- package/dist/better-auth/plugin/lib/payload-access.js +64 -0
- package/dist/better-auth/plugin/lib/payload-access.js.map +1 -0
- package/dist/better-auth/plugin/lib/prepare-session-data.d.ts +21 -0
- package/dist/better-auth/plugin/lib/prepare-session-data.js +42 -0
- package/dist/better-auth/plugin/lib/prepare-session-data.js.map +1 -0
- package/dist/better-auth/plugin/lib/respect-save-to-jwt-fields-middleware.d.ts +15 -0
- package/dist/better-auth/plugin/lib/respect-save-to-jwt-fields-middleware.js +30 -0
- package/dist/better-auth/plugin/lib/respect-save-to-jwt-fields-middleware.js.map +1 -0
- package/dist/better-auth/plugin/lib/sanitize-auth-options.d.ts +5 -0
- package/dist/better-auth/plugin/lib/sanitize-auth-options.js +298 -0
- package/dist/better-auth/plugin/lib/sanitize-auth-options.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/admin-buttons.d.ts +5 -0
- package/dist/better-auth/plugin/payload/components/admin-buttons.js +222 -0
- package/dist/better-auth/plugin/payload/components/admin-buttons.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/login-redirect.d.ts +1 -0
- package/dist/better-auth/plugin/payload/components/login-redirect.js +6 -0
- package/dist/better-auth/plugin/payload/components/login-redirect.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/logo.d.ts +1 -0
- package/dist/better-auth/plugin/payload/components/logo.js +36 -0
- package/dist/better-auth/plugin/payload/components/logo.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/logout.d.ts +1 -0
- package/dist/better-auth/plugin/payload/components/logout.js +61 -0
- package/dist/better-auth/plugin/payload/components/logout.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/sign-in.d.ts +3 -0
- package/dist/better-auth/plugin/payload/components/sign-in.js +384 -0
- package/dist/better-auth/plugin/payload/components/sign-in.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/sign-up.d.ts +6 -0
- package/dist/better-auth/plugin/payload/components/sign-up.js +502 -0
- package/dist/better-auth/plugin/payload/components/sign-up.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/styles.css +73 -0
- package/dist/better-auth/plugin/payload/components/ui/button.d.ts +10 -0
- package/dist/better-auth/plugin/payload/components/ui/button.js +42 -0
- package/dist/better-auth/plugin/payload/components/ui/button.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/ui/card.d.ts +9 -0
- package/dist/better-auth/plugin/payload/components/ui/card.js +55 -0
- package/dist/better-auth/plugin/payload/components/ui/card.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/ui/checkbox.d.ts +4 -0
- package/dist/better-auth/plugin/payload/components/ui/checkbox.js +23 -0
- package/dist/better-auth/plugin/payload/components/ui/checkbox.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/ui/cn.d.ts +2 -0
- package/dist/better-auth/plugin/payload/components/ui/cn.js +7 -0
- package/dist/better-auth/plugin/payload/components/ui/cn.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/ui/input.d.ts +3 -0
- package/dist/better-auth/plugin/payload/components/ui/input.js +14 -0
- package/dist/better-auth/plugin/payload/components/ui/input.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/ui/label.d.ts +4 -0
- package/dist/better-auth/plugin/payload/components/ui/label.js +15 -0
- package/dist/better-auth/plugin/payload/components/ui/label.js.map +1 -0
- package/dist/better-auth/plugin/payload/components/ui/password-input.d.ts +2 -0
- package/dist/better-auth/plugin/payload/components/ui/password-input.js +55 -0
- package/dist/better-auth/plugin/payload/components/ui/password-input.js.map +1 -0
- package/dist/better-auth/plugin/payload/exports/client.d.ts +3 -0
- package/dist/better-auth/plugin/payload/exports/client.js +5 -0
- package/dist/better-auth/plugin/payload/exports/client.js.map +1 -0
- package/dist/better-auth/plugin/payload/exports/rsc.d.ts +5 -0
- package/dist/better-auth/plugin/payload/exports/rsc.js +7 -0
- package/dist/better-auth/plugin/payload/exports/rsc.js.map +1 -0
- package/dist/better-auth/plugin/payload/views/create-first-admin/index.d.ts +4 -0
- package/dist/better-auth/plugin/payload/views/create-first-admin/index.js +112 -0
- package/dist/better-auth/plugin/payload/views/create-first-admin/index.js.map +1 -0
- package/dist/better-auth/plugin/payload/views/login/index.d.ts +4 -0
- package/dist/better-auth/plugin/payload/views/login/index.js +78 -0
- package/dist/better-auth/plugin/payload/views/login/index.js.map +1 -0
- package/dist/better-auth/plugin/types.d.ts +224 -0
- package/dist/better-auth/plugin/types.js +3 -0
- package/dist/better-auth/plugin/types.js.map +1 -0
- package/dist/better-auth/types.d.ts +2 -0
- package/dist/better-auth/types.js +4 -0
- package/dist/better-auth/types.js.map +1 -0
- package/dist/clerk/index.d.ts +1 -0
- package/dist/clerk/index.js +3 -0
- package/dist/clerk/index.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/kinde/index.d.ts +1 -0
- package/dist/kinde/index.js +3 -0
- package/dist/kinde/index.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { setCookieCache } from 'better-auth/cookies';
|
|
2
|
+
import { getFieldsToSign, refreshOperation } from 'payload';
|
|
3
|
+
import { getPayloadAuth } from '../../../lib/get-payload-auth';
|
|
4
|
+
export const getRefreshTokenEndpoint = (options)=>{
|
|
5
|
+
const userSlug = options?.userSlug;
|
|
6
|
+
const endpoint = {
|
|
7
|
+
path: '/refresh-token',
|
|
8
|
+
method: 'post',
|
|
9
|
+
handler: async (req)=>{
|
|
10
|
+
const payload = await getPayloadAuth(req.payload.config);
|
|
11
|
+
const betterAuth = payload.betterAuth;
|
|
12
|
+
const authContext = await betterAuth?.$context;
|
|
13
|
+
const userCollection = payload.collections[userSlug];
|
|
14
|
+
if (!betterAuth || !authContext) {
|
|
15
|
+
return new Response(JSON.stringify({
|
|
16
|
+
message: 'BetterAuth not initialized'
|
|
17
|
+
}), {
|
|
18
|
+
status: 500
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const sessionTokenName = authContext.authCookies.sessionToken.name;
|
|
22
|
+
const cookieHeader = req.headers.get('cookie') || '';
|
|
23
|
+
const hasSessionToken = cookieHeader.includes(`${sessionTokenName}=`);
|
|
24
|
+
if (!hasSessionToken) {
|
|
25
|
+
try {
|
|
26
|
+
const result = await refreshOperation({
|
|
27
|
+
collection: userCollection,
|
|
28
|
+
req
|
|
29
|
+
});
|
|
30
|
+
return new Response(JSON.stringify(result), {
|
|
31
|
+
status: 200
|
|
32
|
+
});
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error('Token refresh failed:', error);
|
|
35
|
+
return new Response(JSON.stringify({
|
|
36
|
+
message: 'Token refresh failed'
|
|
37
|
+
}), {
|
|
38
|
+
status: 401
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// @ts-ignore - @TODO, fix type of .api
|
|
43
|
+
const session = await betterAuth.api.getSession({
|
|
44
|
+
headers: req.headers,
|
|
45
|
+
query: {
|
|
46
|
+
disableCookieCache: true
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
if (!session?.session?.userId) {
|
|
50
|
+
return new Response(JSON.stringify({
|
|
51
|
+
message: 'No user in session'
|
|
52
|
+
}), {
|
|
53
|
+
status: 401
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const user = await payload.findByID({
|
|
57
|
+
collection: userSlug,
|
|
58
|
+
id: session.session.userId
|
|
59
|
+
});
|
|
60
|
+
if (!user) {
|
|
61
|
+
return new Response(JSON.stringify({
|
|
62
|
+
message: 'No user found'
|
|
63
|
+
}), {
|
|
64
|
+
status: 401
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const cookieCacheFields = getFieldsToSign({
|
|
68
|
+
collectionConfig: userCollection.config,
|
|
69
|
+
email: user.email,
|
|
70
|
+
user: user
|
|
71
|
+
});
|
|
72
|
+
const responseData = {
|
|
73
|
+
refreshedToken: null,
|
|
74
|
+
setCookie: !!authContext.options.session?.cookieCache?.enabled,
|
|
75
|
+
strategy: 'better-auth',
|
|
76
|
+
user: {
|
|
77
|
+
...user,
|
|
78
|
+
collection: userSlug
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const response = new Response(JSON.stringify(responseData), {
|
|
82
|
+
status: 200
|
|
83
|
+
});
|
|
84
|
+
const ctx = {
|
|
85
|
+
context: authContext,
|
|
86
|
+
setCookie (name, value, options) {
|
|
87
|
+
const path = options?.path || '/';
|
|
88
|
+
const maxAge = options?.maxAge ? `; Max-Age=${options.maxAge}` : '';
|
|
89
|
+
const httpOnly = options?.httpOnly ? '; HttpOnly' : '';
|
|
90
|
+
const secure = options?.secure ? '; Secure' : '';
|
|
91
|
+
const sameSite = options?.sameSite ? `; SameSite=${options.sameSite}` : '; SameSite=Lax';
|
|
92
|
+
response.headers.set('Set-Cookie', `${name}=${value}; Path=${path}${maxAge}${httpOnly}${secure}${sameSite}`);
|
|
93
|
+
return name;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
await setCookieCache(ctx, {
|
|
97
|
+
session: session.session,
|
|
98
|
+
user: cookieCacheFields
|
|
99
|
+
});
|
|
100
|
+
return response;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
return endpoint;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
//# sourceMappingURL=refresh-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/plugin/collections/users/endpoints/refresh-token.ts"],"sourcesContent":["import { setCookieCache } from 'better-auth/cookies'\nimport { CollectionSlug, type Endpoint, getFieldsToSign, refreshOperation, User } from 'payload'\nimport { GenericEndpointContext } from 'better-auth/types'\nimport { EndpointWithBetterAuth } from '../../../types'\nimport { getPayloadAuth } from '../../../lib/get-payload-auth'\n\ntype RefreshTokenEndpointOptions = {\n userSlug: CollectionSlug\n}\n\nexport const getRefreshTokenEndpoint = (options?: RefreshTokenEndpointOptions): Endpoint => {\n const userSlug = options?.userSlug\n\n const endpoint: EndpointWithBetterAuth = {\n path: '/refresh-token',\n method: 'post',\n handler: async (req) => {\n const payload = await getPayloadAuth(req.payload.config)\n const betterAuth = payload.betterAuth\n const authContext = await betterAuth?.$context\n const userCollection = payload.collections[userSlug as CollectionSlug]\n\n if (!betterAuth || !authContext) {\n return new Response(JSON.stringify({ message: 'BetterAuth not initialized' }), {\n status: 500,\n })\n }\n\n const sessionTokenName = authContext.authCookies.sessionToken.name\n const cookieHeader = req.headers.get('cookie') || ''\n const hasSessionToken = cookieHeader.includes(`${sessionTokenName}=`)\n\n if (!hasSessionToken) {\n try {\n const result = await refreshOperation({ collection: userCollection, req })\n return new Response(JSON.stringify(result), { status: 200 })\n } catch (error) {\n console.error('Token refresh failed:', error)\n return new Response(JSON.stringify({ message: 'Token refresh failed' }), { status: 401 })\n }\n }\n\n // @ts-ignore - @TODO, fix type of .api\n const session = await betterAuth.api.getSession({\n headers: req.headers,\n query: { disableCookieCache: true },\n })\n\n if (!session?.session?.userId) {\n return new Response(JSON.stringify({ message: 'No user in session' }), { status: 401 })\n }\n\n const user = await payload.findByID({\n collection: userSlug as string,\n id: session.session.userId,\n })\n\n if (!user) {\n return new Response(JSON.stringify({ message: 'No user found' }), { status: 401 })\n }\n\n const cookieCacheFields = getFieldsToSign({\n collectionConfig: userCollection.config,\n email: user.email,\n user: user as User,\n })\n\n const responseData = {\n refreshedToken: null,\n setCookie: !!authContext.options.session?.cookieCache?.enabled,\n strategy: 'better-auth',\n user: { ...user, collection: userSlug },\n }\n\n const response = new Response(JSON.stringify(responseData), {\n status: 200,\n })\n\n const ctx = {\n context: authContext,\n setCookie(name, value, options) {\n const path = options?.path || '/'\n const maxAge = options?.maxAge ? `; Max-Age=${options.maxAge}` : ''\n const httpOnly = options?.httpOnly ? '; HttpOnly' : ''\n const secure = options?.secure ? '; Secure' : ''\n const sameSite = options?.sameSite ? `; SameSite=${options.sameSite}` : '; SameSite=Lax'\n\n response.headers.set(\n 'Set-Cookie',\n `${name}=${value}; Path=${path}${maxAge}${httpOnly}${secure}${sameSite}`,\n )\n return name\n },\n } as GenericEndpointContext\n\n await setCookieCache(ctx, {\n session: session.session,\n user: cookieCacheFields as any,\n })\n\n return response\n },\n }\n\n return endpoint as unknown as Endpoint\n}\n"],"names":["setCookieCache","getFieldsToSign","refreshOperation","getPayloadAuth","getRefreshTokenEndpoint","options","userSlug","endpoint","path","method","handler","req","payload","config","betterAuth","authContext","$context","userCollection","collections","Response","JSON","stringify","message","status","sessionTokenName","authCookies","sessionToken","name","cookieHeader","headers","get","hasSessionToken","includes","result","collection","error","console","session","api","getSession","query","disableCookieCache","userId","user","findByID","id","cookieCacheFields","collectionConfig","email","responseData","refreshedToken","setCookie","cookieCache","enabled","strategy","response","ctx","context","value","maxAge","httpOnly","secure","sameSite","set"],"mappings":"AAAA,SAASA,cAAc,QAAQ,sBAAqB;AACpD,SAAwCC,eAAe,EAAEC,gBAAgB,QAAc,UAAS;AAGhG,SAASC,cAAc,QAAQ,gCAA+B;AAM9D,OAAO,MAAMC,0BAA0B,CAACC;IACtC,MAAMC,WAAWD,SAASC;IAE1B,MAAMC,WAAmC;QACvCC,MAAM;QACNC,QAAQ;QACRC,SAAS,OAAOC;YACd,MAAMC,UAAU,MAAMT,eAAeQ,IAAIC,OAAO,CAACC,MAAM;YACvD,MAAMC,aAAaF,QAAQE,UAAU;YACrC,MAAMC,cAAc,MAAMD,YAAYE;YACtC,MAAMC,iBAAiBL,QAAQM,WAAW,CAACZ,SAA2B;YAEtE,IAAI,CAACQ,cAAc,CAACC,aAAa;gBAC/B,OAAO,IAAII,SAASC,KAAKC,SAAS,CAAC;oBAAEC,SAAS;gBAA6B,IAAI;oBAC7EC,QAAQ;gBACV;YACF;YAEA,MAAMC,mBAAmBT,YAAYU,WAAW,CAACC,YAAY,CAACC,IAAI;YAClE,MAAMC,eAAejB,IAAIkB,OAAO,CAACC,GAAG,CAAC,aAAa;YAClD,MAAMC,kBAAkBH,aAAaI,QAAQ,CAAC,GAAGR,iBAAiB,CAAC,CAAC;YAEpE,IAAI,CAACO,iBAAiB;gBACpB,IAAI;oBACF,MAAME,SAAS,MAAM/B,iBAAiB;wBAAEgC,YAAYjB;wBAAgBN;oBAAI;oBACxE,OAAO,IAAIQ,SAASC,KAAKC,SAAS,CAACY,SAAS;wBAAEV,QAAQ;oBAAI;gBAC5D,EAAE,OAAOY,OAAO;oBACdC,QAAQD,KAAK,CAAC,yBAAyBA;oBACvC,OAAO,IAAIhB,SAASC,KAAKC,SAAS,CAAC;wBAAEC,SAAS;oBAAuB,IAAI;wBAAEC,QAAQ;oBAAI;gBACzF;YACF;YAEA,uCAAuC;YACvC,MAAMc,UAAU,MAAMvB,WAAWwB,GAAG,CAACC,UAAU,CAAC;gBAC9CV,SAASlB,IAAIkB,OAAO;gBACpBW,OAAO;oBAAEC,oBAAoB;gBAAK;YACpC;YAEA,IAAI,CAACJ,SAASA,SAASK,QAAQ;gBAC7B,OAAO,IAAIvB,SAASC,KAAKC,SAAS,CAAC;oBAAEC,SAAS;gBAAqB,IAAI;oBAAEC,QAAQ;gBAAI;YACvF;YAEA,MAAMoB,OAAO,MAAM/B,QAAQgC,QAAQ,CAAC;gBAClCV,YAAY5B;gBACZuC,IAAIR,QAAQA,OAAO,CAACK,MAAM;YAC5B;YAEA,IAAI,CAACC,MAAM;gBACT,OAAO,IAAIxB,SAASC,KAAKC,SAAS,CAAC;oBAAEC,SAAS;gBAAgB,IAAI;oBAAEC,QAAQ;gBAAI;YAClF;YAEA,MAAMuB,oBAAoB7C,gBAAgB;gBACxC8C,kBAAkB9B,eAAeJ,MAAM;gBACvCmC,OAAOL,KAAKK,KAAK;gBACjBL,MAAMA;YACR;YAEA,MAAMM,eAAe;gBACnBC,gBAAgB;gBAChBC,WAAW,CAAC,CAACpC,YAAYV,OAAO,CAACgC,OAAO,EAAEe,aAAaC;gBACvDC,UAAU;gBACVX,MAAM;oBAAE,GAAGA,IAAI;oBAAET,YAAY5B;gBAAS;YACxC;YAEA,MAAMiD,WAAW,IAAIpC,SAASC,KAAKC,SAAS,CAAC4B,eAAe;gBAC1D1B,QAAQ;YACV;YAEA,MAAMiC,MAAM;gBACVC,SAAS1C;gBACToC,WAAUxB,IAAI,EAAE+B,KAAK,EAAErD,OAAO;oBAC5B,MAAMG,OAAOH,SAASG,QAAQ;oBAC9B,MAAMmD,SAAStD,SAASsD,SAAS,CAAC,UAAU,EAAEtD,QAAQsD,MAAM,EAAE,GAAG;oBACjE,MAAMC,WAAWvD,SAASuD,WAAW,eAAe;oBACpD,MAAMC,SAASxD,SAASwD,SAAS,aAAa;oBAC9C,MAAMC,WAAWzD,SAASyD,WAAW,CAAC,WAAW,EAAEzD,QAAQyD,QAAQ,EAAE,GAAG;oBAExEP,SAAS1B,OAAO,CAACkC,GAAG,CAClB,cACA,GAAGpC,KAAK,CAAC,EAAE+B,MAAM,OAAO,EAAElD,OAAOmD,SAASC,WAAWC,SAASC,UAAU;oBAE1E,OAAOnC;gBACT;YACF;YAEA,MAAM3B,eAAewD,KAAK;gBACxBnB,SAASA,QAAQA,OAAO;gBACxBM,MAAMG;YACR;YAEA,OAAOS;QACT;IACF;IAEA,OAAOhD;AACT,EAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CollectionAfterLoginHook } from 'payload';
|
|
2
|
+
type AfterLoginOptions = {
|
|
3
|
+
usersCollectionSlug: string;
|
|
4
|
+
sessionsCollectionSlug: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* This hook is used to sync the admin login token with better-auth session token
|
|
8
|
+
* It also creates a new session in better-auth
|
|
9
|
+
*/
|
|
10
|
+
export declare const getAfterLoginHook: (options: AfterLoginOptions) => CollectionAfterLoginHook;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { generateId } from 'better-auth';
|
|
2
|
+
import { createAuthMiddleware } from 'better-auth/api';
|
|
3
|
+
import { setCookieCache } from 'better-auth/cookies';
|
|
4
|
+
import { parseSetCookie } from 'next/dist/compiled/@edge-runtime/cookies';
|
|
5
|
+
import { cookies } from 'next/headers';
|
|
6
|
+
import { getPayloadAuth } from '../../../lib/get-payload-auth';
|
|
7
|
+
import { getIp } from '../../../helpers/get-ip';
|
|
8
|
+
import { prepareSessionData } from '../../../lib/prepare-session-data';
|
|
9
|
+
/**
|
|
10
|
+
* This hook is used to sync the admin login token with better-auth session token
|
|
11
|
+
* It also creates a new session in better-auth
|
|
12
|
+
*/ export const getAfterLoginHook = (options)=>{
|
|
13
|
+
const hook = async ({ collection, context, req, token, user })=>{
|
|
14
|
+
const config = req.payload.config;
|
|
15
|
+
const payload = await getPayloadAuth(config);
|
|
16
|
+
const cookieStore = await cookies();
|
|
17
|
+
const authContext = await payload.betterAuth.$context;
|
|
18
|
+
const sessionExpiration = payload.betterAuth.options.session?.expiresIn || 60 * 60 * 24 * 7 // 7 days
|
|
19
|
+
;
|
|
20
|
+
// we can't use internal adapter as we can cause a race condition unless we pass req to the payload.create
|
|
21
|
+
const session = await payload.create({
|
|
22
|
+
collection: options.sessionsCollectionSlug,
|
|
23
|
+
data: {
|
|
24
|
+
ipAddress: getIp(req.headers, payload.betterAuth.options) || '',
|
|
25
|
+
userAgent: req.headers?.get('user-agent') || '',
|
|
26
|
+
user: user.id,
|
|
27
|
+
token: generateId(32),
|
|
28
|
+
expiresAt: new Date(Date.now() + sessionExpiration * 1000)
|
|
29
|
+
},
|
|
30
|
+
req
|
|
31
|
+
});
|
|
32
|
+
const betterAuthHandleRequest = createAuthMiddleware(async (ctx)=>{
|
|
33
|
+
ctx.context = {
|
|
34
|
+
...authContext,
|
|
35
|
+
user: user
|
|
36
|
+
};
|
|
37
|
+
await ctx.setSignedCookie(ctx.context.authCookies.sessionToken.name, session.token, ctx.context.secret, ctx.context.authCookies.sessionToken.options);
|
|
38
|
+
const filteredSessionData = await prepareSessionData({
|
|
39
|
+
newSession: {
|
|
40
|
+
session,
|
|
41
|
+
user
|
|
42
|
+
},
|
|
43
|
+
payloadConfig: config,
|
|
44
|
+
collectionSlugs: {
|
|
45
|
+
userCollectionSlug: options.usersCollectionSlug,
|
|
46
|
+
sessionCollectionSlug: options.sessionsCollectionSlug
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
await setCookieCache(ctx, filteredSessionData);
|
|
50
|
+
if ('responseHeaders' in ctx) {
|
|
51
|
+
return ctx.responseHeaders;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
});
|
|
55
|
+
const responseHeaders = await betterAuthHandleRequest(req);
|
|
56
|
+
const responseCookies = responseHeaders?.getSetCookie().map((cookie)=>parseSetCookie(cookie)).filter(Boolean);
|
|
57
|
+
if (responseCookies) {
|
|
58
|
+
for (const cookieData of responseCookies){
|
|
59
|
+
const { name, value, ...options } = cookieData;
|
|
60
|
+
cookieStore.set({
|
|
61
|
+
...options,
|
|
62
|
+
name,
|
|
63
|
+
value: decodeURIComponent(value)
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
return hook;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=after-login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/plugin/collections/users/hooks/after-login.ts"],"sourcesContent":["import { generateId, Session } from 'better-auth'\nimport { createAuthMiddleware } from 'better-auth/api'\nimport { setCookieCache } from 'better-auth/cookies'\nimport { parseSetCookie, type ResponseCookie } from 'next/dist/compiled/@edge-runtime/cookies'\nimport { cookies } from 'next/headers'\nimport { CollectionAfterLoginHook } from 'payload'\nimport { getPayloadAuth } from '../../../lib/get-payload-auth'\nimport { getIp } from '../../../helpers/get-ip'\nimport { prepareSessionData } from '../../../lib/prepare-session-data'\n\ntype AfterLoginOptions = {\n usersCollectionSlug: string\n sessionsCollectionSlug: string\n}\n\n/**\n * This hook is used to sync the admin login token with better-auth session token\n * It also creates a new session in better-auth\n */\nexport const getAfterLoginHook = (options: AfterLoginOptions): CollectionAfterLoginHook => {\n const hook: CollectionAfterLoginHook = async ({ collection, context, req, token, user }) => {\n const config = req.payload.config\n const payload = await getPayloadAuth(config)\n const cookieStore = await cookies()\n const authContext = await payload.betterAuth.$context\n\n const sessionExpiration = payload.betterAuth.options.session?.expiresIn || 60 * 60 * 24 * 7 // 7 days\n // we can't use internal adapter as we can cause a race condition unless we pass req to the payload.create\n const session = (await payload.create({\n collection: options.sessionsCollectionSlug,\n data: {\n ipAddress: getIp(req.headers, payload.betterAuth.options) || '',\n userAgent: req.headers?.get('user-agent') || '',\n user: user.id,\n token: generateId(32),\n expiresAt: new Date(Date.now() + sessionExpiration * 1000),\n },\n req,\n })) as Session\n\n const betterAuthHandleRequest = createAuthMiddleware(async (ctx): Promise<Headers | null> => {\n ctx.context = { ...authContext, user: user }\n await ctx.setSignedCookie(\n ctx.context.authCookies.sessionToken.name,\n session.token,\n ctx.context.secret,\n ctx.context.authCookies.sessionToken.options,\n )\n const filteredSessionData = await prepareSessionData({\n newSession: { session, user },\n payloadConfig: config,\n collectionSlugs: {\n userCollectionSlug: options.usersCollectionSlug,\n sessionCollectionSlug: options.sessionsCollectionSlug,\n },\n })\n await setCookieCache(ctx, filteredSessionData as any)\n if ('responseHeaders' in ctx) {\n return ctx.responseHeaders as Headers\n }\n return null\n })\n\n const responseHeaders = await betterAuthHandleRequest(req)\n const responseCookies = responseHeaders\n ?.getSetCookie()\n .map((cookie) => parseSetCookie(cookie))\n .filter(Boolean) as ResponseCookie[]\n\n if (responseCookies) {\n for (const cookieData of responseCookies) {\n const { name, value, ...options } = cookieData\n cookieStore.set({\n ...options,\n name,\n value: decodeURIComponent(value),\n })\n }\n }\n }\n\n return hook as CollectionAfterLoginHook\n}\n"],"names":["generateId","createAuthMiddleware","setCookieCache","parseSetCookie","cookies","getPayloadAuth","getIp","prepareSessionData","getAfterLoginHook","options","hook","collection","context","req","token","user","config","payload","cookieStore","authContext","betterAuth","$context","sessionExpiration","session","expiresIn","create","sessionsCollectionSlug","data","ipAddress","headers","userAgent","get","id","expiresAt","Date","now","betterAuthHandleRequest","ctx","setSignedCookie","authCookies","sessionToken","name","secret","filteredSessionData","newSession","payloadConfig","collectionSlugs","userCollectionSlug","usersCollectionSlug","sessionCollectionSlug","responseHeaders","responseCookies","getSetCookie","map","cookie","filter","Boolean","cookieData","value","set","decodeURIComponent"],"mappings":"AAAA,SAASA,UAAU,QAAiB,cAAa;AACjD,SAASC,oBAAoB,QAAQ,kBAAiB;AACtD,SAASC,cAAc,QAAQ,sBAAqB;AACpD,SAASC,cAAc,QAA6B,2CAA0C;AAC9F,SAASC,OAAO,QAAQ,eAAc;AAEtC,SAASC,cAAc,QAAQ,gCAA+B;AAC9D,SAASC,KAAK,QAAQ,0BAAyB;AAC/C,SAASC,kBAAkB,QAAQ,oCAAmC;AAOtE;;;CAGC,GACD,OAAO,MAAMC,oBAAoB,CAACC;IAChC,MAAMC,OAAiC,OAAO,EAAEC,UAAU,EAAEC,OAAO,EAAEC,GAAG,EAAEC,KAAK,EAAEC,IAAI,EAAE;QACrF,MAAMC,SAASH,IAAII,OAAO,CAACD,MAAM;QACjC,MAAMC,UAAU,MAAMZ,eAAeW;QACrC,MAAME,cAAc,MAAMd;QAC1B,MAAMe,cAAc,MAAMF,QAAQG,UAAU,CAACC,QAAQ;QAErD,MAAMC,oBAAoBL,QAAQG,UAAU,CAACX,OAAO,CAACc,OAAO,EAAEC,aAAa,KAAK,KAAK,KAAK,EAAE,SAAS;;QACrG,0GAA0G;QAC1G,MAAMD,UAAW,MAAMN,QAAQQ,MAAM,CAAC;YACpCd,YAAYF,QAAQiB,sBAAsB;YAC1CC,MAAM;gBACJC,WAAWtB,MAAMO,IAAIgB,OAAO,EAAEZ,QAAQG,UAAU,CAACX,OAAO,KAAK;gBAC7DqB,WAAWjB,IAAIgB,OAAO,EAAEE,IAAI,iBAAiB;gBAC7ChB,MAAMA,KAAKiB,EAAE;gBACblB,OAAOd,WAAW;gBAClBiC,WAAW,IAAIC,KAAKA,KAAKC,GAAG,KAAKb,oBAAoB;YACvD;YACAT;QACF;QAEA,MAAMuB,0BAA0BnC,qBAAqB,OAAOoC;YAC1DA,IAAIzB,OAAO,GAAG;gBAAE,GAAGO,WAAW;gBAAEJ,MAAMA;YAAK;YAC3C,MAAMsB,IAAIC,eAAe,CACvBD,IAAIzB,OAAO,CAAC2B,WAAW,CAACC,YAAY,CAACC,IAAI,EACzClB,QAAQT,KAAK,EACbuB,IAAIzB,OAAO,CAAC8B,MAAM,EAClBL,IAAIzB,OAAO,CAAC2B,WAAW,CAACC,YAAY,CAAC/B,OAAO;YAE9C,MAAMkC,sBAAsB,MAAMpC,mBAAmB;gBACnDqC,YAAY;oBAAErB;oBAASR;gBAAK;gBAC5B8B,eAAe7B;gBACf8B,iBAAiB;oBACfC,oBAAoBtC,QAAQuC,mBAAmB;oBAC/CC,uBAAuBxC,QAAQiB,sBAAsB;gBACvD;YACF;YACA,MAAMxB,eAAemC,KAAKM;YAC1B,IAAI,qBAAqBN,KAAK;gBAC5B,OAAOA,IAAIa,eAAe;YAC5B;YACA,OAAO;QACT;QAEA,MAAMA,kBAAkB,MAAMd,wBAAwBvB;QACtD,MAAMsC,kBAAkBD,iBACpBE,eACDC,IAAI,CAACC,SAAWnD,eAAemD,SAC/BC,OAAOC;QAEV,IAAIL,iBAAiB;YACnB,KAAK,MAAMM,cAAcN,gBAAiB;gBACxC,MAAM,EAAEV,IAAI,EAAEiB,KAAK,EAAE,GAAGjD,SAAS,GAAGgD;gBACpCvC,YAAYyC,GAAG,CAAC;oBACd,GAAGlD,OAAO;oBACVgC;oBACAiB,OAAOE,mBAAmBF;gBAC5B;YACF;QACF;IACF;IAEA,OAAOhD;AACT,EAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { cookies } from 'next/headers';
|
|
2
|
+
import { getPayloadAuth } from '../../../lib/get-payload-auth';
|
|
3
|
+
export const getAfterLogoutHook = (options)=>{
|
|
4
|
+
const hook = async ({ req })=>{
|
|
5
|
+
const cookieStore = await cookies();
|
|
6
|
+
const payload = await getPayloadAuth(req.payload.config);
|
|
7
|
+
const authContext = await payload.betterAuth.$context;
|
|
8
|
+
const sessionTokenName = authContext.authCookies.sessionToken.name;
|
|
9
|
+
const sessionDataName = authContext.authCookies.sessionData.name;
|
|
10
|
+
const dontRememberTokenName = authContext.authCookies.dontRememberToken.name;
|
|
11
|
+
const sessionCookieValue = cookieStore.get(sessionTokenName)?.value;
|
|
12
|
+
if (sessionCookieValue) {
|
|
13
|
+
const payload = req.payload;
|
|
14
|
+
const [token] = sessionCookieValue.split('.');
|
|
15
|
+
const { docs: sessions } = await payload.find({
|
|
16
|
+
collection: options.sessionsCollectionSlug,
|
|
17
|
+
where: {
|
|
18
|
+
token: {
|
|
19
|
+
equals: token
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
limit: 1
|
|
23
|
+
});
|
|
24
|
+
const session = sessions.at(0);
|
|
25
|
+
if (session) {
|
|
26
|
+
await payload.delete({
|
|
27
|
+
collection: options.sessionsCollectionSlug,
|
|
28
|
+
id: session.id
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const baseMultiSessionName = sessionTokenName + '_multi';
|
|
33
|
+
const multiSessionCookies = cookieStore.getAll();
|
|
34
|
+
multiSessionCookies.forEach((cookie)=>{
|
|
35
|
+
if (cookie.name.startsWith(baseMultiSessionName)) {
|
|
36
|
+
cookieStore.delete(cookie.name);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
//TODO: this is a hack to delete the admin session cookie
|
|
40
|
+
// we need to find a better way to do this (BETTER AUTH HARDCODED THIS)
|
|
41
|
+
cookieStore.delete('admin_session');
|
|
42
|
+
cookieStore.delete(sessionTokenName);
|
|
43
|
+
cookieStore.delete(sessionDataName);
|
|
44
|
+
cookieStore.delete(dontRememberTokenName);
|
|
45
|
+
};
|
|
46
|
+
return hook;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=after-logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/plugin/collections/users/hooks/after-logout.ts"],"sourcesContent":["import { cookies } from 'next/headers'\nimport type { CollectionAfterLogoutHook } from 'payload'\nimport type { CollectionHookWithBetterAuth } from '../../../types'\nimport { getPayloadAuth } from '../../../lib/get-payload-auth'\n\ntype CollectionAfterLogoutHookWithBetterAuth =\n CollectionHookWithBetterAuth<CollectionAfterLogoutHook>\n\ntype AfterLogoutOptions = {\n sessionsCollectionSlug: string\n}\n\nexport const getAfterLogoutHook = (options: AfterLogoutOptions): CollectionAfterLogoutHook => {\n const hook: CollectionAfterLogoutHookWithBetterAuth = async ({ req }) => {\n const cookieStore = await cookies()\n const payload = await getPayloadAuth(req.payload.config)\n const authContext = await payload.betterAuth.$context\n const sessionTokenName = authContext.authCookies.sessionToken.name\n\n const sessionDataName = authContext.authCookies.sessionData.name\n const dontRememberTokenName = authContext.authCookies.dontRememberToken.name\n\n const sessionCookieValue = cookieStore.get(sessionTokenName)?.value\n if (sessionCookieValue) {\n const payload = req.payload\n const [token] = sessionCookieValue.split('.')\n const { docs: sessions } = await payload.find({\n collection: options.sessionsCollectionSlug,\n where: {\n token: { equals: token },\n },\n limit: 1,\n })\n const session = sessions.at(0)\n if (session) {\n await payload.delete({\n collection: options.sessionsCollectionSlug,\n id: session.id,\n })\n }\n }\n\n const baseMultiSessionName = sessionTokenName + '_multi'\n const multiSessionCookies = cookieStore.getAll()\n multiSessionCookies.forEach((cookie) => {\n if (cookie.name.startsWith(baseMultiSessionName)) {\n cookieStore.delete(cookie.name)\n }\n })\n\n //TODO: this is a hack to delete the admin session cookie\n // we need to find a better way to do this (BETTER AUTH HARDCODED THIS)\n cookieStore.delete('admin_session')\n\n cookieStore.delete(sessionTokenName)\n cookieStore.delete(sessionDataName)\n cookieStore.delete(dontRememberTokenName)\n }\n\n return hook as CollectionAfterLogoutHook\n}\n"],"names":["cookies","getPayloadAuth","getAfterLogoutHook","options","hook","req","cookieStore","payload","config","authContext","betterAuth","$context","sessionTokenName","authCookies","sessionToken","name","sessionDataName","sessionData","dontRememberTokenName","dontRememberToken","sessionCookieValue","get","value","token","split","docs","sessions","find","collection","sessionsCollectionSlug","where","equals","limit","session","at","delete","id","baseMultiSessionName","multiSessionCookies","getAll","forEach","cookie","startsWith"],"mappings":"AAAA,SAASA,OAAO,QAAQ,eAAc;AAGtC,SAASC,cAAc,QAAQ,gCAA+B;AAS9D,OAAO,MAAMC,qBAAqB,CAACC;IACjC,MAAMC,OAAgD,OAAO,EAAEC,GAAG,EAAE;QAClE,MAAMC,cAAc,MAAMN;QAC1B,MAAMO,UAAU,MAAMN,eAAeI,IAAIE,OAAO,CAACC,MAAM;QACvD,MAAMC,cAAc,MAAMF,QAAQG,UAAU,CAACC,QAAQ;QACrD,MAAMC,mBAAmBH,YAAYI,WAAW,CAACC,YAAY,CAACC,IAAI;QAElE,MAAMC,kBAAkBP,YAAYI,WAAW,CAACI,WAAW,CAACF,IAAI;QAChE,MAAMG,wBAAwBT,YAAYI,WAAW,CAACM,iBAAiB,CAACJ,IAAI;QAE5E,MAAMK,qBAAqBd,YAAYe,GAAG,CAACT,mBAAmBU;QAC9D,IAAIF,oBAAoB;YACtB,MAAMb,UAAUF,IAAIE,OAAO;YAC3B,MAAM,CAACgB,MAAM,GAAGH,mBAAmBI,KAAK,CAAC;YACzC,MAAM,EAAEC,MAAMC,QAAQ,EAAE,GAAG,MAAMnB,QAAQoB,IAAI,CAAC;gBAC5CC,YAAYzB,QAAQ0B,sBAAsB;gBAC1CC,OAAO;oBACLP,OAAO;wBAAEQ,QAAQR;oBAAM;gBACzB;gBACAS,OAAO;YACT;YACA,MAAMC,UAAUP,SAASQ,EAAE,CAAC;YAC5B,IAAID,SAAS;gBACX,MAAM1B,QAAQ4B,MAAM,CAAC;oBACnBP,YAAYzB,QAAQ0B,sBAAsB;oBAC1CO,IAAIH,QAAQG,EAAE;gBAChB;YACF;QACF;QAEA,MAAMC,uBAAuBzB,mBAAmB;QAChD,MAAM0B,sBAAsBhC,YAAYiC,MAAM;QAC9CD,oBAAoBE,OAAO,CAAC,CAACC;YAC3B,IAAIA,OAAO1B,IAAI,CAAC2B,UAAU,CAACL,uBAAuB;gBAChD/B,YAAY6B,MAAM,CAACM,OAAO1B,IAAI;YAChC;QACF;QAEA,yDAAyD;QACzD,uEAAuE;QACvET,YAAY6B,MAAM,CAAC;QAEnB7B,YAAY6B,MAAM,CAACvB;QACnBN,YAAY6B,MAAM,CAACnB;QACnBV,YAAY6B,MAAM,CAACjB;IACrB;IAEA,OAAOd;AACT,EAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { APIError } from 'payload';
|
|
2
|
+
import { getPayloadAuth } from '../../../lib/get-payload-auth';
|
|
3
|
+
/**
|
|
4
|
+
* This hook blocks login attempts if email verification is required and the user's email is not verified
|
|
5
|
+
*/ export const getBeforeLoginHook = ()=>{
|
|
6
|
+
const hook = async ({ req, user })=>{
|
|
7
|
+
const config = req.payload.config;
|
|
8
|
+
const payload = await getPayloadAuth(config);
|
|
9
|
+
const requireEmailVerification = payload.betterAuth.options.emailAndPassword?.requireEmailVerification ?? false;
|
|
10
|
+
if (requireEmailVerification && !user.emailVerified) {
|
|
11
|
+
throw new APIError('Email verification required. Please verify your email before logging in.', 403);
|
|
12
|
+
}
|
|
13
|
+
return user;
|
|
14
|
+
};
|
|
15
|
+
return hook;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=before-login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/plugin/collections/users/hooks/before-login.ts"],"sourcesContent":["import { APIError, CollectionBeforeLoginHook } from 'payload'\nimport { getPayloadAuth } from '../../../lib/get-payload-auth'\n\n/**\n * This hook blocks login attempts if email verification is required and the user's email is not verified\n */\nexport const getBeforeLoginHook = (): CollectionBeforeLoginHook => {\n const hook: CollectionBeforeLoginHook = async ({ req, user }) => {\n const config = req.payload.config\n const payload = await getPayloadAuth(config)\n\n const requireEmailVerification =\n payload.betterAuth.options.emailAndPassword?.requireEmailVerification ?? false\n\n if (requireEmailVerification && !user.emailVerified) {\n throw new APIError(\n 'Email verification required. Please verify your email before logging in.',\n 403,\n )\n }\n\n return user\n }\n\n return hook\n}\n"],"names":["APIError","getPayloadAuth","getBeforeLoginHook","hook","req","user","config","payload","requireEmailVerification","betterAuth","options","emailAndPassword","emailVerified"],"mappings":"AAAA,SAASA,QAAQ,QAAmC,UAAS;AAC7D,SAASC,cAAc,QAAQ,gCAA+B;AAE9D;;CAEC,GACD,OAAO,MAAMC,qBAAqB;IAChC,MAAMC,OAAkC,OAAO,EAAEC,GAAG,EAAEC,IAAI,EAAE;QAC1D,MAAMC,SAASF,IAAIG,OAAO,CAACD,MAAM;QACjC,MAAMC,UAAU,MAAMN,eAAeK;QAErC,MAAME,2BACJD,QAAQE,UAAU,CAACC,OAAO,CAACC,gBAAgB,EAAEH,4BAA4B;QAE3E,IAAIA,4BAA4B,CAACH,KAAKO,aAAa,EAAE;YACnD,MAAM,IAAIZ,SACR,4EACA;QAEJ;QAEA,OAAOK;IACT;IAEA,OAAOF;AACT,EAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CollectionAfterDeleteHook } from 'payload';
|
|
2
|
+
import type { CollectionHookWithBetterAuth } from '../../../types';
|
|
3
|
+
type CollectionAfterDeleteHookWithBetterAuth = CollectionHookWithBetterAuth<CollectionAfterDeleteHook>;
|
|
4
|
+
export declare const cleanUpUserAfterDelete: CollectionAfterDeleteHookWithBetterAuth;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const cleanUpUserAfterDelete = async ({ doc, req })=>{
|
|
2
|
+
try {
|
|
3
|
+
const { payload } = req;
|
|
4
|
+
const betterAuthContext = await payload.betterAuth.$context;
|
|
5
|
+
const userId = doc.id;
|
|
6
|
+
const beforeDelete = betterAuthContext.options.user?.deleteUser?.beforeDelete;
|
|
7
|
+
if (typeof beforeDelete === 'function') {
|
|
8
|
+
await beforeDelete(doc, req);
|
|
9
|
+
}
|
|
10
|
+
await betterAuthContext.internalAdapter.deleteSessions(userId);
|
|
11
|
+
await betterAuthContext.internalAdapter.deleteAccounts(userId);
|
|
12
|
+
if (payload.collections.verifications) {
|
|
13
|
+
await payload.delete({
|
|
14
|
+
collection: payload.collections.verifications.config.slug,
|
|
15
|
+
where: {
|
|
16
|
+
value: {
|
|
17
|
+
like: `"${userId}"`
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const afterDelete = betterAuthContext.options.user?.deleteUser?.afterDelete;
|
|
23
|
+
if (typeof afterDelete === 'function') {
|
|
24
|
+
await afterDelete(doc, req);
|
|
25
|
+
}
|
|
26
|
+
return doc;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error('Error in user afterDelete hook:', error);
|
|
29
|
+
return doc;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=clean-up-user-after-delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/plugin/collections/users/hooks/clean-up-user-after-delete.ts"],"sourcesContent":["import type { CollectionAfterDeleteHook } from 'payload'\nimport type { CollectionHookWithBetterAuth } from '../../../types'\n\ntype CollectionAfterDeleteHookWithBetterAuth =\n CollectionHookWithBetterAuth<CollectionAfterDeleteHook>\n\nexport const cleanUpUserAfterDelete: CollectionAfterDeleteHookWithBetterAuth = async ({\n doc,\n req,\n}) => {\n try {\n const { payload } = req\n const betterAuthContext = await payload.betterAuth.$context\n const userId = doc.id\n const beforeDelete = betterAuthContext.options.user?.deleteUser?.beforeDelete\n if (typeof beforeDelete === 'function') {\n await beforeDelete(doc, req as Request)\n }\n await betterAuthContext.internalAdapter.deleteSessions(userId)\n await betterAuthContext.internalAdapter.deleteAccounts(userId)\n if (payload.collections.verifications) {\n await payload.delete({\n collection: payload.collections.verifications.config.slug,\n where: {\n value: {\n like: `\"${userId}\"`,\n },\n },\n })\n }\n const afterDelete = betterAuthContext.options.user?.deleteUser?.afterDelete\n if (typeof afterDelete === 'function') {\n await afterDelete(doc, req as Request)\n }\n return doc\n } catch (error) {\n console.error('Error in user afterDelete hook:', error)\n return doc\n }\n}\n"],"names":["cleanUpUserAfterDelete","doc","req","payload","betterAuthContext","betterAuth","$context","userId","id","beforeDelete","options","user","deleteUser","internalAdapter","deleteSessions","deleteAccounts","collections","verifications","delete","collection","config","slug","where","value","like","afterDelete","error","console"],"mappings":"AAMA,OAAO,MAAMA,yBAAkE,OAAO,EACpFC,GAAG,EACHC,GAAG,EACJ;IACC,IAAI;QACF,MAAM,EAAEC,OAAO,EAAE,GAAGD;QACpB,MAAME,oBAAoB,MAAMD,QAAQE,UAAU,CAACC,QAAQ;QAC3D,MAAMC,SAASN,IAAIO,EAAE;QACrB,MAAMC,eAAeL,kBAAkBM,OAAO,CAACC,IAAI,EAAEC,YAAYH;QACjE,IAAI,OAAOA,iBAAiB,YAAY;YACtC,MAAMA,aAAaR,KAAKC;QAC1B;QACA,MAAME,kBAAkBS,eAAe,CAACC,cAAc,CAACP;QACvD,MAAMH,kBAAkBS,eAAe,CAACE,cAAc,CAACR;QACvD,IAAIJ,QAAQa,WAAW,CAACC,aAAa,EAAE;YACrC,MAAMd,QAAQe,MAAM,CAAC;gBACnBC,YAAYhB,QAAQa,WAAW,CAACC,aAAa,CAACG,MAAM,CAACC,IAAI;gBACzDC,OAAO;oBACLC,OAAO;wBACLC,MAAM,CAAC,CAAC,EAAEjB,OAAO,CAAC,CAAC;oBACrB;gBACF;YACF;QACF;QACA,MAAMkB,cAAcrB,kBAAkBM,OAAO,CAACC,IAAI,EAAEC,YAAYa;QAChE,IAAI,OAAOA,gBAAgB,YAAY;YACrC,MAAMA,YAAYxB,KAAKC;QACzB;QACA,OAAOD;IACT,EAAE,OAAOyB,OAAO;QACdC,QAAQD,KAAK,CAAC,mCAAmCA;QACjD,OAAOzB;IACT;AACF,EAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const onVerifiedChange = async ({ data, originalDoc })=>{
|
|
2
|
+
const isVerifiedChangingToTrue = Boolean(data._verified) && !Boolean(originalDoc?._verified);
|
|
3
|
+
const isEmailVerifiedChangingToTrue = Boolean(data.emailVerified) && !Boolean(originalDoc?.emailVerified);
|
|
4
|
+
if (!isVerifiedChangingToTrue && !isEmailVerifiedChangingToTrue) {
|
|
5
|
+
return data;
|
|
6
|
+
}
|
|
7
|
+
return {
|
|
8
|
+
...data,
|
|
9
|
+
_verified: true,
|
|
10
|
+
emailVerified: true
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=on-verified-change.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/plugin/collections/users/hooks/on-verified-change.ts"],"sourcesContent":["import { CollectionBeforeChangeHook } from 'payload'\n\nexport const onVerifiedChange: CollectionBeforeChangeHook = async ({ data, originalDoc }) => {\n const isVerifiedChangingToTrue = Boolean(data._verified) && !Boolean(originalDoc?._verified)\n const isEmailVerifiedChangingToTrue =\n Boolean(data.emailVerified) && !Boolean(originalDoc?.emailVerified)\n\n if (!isVerifiedChangingToTrue && !isEmailVerifiedChangingToTrue) {\n return data\n }\n\n return {\n ...data,\n _verified: true,\n emailVerified: true,\n }\n}\n"],"names":["onVerifiedChange","data","originalDoc","isVerifiedChangingToTrue","Boolean","_verified","isEmailVerifiedChangingToTrue","emailVerified"],"mappings":"AAEA,OAAO,MAAMA,mBAA+C,OAAO,EAAEC,IAAI,EAAEC,WAAW,EAAE;IACtF,MAAMC,2BAA2BC,QAAQH,KAAKI,SAAS,KAAK,CAACD,QAAQF,aAAaG;IAClF,MAAMC,gCACJF,QAAQH,KAAKM,aAAa,KAAK,CAACH,QAAQF,aAAaK;IAEvD,IAAI,CAACJ,4BAA4B,CAACG,+BAA+B;QAC/D,OAAOL;IACT;IAEA,OAAO;QACL,GAAGA,IAAI;QACPI,WAAW;QACXE,eAAe;IACjB;AACF,EAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { BETTER_AUTH_CONTEXT_KEY } from 'payload-auth/better-auth/adapter';
|
|
2
|
+
export const getSyncAccountHook = (options)=>{
|
|
3
|
+
const hook = async ({ doc, req, operation, context })=>{
|
|
4
|
+
if (context?.syncPasswordToUser) return doc;
|
|
5
|
+
if (operation !== 'create' && operation !== 'update') return doc;
|
|
6
|
+
const user = await req.payload.findByID({
|
|
7
|
+
collection: options.userSlug,
|
|
8
|
+
id: doc.id,
|
|
9
|
+
depth: 0,
|
|
10
|
+
req,
|
|
11
|
+
showHiddenFields: true
|
|
12
|
+
});
|
|
13
|
+
if (!user || !user.hash || !user.salt) return doc;
|
|
14
|
+
const passwordValue = `${user.salt}:${user.hash}`;
|
|
15
|
+
const userField = req.payload.betterAuth.options.account?.fields?.userId || 'userId';
|
|
16
|
+
if (operation === 'create' && !(BETTER_AUTH_CONTEXT_KEY in context)) {
|
|
17
|
+
try {
|
|
18
|
+
await req.payload.create({
|
|
19
|
+
collection: options.accountSlug,
|
|
20
|
+
data: {
|
|
21
|
+
[userField]: doc.id,
|
|
22
|
+
accountId: doc.id.toString(),
|
|
23
|
+
providerId: 'credential',
|
|
24
|
+
password: passwordValue,
|
|
25
|
+
context: {
|
|
26
|
+
syncAccountHook: true
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
req
|
|
30
|
+
});
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error('Failed to create account for user:', error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (operation === 'update') {
|
|
36
|
+
try {
|
|
37
|
+
const accounts = await req.payload.find({
|
|
38
|
+
collection: options.accountSlug,
|
|
39
|
+
where: {
|
|
40
|
+
and: [
|
|
41
|
+
{
|
|
42
|
+
[userField]: {
|
|
43
|
+
equals: doc.id
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
providerId: {
|
|
48
|
+
equals: 'credential'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
req,
|
|
54
|
+
depth: 0,
|
|
55
|
+
context: {
|
|
56
|
+
syncAccountHook: true
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const account = accounts.docs.at(0);
|
|
60
|
+
if (account) {
|
|
61
|
+
await req.payload.update({
|
|
62
|
+
collection: options.accountSlug,
|
|
63
|
+
id: account.id,
|
|
64
|
+
data: {
|
|
65
|
+
password: passwordValue
|
|
66
|
+
},
|
|
67
|
+
req,
|
|
68
|
+
context: {
|
|
69
|
+
syncAccountHook: true
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('Failed to sync hash/salt to account:', error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return doc;
|
|
78
|
+
};
|
|
79
|
+
return hook;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=sync-account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/plugin/collections/users/hooks/sync-account.ts"],"sourcesContent":["import type { CollectionAfterChangeHook } from 'payload'\nimport type { CollectionHookWithBetterAuth } from '../../../types'\nimport { BETTER_AUTH_CONTEXT_KEY } from 'payload-auth/better-auth/adapter'\n\ntype CollectionAfterChangeHookWithBetterAuth =\n CollectionHookWithBetterAuth<CollectionAfterChangeHook>\n\ntype SyncAccountOptions = {\n userSlug: string\n accountSlug: string\n}\n\nexport const getSyncAccountHook = (options: SyncAccountOptions): CollectionAfterChangeHook => {\n const hook: CollectionAfterChangeHookWithBetterAuth = async ({\n doc,\n req,\n operation,\n context,\n }) => {\n if (context?.syncPasswordToUser) return doc\n\n if (operation !== 'create' && operation !== 'update') return doc\n\n const user = await req.payload.findByID({\n collection: options.userSlug,\n id: doc.id,\n depth: 0,\n req,\n showHiddenFields: true,\n })\n\n if (!user || !user.hash || !user.salt) return doc\n\n const passwordValue = `${user.salt}:${user.hash}`\n const userField = req.payload.betterAuth.options.account?.fields?.userId || 'userId'\n\n if (operation === 'create' && !(BETTER_AUTH_CONTEXT_KEY in context)) {\n try {\n await req.payload.create({\n collection: options.accountSlug,\n data: {\n [userField]: doc.id,\n accountId: doc.id.toString(),\n providerId: 'credential',\n password: passwordValue,\n context: { syncAccountHook: true },\n },\n req,\n })\n } catch (error) {\n console.error('Failed to create account for user:', error)\n }\n }\n\n if (operation === 'update') {\n try {\n const accounts = await req.payload.find({\n collection: options.accountSlug,\n where: {\n and: [{ [userField]: { equals: doc.id } }, { providerId: { equals: 'credential' } }],\n },\n req,\n depth: 0,\n context: { syncAccountHook: true },\n })\n\n const account = accounts.docs.at(0)\n if (account) {\n await req.payload.update({\n collection: options.accountSlug,\n id: account.id,\n data: {\n password: passwordValue,\n },\n req,\n context: { syncAccountHook: true },\n })\n }\n } catch (error) {\n console.error('Failed to sync hash/salt to account:', error)\n }\n }\n\n return doc\n }\n\n return hook as CollectionAfterChangeHook\n}\n"],"names":["BETTER_AUTH_CONTEXT_KEY","getSyncAccountHook","options","hook","doc","req","operation","context","syncPasswordToUser","user","payload","findByID","collection","userSlug","id","depth","showHiddenFields","hash","salt","passwordValue","userField","betterAuth","account","fields","userId","create","accountSlug","data","accountId","toString","providerId","password","syncAccountHook","error","console","accounts","find","where","and","equals","docs","at","update"],"mappings":"AAEA,SAASA,uBAAuB,QAAQ,mCAAkC;AAU1E,OAAO,MAAMC,qBAAqB,CAACC;IACjC,MAAMC,OAAgD,OAAO,EAC3DC,GAAG,EACHC,GAAG,EACHC,SAAS,EACTC,OAAO,EACR;QACC,IAAIA,SAASC,oBAAoB,OAAOJ;QAExC,IAAIE,cAAc,YAAYA,cAAc,UAAU,OAAOF;QAE7D,MAAMK,OAAO,MAAMJ,IAAIK,OAAO,CAACC,QAAQ,CAAC;YACtCC,YAAYV,QAAQW,QAAQ;YAC5BC,IAAIV,IAAIU,EAAE;YACVC,OAAO;YACPV;YACAW,kBAAkB;QACpB;QAEA,IAAI,CAACP,QAAQ,CAACA,KAAKQ,IAAI,IAAI,CAACR,KAAKS,IAAI,EAAE,OAAOd;QAE9C,MAAMe,gBAAgB,GAAGV,KAAKS,IAAI,CAAC,CAAC,EAAET,KAAKQ,IAAI,EAAE;QACjD,MAAMG,YAAYf,IAAIK,OAAO,CAACW,UAAU,CAACnB,OAAO,CAACoB,OAAO,EAAEC,QAAQC,UAAU;QAE5E,IAAIlB,cAAc,YAAY,CAAEN,CAAAA,2BAA2BO,OAAM,GAAI;YACnE,IAAI;gBACF,MAAMF,IAAIK,OAAO,CAACe,MAAM,CAAC;oBACvBb,YAAYV,QAAQwB,WAAW;oBAC/BC,MAAM;wBACJ,CAACP,UAAU,EAAEhB,IAAIU,EAAE;wBACnBc,WAAWxB,IAAIU,EAAE,CAACe,QAAQ;wBAC1BC,YAAY;wBACZC,UAAUZ;wBACVZ,SAAS;4BAAEyB,iBAAiB;wBAAK;oBACnC;oBACA3B;gBACF;YACF,EAAE,OAAO4B,OAAO;gBACdC,QAAQD,KAAK,CAAC,sCAAsCA;YACtD;QACF;QAEA,IAAI3B,cAAc,UAAU;YAC1B,IAAI;gBACF,MAAM6B,WAAW,MAAM9B,IAAIK,OAAO,CAAC0B,IAAI,CAAC;oBACtCxB,YAAYV,QAAQwB,WAAW;oBAC/BW,OAAO;wBACLC,KAAK;4BAAC;gCAAE,CAAClB,UAAU,EAAE;oCAAEmB,QAAQnC,IAAIU,EAAE;gCAAC;4BAAE;4BAAG;gCAAEgB,YAAY;oCAAES,QAAQ;gCAAa;4BAAE;yBAAE;oBACtF;oBACAlC;oBACAU,OAAO;oBACPR,SAAS;wBAAEyB,iBAAiB;oBAAK;gBACnC;gBAEA,MAAMV,UAAUa,SAASK,IAAI,CAACC,EAAE,CAAC;gBACjC,IAAInB,SAAS;oBACX,MAAMjB,IAAIK,OAAO,CAACgC,MAAM,CAAC;wBACvB9B,YAAYV,QAAQwB,WAAW;wBAC/BZ,IAAIQ,QAAQR,EAAE;wBACda,MAAM;4BACJI,UAAUZ;wBACZ;wBACAd;wBACAE,SAAS;4BAAEyB,iBAAiB;wBAAK;oBACnC;gBACF;YACF,EAAE,OAAOC,OAAO;gBACdC,QAAQD,KAAK,CAAC,wCAAwCA;YACxD;QACF;QAEA,OAAO7B;IACT;IAEA,OAAOD;AACT,EAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a verification URL for email verification
|
|
3
|
+
*
|
|
4
|
+
* This utility function creates a JWT token containing the user's email and
|
|
5
|
+
* expiration information, signs it with the provided secret, and constructs
|
|
6
|
+
* a verification URL with the token as a query parameter.
|
|
7
|
+
*
|
|
8
|
+
* @param userEmail - The email address of the user to verify
|
|
9
|
+
* @param secret - The secret used to sign the JWT
|
|
10
|
+
* @param expiresIn - Duration in seconds for token expiration (default: 3600)
|
|
11
|
+
* @param verifyRouteUrl - The base URL for the verification endpoint
|
|
12
|
+
* @param callbackURL - Optional callback URL after verification (default: "/")
|
|
13
|
+
* @returns The complete verification URL with token
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const url = await generateVerifyEmailUrl({
|
|
17
|
+
* userEmail: 'user@example.com',
|
|
18
|
+
* secret: 'your-secret-key',
|
|
19
|
+
* verifyRouteUrl: 'https://your-app.com/api/auth/verify-email',
|
|
20
|
+
* callbackURL: '/profile'
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export declare const generateVerifyEmailUrl: ({ userEmail, secret, expiresIn, verifyRouteUrl, callbackURL, }: {
|
|
24
|
+
userEmail: string;
|
|
25
|
+
secret: string;
|
|
26
|
+
expiresIn?: number;
|
|
27
|
+
verifyRouteUrl: string;
|
|
28
|
+
callbackURL?: string;
|
|
29
|
+
}) => Promise<string>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SignJWT } from 'jose';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a verification URL for email verification
|
|
4
|
+
*
|
|
5
|
+
* This utility function creates a JWT token containing the user's email and
|
|
6
|
+
* expiration information, signs it with the provided secret, and constructs
|
|
7
|
+
* a verification URL with the token as a query parameter.
|
|
8
|
+
*
|
|
9
|
+
* @param userEmail - The email address of the user to verify
|
|
10
|
+
* @param secret - The secret used to sign the JWT
|
|
11
|
+
* @param expiresIn - Duration in seconds for token expiration (default: 3600)
|
|
12
|
+
* @param verifyRouteUrl - The base URL for the verification endpoint
|
|
13
|
+
* @param callbackURL - Optional callback URL after verification (default: "/")
|
|
14
|
+
* @returns The complete verification URL with token
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const url = await generateVerifyEmailUrl({
|
|
18
|
+
* userEmail: 'user@example.com',
|
|
19
|
+
* secret: 'your-secret-key',
|
|
20
|
+
* verifyRouteUrl: 'https://your-app.com/api/auth/verify-email',
|
|
21
|
+
* callbackURL: '/profile'
|
|
22
|
+
* });
|
|
23
|
+
*/ export const generateVerifyEmailUrl = async ({ userEmail, secret, expiresIn = 3600, verifyRouteUrl, callbackURL = '/' })=>{
|
|
24
|
+
if (!userEmail) {
|
|
25
|
+
throw new Error('userEmail is required to generate a verification URL');
|
|
26
|
+
}
|
|
27
|
+
if (!secret) {
|
|
28
|
+
throw new Error('secret is required to sign the JWT token');
|
|
29
|
+
}
|
|
30
|
+
if (!verifyRouteUrl) {
|
|
31
|
+
throw new Error('verifyRouteUrl is required to generate a verification URL');
|
|
32
|
+
}
|
|
33
|
+
// Create and sign the JWT token
|
|
34
|
+
const jwt = await new SignJWT({
|
|
35
|
+
email: userEmail,
|
|
36
|
+
iat: Math.floor(Date.now() / 1000),
|
|
37
|
+
exp: Math.floor(Date.now() / 1000) + expiresIn
|
|
38
|
+
}).setProtectedHeader({
|
|
39
|
+
alg: 'HS256'
|
|
40
|
+
}).sign(new TextEncoder().encode(secret));
|
|
41
|
+
// Build the verification URL
|
|
42
|
+
const verifyUrl = `${verifyRouteUrl}?token=${jwt}${callbackURL ? `&callbackURL=${encodeURIComponent(callbackURL)}` : ''}`;
|
|
43
|
+
return verifyUrl;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=generate-verify-email-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/plugin/helpers/generate-verify-email-url.ts"],"sourcesContent":["import { SignJWT } from 'jose'\n\n/**\n * Generates a verification URL for email verification\n *\n * This utility function creates a JWT token containing the user's email and\n * expiration information, signs it with the provided secret, and constructs\n * a verification URL with the token as a query parameter.\n *\n * @param userEmail - The email address of the user to verify\n * @param secret - The secret used to sign the JWT\n * @param expiresIn - Duration in seconds for token expiration (default: 3600)\n * @param verifyRouteUrl - The base URL for the verification endpoint\n * @param callbackURL - Optional callback URL after verification (default: \"/\")\n * @returns The complete verification URL with token\n *\n * @example\n * const url = await generateVerifyEmailUrl({\n * userEmail: 'user@example.com',\n * secret: 'your-secret-key',\n * verifyRouteUrl: 'https://your-app.com/api/auth/verify-email',\n * callbackURL: '/profile'\n * });\n */\nexport const generateVerifyEmailUrl = async ({\n userEmail,\n secret,\n expiresIn = 3600,\n verifyRouteUrl,\n callbackURL = '/',\n}: {\n userEmail: string\n secret: string\n expiresIn?: number\n verifyRouteUrl: string\n callbackURL?: string\n}): Promise<string> => {\n if (!userEmail) {\n throw new Error('userEmail is required to generate a verification URL')\n }\n\n if (!secret) {\n throw new Error('secret is required to sign the JWT token')\n }\n\n if (!verifyRouteUrl) {\n throw new Error('verifyRouteUrl is required to generate a verification URL')\n }\n\n // Create and sign the JWT token\n const jwt = await new SignJWT({\n email: userEmail,\n iat: Math.floor(Date.now() / 1000),\n exp: Math.floor(Date.now() / 1000) + expiresIn,\n })\n .setProtectedHeader({ alg: 'HS256' })\n .sign(new TextEncoder().encode(secret))\n\n // Build the verification URL\n const verifyUrl = `${verifyRouteUrl}?token=${jwt}${callbackURL ? `&callbackURL=${encodeURIComponent(callbackURL)}` : ''}`\n\n return verifyUrl\n}\n"],"names":["SignJWT","generateVerifyEmailUrl","userEmail","secret","expiresIn","verifyRouteUrl","callbackURL","Error","jwt","email","iat","Math","floor","Date","now","exp","setProtectedHeader","alg","sign","TextEncoder","encode","verifyUrl","encodeURIComponent"],"mappings":"AAAA,SAASA,OAAO,QAAQ,OAAM;AAE9B;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,MAAMC,yBAAyB,OAAO,EAC3CC,SAAS,EACTC,MAAM,EACNC,YAAY,IAAI,EAChBC,cAAc,EACdC,cAAc,GAAG,EAOlB;IACC,IAAI,CAACJ,WAAW;QACd,MAAM,IAAIK,MAAM;IAClB;IAEA,IAAI,CAACJ,QAAQ;QACX,MAAM,IAAII,MAAM;IAClB;IAEA,IAAI,CAACF,gBAAgB;QACnB,MAAM,IAAIE,MAAM;IAClB;IAEA,gCAAgC;IAChC,MAAMC,MAAM,MAAM,IAAIR,QAAQ;QAC5BS,OAAOP;QACPQ,KAAKC,KAAKC,KAAK,CAACC,KAAKC,GAAG,KAAK;QAC7BC,KAAKJ,KAAKC,KAAK,CAACC,KAAKC,GAAG,KAAK,QAAQV;IACvC,GACGY,kBAAkB,CAAC;QAAEC,KAAK;IAAQ,GAClCC,IAAI,CAAC,IAAIC,cAAcC,MAAM,CAACjB;IAEjC,6BAA6B;IAC7B,MAAMkB,YAAY,GAAGhB,eAAe,OAAO,EAAEG,MAAMF,cAAc,CAAC,aAAa,EAAEgB,mBAAmBhB,cAAc,GAAG,IAAI;IAEzH,OAAOe;AACT,EAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function getIp(headers, options) {
|
|
2
|
+
if (options.advanced?.ipAddress?.disableIpTracking) {
|
|
3
|
+
return null;
|
|
4
|
+
}
|
|
5
|
+
const testIP = '127.0.0.1';
|
|
6
|
+
if ((process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development') ?? false) {
|
|
7
|
+
return testIP;
|
|
8
|
+
}
|
|
9
|
+
const ipHeaders = options.advanced?.ipAddress?.ipAddressHeaders;
|
|
10
|
+
const keys = ipHeaders || [
|
|
11
|
+
'x-client-ip',
|
|
12
|
+
'x-forwarded-for',
|
|
13
|
+
'cf-connecting-ip',
|
|
14
|
+
'fastly-client-ip',
|
|
15
|
+
'x-real-ip',
|
|
16
|
+
'x-cluster-client-ip',
|
|
17
|
+
'x-forwarded',
|
|
18
|
+
'forwarded-for',
|
|
19
|
+
'forwarded'
|
|
20
|
+
];
|
|
21
|
+
for (const key of keys){
|
|
22
|
+
const value = headers.get(key);
|
|
23
|
+
if (typeof value === 'string') {
|
|
24
|
+
const ip = value.split(',')[0].trim();
|
|
25
|
+
if (ip) return ip;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=get-ip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/plugin/helpers/get-ip.ts"],"sourcesContent":["import type { BetterAuthOptions } from 'better-auth'\n\nexport function getIp(headers: Headers, options: BetterAuthOptions): string | null {\n if (options.advanced?.ipAddress?.disableIpTracking) {\n return null\n }\n const testIP = '127.0.0.1'\n if ((process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development') ?? false) {\n return testIP\n }\n const ipHeaders = options.advanced?.ipAddress?.ipAddressHeaders\n const keys = ipHeaders || [\n 'x-client-ip',\n 'x-forwarded-for',\n 'cf-connecting-ip',\n 'fastly-client-ip',\n 'x-real-ip',\n 'x-cluster-client-ip',\n 'x-forwarded',\n 'forwarded-for',\n 'forwarded',\n ]\n for (const key of keys) {\n const value = headers.get(key)\n if (typeof value === 'string') {\n const ip = value.split(',')[0].trim()\n if (ip) return ip\n }\n }\n return null\n}\n"],"names":["getIp","headers","options","advanced","ipAddress","disableIpTracking","testIP","process","env","NODE_ENV","ipHeaders","ipAddressHeaders","keys","key","value","get","ip","split","trim"],"mappings":"AAEA,OAAO,SAASA,MAAMC,OAAgB,EAAEC,OAA0B;IAChE,IAAIA,QAAQC,QAAQ,EAAEC,WAAWC,mBAAmB;QAClD,OAAO;IACT;IACA,MAAMC,SAAS;IACf,IAAI,AAACC,CAAAA,QAAQC,GAAG,CAACC,QAAQ,KAAK,UAAUF,QAAQC,GAAG,CAACC,QAAQ,KAAK,aAAY,KAAM,OAAO;QACxF,OAAOH;IACT;IACA,MAAMI,YAAYR,QAAQC,QAAQ,EAAEC,WAAWO;IAC/C,MAAMC,OAAOF,aAAa;QACxB;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD;IACD,KAAK,MAAMG,OAAOD,KAAM;QACtB,MAAME,QAAQb,QAAQc,GAAG,CAACF;QAC1B,IAAI,OAAOC,UAAU,UAAU;YAC7B,MAAME,KAAKF,MAAMG,KAAK,CAAC,IAAI,CAAC,EAAE,CAACC,IAAI;YACnC,IAAIF,IAAI,OAAOA;QACjB;IACF;IACA,OAAO;AACT"}
|