better-auth-nuxt 0.0.2 → 0.0.3
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/dist/module.d.mts +4 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +196 -7
- package/dist/runtime/middleware/auth.global.d.ts +27 -0
- package/dist/runtime/middleware/auth.global.js +35 -0
- package/dist/runtime/plugin.d.ts +1 -1
- package/dist/runtime/server/handler.js +1 -1
- package/package.json +1 -1
- package/dist/runtime/composables/useAuth.d.ts +0 -3492
- package/dist/runtime/composables/useAuth.js +0 -81
package/dist/module.d.mts
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { defineNuxtModule, createResolver, logger,
|
|
2
|
+
import { defineNuxtModule, createResolver, logger, addServerHandler, addTypeTemplate, addServerImports, addImports, addRouteMiddleware, addPlugin, addTemplate } from '@nuxt/kit';
|
|
3
3
|
import { defu } from 'defu';
|
|
4
4
|
import { resolve } from 'pathe';
|
|
5
5
|
import { hash } from 'ohash';
|
|
@@ -33,6 +33,119 @@ async function serverAuth({ options }) {
|
|
|
33
33
|
].join("\n");
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
async function useUserSession({ options }) {
|
|
37
|
+
return [
|
|
38
|
+
"import { createAuthClient } from 'better-auth/vue'",
|
|
39
|
+
...options.configs.map((config) => {
|
|
40
|
+
return `import ${config.key} from "${config.path}"`;
|
|
41
|
+
}),
|
|
42
|
+
"import { defu } from 'defu'",
|
|
43
|
+
"import { computed, ref } from 'vue'",
|
|
44
|
+
"import { navigateTo, useRequestHeaders, useRequestURL, useRuntimeConfig, useState } from '#app'",
|
|
45
|
+
"",
|
|
46
|
+
"let _authInstance",
|
|
47
|
+
"",
|
|
48
|
+
"export function createAuthInstance() {",
|
|
49
|
+
" const url = useRequestURL()",
|
|
50
|
+
" const headers = import.meta.server ? useRequestHeaders() : undefined",
|
|
51
|
+
" const config = useRuntimeConfig()",
|
|
52
|
+
"",
|
|
53
|
+
" const authClient = createAuthClient({",
|
|
54
|
+
" baseURL: url.origin,",
|
|
55
|
+
" fetchOptions: {",
|
|
56
|
+
...options.configs.map((config) => {
|
|
57
|
+
return ` ...${config.key}?.fetchOptions || {},`;
|
|
58
|
+
}),
|
|
59
|
+
" headers,",
|
|
60
|
+
" },",
|
|
61
|
+
...options.configs.map((config) => {
|
|
62
|
+
return ` ${config.key},`;
|
|
63
|
+
}),
|
|
64
|
+
" plugins: [",
|
|
65
|
+
...options.configs.map((config) => {
|
|
66
|
+
return ` ...${config.key}?.plugins || [],`;
|
|
67
|
+
}),
|
|
68
|
+
" ],",
|
|
69
|
+
" })",
|
|
70
|
+
"",
|
|
71
|
+
" const options = defu(config.public.betterAuth.redirectOptions || {}, {",
|
|
72
|
+
" redirectUserTo: '/profile',",
|
|
73
|
+
" redirectGuestTo: '/signin',",
|
|
74
|
+
" redirectUnauthorizedTo: '/401',",
|
|
75
|
+
" })",
|
|
76
|
+
"",
|
|
77
|
+
" const session = useState('auth:session', () => null)",
|
|
78
|
+
" const user = useState('auth:user', () => null)",
|
|
79
|
+
" const sessionFetching = import.meta.server ? ref(false) : useState('auth:sessionFetching', () => false)",
|
|
80
|
+
"",
|
|
81
|
+
" const fetchSession = async () => {",
|
|
82
|
+
" if (sessionFetching.value) {",
|
|
83
|
+
" return",
|
|
84
|
+
" }",
|
|
85
|
+
" sessionFetching.value = true",
|
|
86
|
+
" const { data } = await authClient.getSession({",
|
|
87
|
+
" fetchOptions: {",
|
|
88
|
+
" headers,",
|
|
89
|
+
" },",
|
|
90
|
+
" })",
|
|
91
|
+
" session.value = data?.session || null",
|
|
92
|
+
" user.value = data?.user || null",
|
|
93
|
+
" sessionFetching.value = false",
|
|
94
|
+
" return data",
|
|
95
|
+
" }",
|
|
96
|
+
"",
|
|
97
|
+
" return {",
|
|
98
|
+
" session,",
|
|
99
|
+
" user,",
|
|
100
|
+
" loggedIn: computed(() => !!session.value),",
|
|
101
|
+
" signIn: authClient.signIn,",
|
|
102
|
+
" signUp: authClient.signUp,",
|
|
103
|
+
" options,",
|
|
104
|
+
" fetchSession,",
|
|
105
|
+
" client: authClient,",
|
|
106
|
+
" signOut: async (options = {}) => {",
|
|
107
|
+
" try {",
|
|
108
|
+
" await authClient.signOut()",
|
|
109
|
+
" if (options.redirectTo)",
|
|
110
|
+
" await navigateTo(options.redirectTo)",
|
|
111
|
+
" }",
|
|
112
|
+
" catch (error) {",
|
|
113
|
+
" console.error('Sign out failed:', error)",
|
|
114
|
+
" throw error",
|
|
115
|
+
" }",
|
|
116
|
+
" },",
|
|
117
|
+
" }",
|
|
118
|
+
"}",
|
|
119
|
+
"",
|
|
120
|
+
"// Setup session listener for client-side updates",
|
|
121
|
+
"function setupSessionListener(client) {",
|
|
122
|
+
" if (!import.meta.client)",
|
|
123
|
+
" return",
|
|
124
|
+
"",
|
|
125
|
+
" client.$store.listen('$sessionSignal', async (signal) => {",
|
|
126
|
+
" if (!signal)",
|
|
127
|
+
" return",
|
|
128
|
+
" await client.useSession($fetch)",
|
|
129
|
+
" })",
|
|
130
|
+
"}",
|
|
131
|
+
"",
|
|
132
|
+
"export function useUserSession() {",
|
|
133
|
+
" if (_authInstance && import.meta.client)",
|
|
134
|
+
" return _authInstance",
|
|
135
|
+
"",
|
|
136
|
+
" const auth = createAuthInstance()",
|
|
137
|
+
"",
|
|
138
|
+
" if (import.meta.client) {",
|
|
139
|
+
" setupSessionListener(auth.client)",
|
|
140
|
+
" _authInstance = auth",
|
|
141
|
+
" }",
|
|
142
|
+
"",
|
|
143
|
+
" return auth",
|
|
144
|
+
"}",
|
|
145
|
+
""
|
|
146
|
+
].join("\n");
|
|
147
|
+
}
|
|
148
|
+
|
|
36
149
|
const module = defineNuxtModule({
|
|
37
150
|
meta: {
|
|
38
151
|
name: "better-auth",
|
|
@@ -50,6 +163,12 @@ const module = defineNuxtModule({
|
|
|
50
163
|
},
|
|
51
164
|
async setup(options, nuxt) {
|
|
52
165
|
const resolver = createResolver(import.meta.url);
|
|
166
|
+
nuxt.options.vite.optimizeDeps ??= {};
|
|
167
|
+
nuxt.options.vite.optimizeDeps.include ??= [];
|
|
168
|
+
nuxt.options.vite.optimizeDeps.include.push(...[
|
|
169
|
+
"better-auth/client",
|
|
170
|
+
"better-auth/vue"
|
|
171
|
+
]);
|
|
53
172
|
if (!options.endpoint) {
|
|
54
173
|
logger.withTag("better-auth").error("Missing endpoint option");
|
|
55
174
|
}
|
|
@@ -59,7 +178,6 @@ const module = defineNuxtModule({
|
|
|
59
178
|
redirectOptions: options.redirectOptions
|
|
60
179
|
});
|
|
61
180
|
nuxt.options.alias["#better-auth"] = resolve("./runtime");
|
|
62
|
-
addImportsDir(resolve("./runtime/composables"));
|
|
63
181
|
addServerHandler({
|
|
64
182
|
route: options.endpoint,
|
|
65
183
|
handler: resolver.resolve("./runtime/server/handler")
|
|
@@ -113,13 +231,13 @@ const module = defineNuxtModule({
|
|
|
113
231
|
}
|
|
114
232
|
}
|
|
115
233
|
}
|
|
116
|
-
registerTemplate({
|
|
117
|
-
filename: "better-auth
|
|
234
|
+
const server = registerTemplate({
|
|
235
|
+
filename: "better-auth/server.mjs",
|
|
118
236
|
getContents: serverAuth,
|
|
119
237
|
options: { configs: serverConfigs }
|
|
120
238
|
});
|
|
121
239
|
addTypeTemplate({
|
|
122
|
-
filename: "better-auth
|
|
240
|
+
filename: "better-auth/server.d.ts",
|
|
123
241
|
getContents: () => {
|
|
124
242
|
return [
|
|
125
243
|
'import { betterAuth } from "better-auth"',
|
|
@@ -138,16 +256,87 @@ const module = defineNuxtModule({
|
|
|
138
256
|
].join("\n");
|
|
139
257
|
}
|
|
140
258
|
});
|
|
259
|
+
const clientConfigs = [];
|
|
260
|
+
for (const layer of nuxt.options._layers) {
|
|
261
|
+
const paths = await glob([
|
|
262
|
+
"**/*.better-auth-client.ts",
|
|
263
|
+
...options.clientConfigs?.map((pattern) => {
|
|
264
|
+
return `**/${pattern}.ts`;
|
|
265
|
+
}) || []
|
|
266
|
+
], { onlyFiles: true, ignore: nuxt.options.ignore, dot: true, cwd: layer.config.rootDir, absolute: true });
|
|
267
|
+
const pathsJS = await glob([
|
|
268
|
+
"**/*.better-auth.js",
|
|
269
|
+
...options.serverConfigs?.map((pattern) => {
|
|
270
|
+
return `**/${pattern}.js`;
|
|
271
|
+
}) || []
|
|
272
|
+
], { cwd: layer.config.serverDir });
|
|
273
|
+
if (paths.length === 0 && pathsJS.length === 0) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
for (const path of [...paths, ...pathsJS]) {
|
|
277
|
+
console.log("path", path);
|
|
278
|
+
if (fs.existsSync(path)) {
|
|
279
|
+
clientConfigs.push({
|
|
280
|
+
key: pascalCase(hash(path)),
|
|
281
|
+
path
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const client = registerTemplate({
|
|
287
|
+
filename: "better-auth/client.mjs",
|
|
288
|
+
getContents: useUserSession,
|
|
289
|
+
options: { configs: clientConfigs }
|
|
290
|
+
});
|
|
291
|
+
addTypeTemplate({
|
|
292
|
+
filename: "better-auth/client.d.ts",
|
|
293
|
+
getContents: () => {
|
|
294
|
+
return [
|
|
295
|
+
'import { createAuthInstance } from "./client.mjs"',
|
|
296
|
+
'import type { ClientOptions, InferSessionFromClient, InferUserFromClient } from "better-auth"',
|
|
297
|
+
'import type { RouteLocationRaw } from "vue-router"',
|
|
298
|
+
'import { Ref, ComputedRef } from "vue"',
|
|
299
|
+
...clientConfigs.map((config) => {
|
|
300
|
+
return `import ${config.key} from "${config.path}"`;
|
|
301
|
+
}),
|
|
302
|
+
"export interface RuntimeAuthConfig {",
|
|
303
|
+
" redirectUserTo: RouteLocationRaw | string",
|
|
304
|
+
" redirectGuestTo: RouteLocationRaw | string",
|
|
305
|
+
" redirectUnauthorizedTo: RouteLocationRaw | string",
|
|
306
|
+
"}",
|
|
307
|
+
"export interface AuthSignOutOptions {",
|
|
308
|
+
" redirectTo?: RouteLocationRaw",
|
|
309
|
+
"}",
|
|
310
|
+
"export type AuthClient = ReturnType<typeof createAuthInstance>",
|
|
311
|
+
"export declare const useUserSession: () => AuthClient"
|
|
312
|
+
].join("\n");
|
|
313
|
+
}
|
|
314
|
+
});
|
|
141
315
|
addServerImports([
|
|
142
316
|
{
|
|
143
|
-
from:
|
|
317
|
+
from: server.dst,
|
|
144
318
|
name: "useAuth"
|
|
145
319
|
},
|
|
146
320
|
{
|
|
147
|
-
from:
|
|
321
|
+
from: server.dst,
|
|
148
322
|
name: "auth"
|
|
149
323
|
}
|
|
150
324
|
]);
|
|
325
|
+
addImports([
|
|
326
|
+
{
|
|
327
|
+
from: client.dst,
|
|
328
|
+
name: "useUserSession"
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
from: client.dst,
|
|
332
|
+
name: "createAuthInstance"
|
|
333
|
+
}
|
|
334
|
+
]);
|
|
335
|
+
addRouteMiddleware({
|
|
336
|
+
name: "better-auth",
|
|
337
|
+
path: resolver.resolve("./runtime/middleware/auth.global"),
|
|
338
|
+
global: true
|
|
339
|
+
});
|
|
151
340
|
addPlugin(resolver.resolve("./runtime/plugin"));
|
|
152
341
|
}
|
|
153
342
|
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
type MiddlewareOptions = false | {
|
|
2
|
+
/**
|
|
3
|
+
* Only apply auth middleware to guest or user
|
|
4
|
+
*/
|
|
5
|
+
only?: 'guest' | 'user' | 'member' | 'admin';
|
|
6
|
+
/**
|
|
7
|
+
* Redirect authenticated user to this route
|
|
8
|
+
*/
|
|
9
|
+
redirectUserTo?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Redirect guest to this route
|
|
12
|
+
*/
|
|
13
|
+
redirectGuestTo?: string;
|
|
14
|
+
redirectUnauthorizedTo?: string;
|
|
15
|
+
};
|
|
16
|
+
declare module '#app' {
|
|
17
|
+
interface PageMeta {
|
|
18
|
+
auth?: MiddlewareOptions;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
declare module 'vue-router' {
|
|
22
|
+
interface RouteMeta {
|
|
23
|
+
auth?: MiddlewareOptions;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
declare const _default: import("#app").RouteMiddleware;
|
|
27
|
+
export default _default;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defu } from "defu";
|
|
2
|
+
import { defineNuxtRouteMiddleware, navigateTo } from "#app";
|
|
3
|
+
import { useUserSession } from "#imports";
|
|
4
|
+
export default defineNuxtRouteMiddleware(async (to) => {
|
|
5
|
+
if (to.meta?.auth === false) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const { loggedIn, options, fetchSession, session } = useUserSession();
|
|
9
|
+
const { only, redirectUserTo, redirectGuestTo, redirectUnauthorizedTo } = defu(to.meta?.auth, options);
|
|
10
|
+
if (import.meta.client) {
|
|
11
|
+
await fetchSession();
|
|
12
|
+
}
|
|
13
|
+
if (loggedIn.value && to.path.startsWith("/auth/")) {
|
|
14
|
+
if (to.path === redirectUserTo) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
return navigateTo(redirectUserTo);
|
|
18
|
+
}
|
|
19
|
+
if (only === "guest" && loggedIn.value) {
|
|
20
|
+
if (to.path === redirectUserTo) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
return navigateTo(redirectUserTo);
|
|
24
|
+
}
|
|
25
|
+
if (only && only !== "guest" && !loggedIn.value) {
|
|
26
|
+
if (to.path === redirectGuestTo)
|
|
27
|
+
return;
|
|
28
|
+
return navigateTo(redirectGuestTo);
|
|
29
|
+
}
|
|
30
|
+
if (only && only !== "guest" && session.value) {
|
|
31
|
+
if (to.path === redirectUnauthorizedTo)
|
|
32
|
+
return;
|
|
33
|
+
return navigateTo(redirectUnauthorizedTo ?? "/401");
|
|
34
|
+
}
|
|
35
|
+
});
|
package/dist/runtime/plugin.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("
|
|
1
|
+
declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
|
|
2
2
|
export default _default;
|