@onmax/nuxt-better-auth 0.0.2-alpha.14 → 0.0.2-alpha.15
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.json +1 -1
- package/dist/module.mjs +118 -14
- package/dist/runtime/app/composables/useUserSession.js +1 -1
- package/dist/runtime/config.d.ts +5 -4
- package/dist/runtime/config.js +7 -2
- package/package.json +5 -3
- package/skills/nuxt-better-auth/references/client-only.md +4 -6
- package/skills/nuxt-better-auth/references/database.md +4 -4
- package/skills/nuxt-better-auth/references/installation.md +22 -5
- package/skills/nuxt-better-auth/references/plugins.md +6 -5
- package/skills/nuxt-better-auth/references/types.md +4 -2
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { existsSync, writeFileSync, readFileSync } from 'node:fs';
|
|
2
3
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { defineNuxtModule, createResolver, hasNuxtModule, addTemplate, addTypeTemplate, updateTemplates, addServerImportsDir, addServerImports, addServerScanDir, addServerHandler, addImportsDir, addPlugin, addComponentsDir, extendPages } from '@nuxt/kit';
|
|
4
|
+
import { defineNuxtModule, createResolver, hasNuxtModule, addTemplate, addTypeTemplate, updateTemplates, addServerImportsDir, addServerImports, addServerScanDir, addServerHandler, addImportsDir, addPlugin, addComponentsDir, installModule, extendPages } from '@nuxt/kit';
|
|
4
5
|
import { consola as consola$1 } from 'consola';
|
|
5
6
|
import { defu } from 'defu';
|
|
6
|
-
import { join } from 'pathe';
|
|
7
|
+
import { join, dirname } from 'pathe';
|
|
7
8
|
import { toRouteMatcher, createRouter } from 'radix3';
|
|
9
|
+
import { isCI, isTest } from 'std-env';
|
|
8
10
|
import { generateDrizzleSchema as generateDrizzleSchema$1 } from '@better-auth/cli/api';
|
|
9
11
|
export { defineClientAuth, defineServerAuth } from '../dist/runtime/config.js';
|
|
10
12
|
|
|
13
|
+
const version = "0.0.2-alpha.15";
|
|
14
|
+
|
|
11
15
|
function setupDevTools(nuxt) {
|
|
12
16
|
nuxt.hook("devtools:customTabs", (tabs) => {
|
|
13
17
|
tabs.push({
|
|
@@ -63,11 +67,11 @@ async function loadUserAuthConfig(configPath, throwOnError = false) {
|
|
|
63
67
|
globalThis.defineServerAuth._count++;
|
|
64
68
|
try {
|
|
65
69
|
const mod = await jiti.import(configPath);
|
|
66
|
-
const configFn =
|
|
70
|
+
const configFn = mod.default;
|
|
67
71
|
if (typeof configFn === "function") {
|
|
68
72
|
return configFn({ runtimeConfig: {}, db: null });
|
|
69
73
|
}
|
|
70
|
-
consola$1.warn("[@onmax/nuxt-better-auth] auth.config.ts does not export
|
|
74
|
+
consola$1.warn("[@onmax/nuxt-better-auth] auth.config.ts does not export default. Expected: export default defineServerAuth(...)");
|
|
71
75
|
if (throwOnError) {
|
|
72
76
|
throw new Error("auth.config.ts must export default defineServerAuth(...)");
|
|
73
77
|
}
|
|
@@ -101,8 +105,72 @@ function getHubCasing(hub) {
|
|
|
101
105
|
return hub.db.casing;
|
|
102
106
|
}
|
|
103
107
|
const consola = consola$1.withTag("nuxt-better-auth");
|
|
108
|
+
const generateSecret = () => randomBytes(32).toString("hex");
|
|
109
|
+
function readEnvFile(rootDir) {
|
|
110
|
+
const envPath = join(rootDir, ".env");
|
|
111
|
+
return existsSync(envPath) ? readFileSync(envPath, "utf-8") : "";
|
|
112
|
+
}
|
|
113
|
+
function hasEnvSecret(rootDir) {
|
|
114
|
+
const match = readEnvFile(rootDir).match(/^BETTER_AUTH_SECRET=(.+)$/m);
|
|
115
|
+
return !!match && !!match[1] && match[1].trim().length > 0;
|
|
116
|
+
}
|
|
117
|
+
function appendSecretToEnv(rootDir, secret) {
|
|
118
|
+
const envPath = join(rootDir, ".env");
|
|
119
|
+
let content = readEnvFile(rootDir);
|
|
120
|
+
if (content.length > 0 && !content.endsWith("\n"))
|
|
121
|
+
content += "\n";
|
|
122
|
+
content += `BETTER_AUTH_SECRET=${secret}
|
|
123
|
+
`;
|
|
124
|
+
writeFileSync(envPath, content, "utf-8");
|
|
125
|
+
}
|
|
126
|
+
async function promptForSecret(rootDir) {
|
|
127
|
+
if (process.env.BETTER_AUTH_SECRET || hasEnvSecret(rootDir))
|
|
128
|
+
return void 0;
|
|
129
|
+
if (isCI || isTest) {
|
|
130
|
+
const secret2 = generateSecret();
|
|
131
|
+
appendSecretToEnv(rootDir, secret2);
|
|
132
|
+
consola.info("Generated BETTER_AUTH_SECRET and added to .env (CI mode)");
|
|
133
|
+
return secret2;
|
|
134
|
+
}
|
|
135
|
+
consola.box("BETTER_AUTH_SECRET is required for authentication.\nThis will be appended to your .env file.");
|
|
136
|
+
const choice = await consola.prompt("How do you want to set it?", {
|
|
137
|
+
type: "select",
|
|
138
|
+
options: [
|
|
139
|
+
{ label: "Generate for me", value: "generate", hint: "uses crypto.randomBytes(32)" },
|
|
140
|
+
{ label: "Enter manually", value: "paste" },
|
|
141
|
+
{ label: "Skip", value: "skip", hint: "will fail in production" }
|
|
142
|
+
],
|
|
143
|
+
cancel: "null"
|
|
144
|
+
});
|
|
145
|
+
if (typeof choice === "symbol" || choice === "skip") {
|
|
146
|
+
consola.warn("Skipping BETTER_AUTH_SECRET. Auth will fail without it in production.");
|
|
147
|
+
return void 0;
|
|
148
|
+
}
|
|
149
|
+
let secret;
|
|
150
|
+
if (choice === "generate") {
|
|
151
|
+
secret = generateSecret();
|
|
152
|
+
} else {
|
|
153
|
+
const input = await consola.prompt("Paste your secret (min 32 chars):", { type: "text", cancel: "null" });
|
|
154
|
+
if (typeof input === "symbol" || !input || input.length < 32) {
|
|
155
|
+
consola.warn("Invalid secret. Skipping.");
|
|
156
|
+
return void 0;
|
|
157
|
+
}
|
|
158
|
+
secret = input;
|
|
159
|
+
}
|
|
160
|
+
const preview = `${secret.slice(0, 8)}...${secret.slice(-4)}`;
|
|
161
|
+
const confirm = await consola.prompt(`Add to .env:
|
|
162
|
+
BETTER_AUTH_SECRET=${preview}
|
|
163
|
+
Proceed?`, { type: "confirm", initial: true, cancel: "null" });
|
|
164
|
+
if (typeof confirm === "symbol" || !confirm) {
|
|
165
|
+
consola.info("Cancelled. Secret not written.");
|
|
166
|
+
return void 0;
|
|
167
|
+
}
|
|
168
|
+
appendSecretToEnv(rootDir, secret);
|
|
169
|
+
consola.success("Added BETTER_AUTH_SECRET to .env");
|
|
170
|
+
return secret;
|
|
171
|
+
}
|
|
104
172
|
const module$1 = defineNuxtModule({
|
|
105
|
-
meta: { name: "@onmax/nuxt-better-auth", configKey: "auth", compatibility: { nuxt: ">=3.0.0" } },
|
|
173
|
+
meta: { name: "@onmax/nuxt-better-auth", version, configKey: "auth", compatibility: { nuxt: ">=3.0.0" } },
|
|
106
174
|
defaults: {
|
|
107
175
|
clientOnly: false,
|
|
108
176
|
serverConfig: "server/auth.config",
|
|
@@ -110,8 +178,40 @@ const module$1 = defineNuxtModule({
|
|
|
110
178
|
redirects: { login: "/login", guest: "/" },
|
|
111
179
|
secondaryStorage: false
|
|
112
180
|
},
|
|
181
|
+
async onInstall(nuxt) {
|
|
182
|
+
const generatedSecret = await promptForSecret(nuxt.options.rootDir);
|
|
183
|
+
if (generatedSecret)
|
|
184
|
+
process.env.BETTER_AUTH_SECRET = generatedSecret;
|
|
185
|
+
const serverPath = join(nuxt.options.rootDir, "server/auth.config.ts");
|
|
186
|
+
const clientPath = join(nuxt.options.srcDir, "auth.config.ts");
|
|
187
|
+
const serverTemplate = `import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
|
|
188
|
+
|
|
189
|
+
export default defineServerAuth({
|
|
190
|
+
emailAndPassword: { enabled: true },
|
|
191
|
+
})
|
|
192
|
+
`;
|
|
193
|
+
const clientTemplate = `import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
|
|
194
|
+
|
|
195
|
+
export default defineClientAuth({})
|
|
196
|
+
`;
|
|
197
|
+
if (!existsSync(serverPath)) {
|
|
198
|
+
await mkdir(dirname(serverPath), { recursive: true });
|
|
199
|
+
await writeFile(serverPath, serverTemplate);
|
|
200
|
+
consola.success("Created server/auth.config.ts");
|
|
201
|
+
}
|
|
202
|
+
if (!existsSync(clientPath)) {
|
|
203
|
+
await mkdir(dirname(clientPath), { recursive: true });
|
|
204
|
+
await writeFile(clientPath, clientTemplate);
|
|
205
|
+
const relativePath = clientPath.replace(`${nuxt.options.rootDir}/`, "");
|
|
206
|
+
consola.success(`Created ${relativePath}`);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
113
209
|
async setup(options, nuxt) {
|
|
114
210
|
const resolver = createResolver(import.meta.url);
|
|
211
|
+
if (options.clientConfig === "app/auth.config") {
|
|
212
|
+
const srcDirRelative = nuxt.options.srcDir.replace(`${nuxt.options.rootDir}/`, "");
|
|
213
|
+
options.clientConfig = srcDirRelative === nuxt.options.srcDir ? "auth.config" : `${srcDirRelative}/auth.config`;
|
|
214
|
+
}
|
|
115
215
|
const clientOnly = options.clientOnly;
|
|
116
216
|
const serverConfigFile = options.serverConfig;
|
|
117
217
|
const clientConfigFile = options.clientConfig;
|
|
@@ -120,9 +220,9 @@ const module$1 = defineNuxtModule({
|
|
|
120
220
|
const serverConfigExists = existsSync(`${serverConfigPath}.ts`) || existsSync(`${serverConfigPath}.js`);
|
|
121
221
|
const clientConfigExists = existsSync(`${clientConfigPath}.ts`) || existsSync(`${clientConfigPath}.js`);
|
|
122
222
|
if (!clientOnly && !serverConfigExists)
|
|
123
|
-
throw new Error(`[nuxt-better-auth] Missing ${serverConfigFile}.ts -
|
|
223
|
+
throw new Error(`[nuxt-better-auth] Missing ${serverConfigFile}.ts - export default defineServerAuth(...)`);
|
|
124
224
|
if (!clientConfigExists)
|
|
125
|
-
throw new Error(`[nuxt-better-auth] Missing ${clientConfigFile}.ts - export
|
|
225
|
+
throw new Error(`[nuxt-better-auth] Missing ${clientConfigFile}.ts - export default defineClientAuth(...)`);
|
|
126
226
|
const hasNuxtHub = hasNuxtModule("@nuxthub/core", nuxt);
|
|
127
227
|
const hub = hasNuxtHub ? nuxt.options.hub : void 0;
|
|
128
228
|
const hasHubDb = !clientOnly && hasNuxtHub && !!hub?.db;
|
|
@@ -151,7 +251,7 @@ const module$1 = defineNuxtModule({
|
|
|
151
251
|
const currentSecret = nuxt.options.runtimeConfig.betterAuthSecret;
|
|
152
252
|
nuxt.options.runtimeConfig.betterAuthSecret = currentSecret || process.env.BETTER_AUTH_SECRET || "";
|
|
153
253
|
const betterAuthSecret = nuxt.options.runtimeConfig.betterAuthSecret;
|
|
154
|
-
if (!nuxt.options.dev && !betterAuthSecret) {
|
|
254
|
+
if (!nuxt.options.dev && !nuxt.options._prepare && !betterAuthSecret) {
|
|
155
255
|
throw new Error("[nuxt-better-auth] BETTER_AUTH_SECRET is required in production. Set BETTER_AUTH_SECRET or NUXT_BETTER_AUTH_SECRET environment variable.");
|
|
156
256
|
}
|
|
157
257
|
if (betterAuthSecret && betterAuthSecret.length < 32) {
|
|
@@ -183,11 +283,13 @@ export function createSecondaryStorage() {
|
|
|
183
283
|
throw new Error("[nuxt-better-auth] hub:db not found. Ensure @nuxthub/core is loaded before this module and hub.db is configured.");
|
|
184
284
|
}
|
|
185
285
|
const hubDialect = getHubDialect(hub) ?? "sqlite";
|
|
286
|
+
const usePlural = options.schema?.usePlural ?? false;
|
|
287
|
+
const camelCase = (options.schema?.casing ?? getHubCasing(hub)) !== "snake_case";
|
|
186
288
|
const databaseCode = hasHubDb ? `import { db, schema } from '../hub/db.mjs'
|
|
187
289
|
import { drizzleAdapter } from 'better-auth/adapters/drizzle'
|
|
188
290
|
const rawDialect = '${hubDialect}'
|
|
189
291
|
const dialect = rawDialect === 'postgresql' ? 'pg' : rawDialect
|
|
190
|
-
export function createDatabase() { return drizzleAdapter(db, { provider: dialect, schema }) }
|
|
292
|
+
export function createDatabase() { return drizzleAdapter(db, { provider: dialect, schema, usePlural: ${usePlural}, camelCase: ${camelCase} }) }
|
|
191
293
|
export { db }` : `export function createDatabase() { return undefined }
|
|
192
294
|
export const db = undefined`;
|
|
193
295
|
const databaseTemplate = addTemplate({ filename: "better-auth/database.mjs", getContents: () => databaseCode, write: true });
|
|
@@ -220,9 +322,9 @@ declare module '#auth/database' {
|
|
|
220
322
|
getContents: () => `
|
|
221
323
|
import type { InferUser, InferSession, InferPluginTypes } from 'better-auth'
|
|
222
324
|
import type { RuntimeConfig } from 'nuxt/schema'
|
|
223
|
-
import type
|
|
325
|
+
import type createServerAuth from '${serverConfigPath}'
|
|
224
326
|
|
|
225
|
-
type _Config = ReturnType<typeof
|
|
327
|
+
type _Config = ReturnType<typeof createServerAuth>
|
|
226
328
|
|
|
227
329
|
declare module '#nuxt-better-auth' {
|
|
228
330
|
interface AuthUser extends InferUser<_Config> {}
|
|
@@ -243,7 +345,7 @@ interface _AugmentedServerAuthContext {
|
|
|
243
345
|
declare module '@onmax/nuxt-better-auth/config' {
|
|
244
346
|
import type { BetterAuthOptions } from 'better-auth'
|
|
245
347
|
type ServerAuthConfig = Omit<BetterAuthOptions, 'database' | 'secret' | 'baseURL'>
|
|
246
|
-
export function defineServerAuth<T extends ServerAuthConfig>(config: (ctx: _AugmentedServerAuthContext) => T): (ctx: _AugmentedServerAuthContext) => T
|
|
348
|
+
export function defineServerAuth<T extends ServerAuthConfig>(config: T | ((ctx: _AugmentedServerAuthContext) => T)): (ctx: _AugmentedServerAuthContext) => T
|
|
247
349
|
}
|
|
248
350
|
`
|
|
249
351
|
}, { nuxt: true, nitro: true, node: true });
|
|
@@ -280,7 +382,7 @@ export type { AuthMeta, AuthMode, AuthRouteRules, UserMatch, RequireSessionOptio
|
|
|
280
382
|
addTypeTemplate({
|
|
281
383
|
filename: "types/nuxt-better-auth-client.d.ts",
|
|
282
384
|
getContents: () => `
|
|
283
|
-
import type
|
|
385
|
+
import type createAppAuthClient from '${clientConfigPath}'
|
|
284
386
|
declare module '#nuxt-better-auth' {
|
|
285
387
|
export type AppAuthClient = ReturnType<typeof createAppAuthClient>
|
|
286
388
|
}
|
|
@@ -311,6 +413,8 @@ declare module '#nuxt-better-auth' {
|
|
|
311
413
|
}
|
|
312
414
|
const isProduction = process.env.NODE_ENV === "production" || !nuxt.options.dev;
|
|
313
415
|
if (!isProduction && !clientOnly) {
|
|
416
|
+
if (!hasNuxtModule("@nuxt/ui"))
|
|
417
|
+
await installModule("@nuxt/ui");
|
|
314
418
|
setupDevTools(nuxt);
|
|
315
419
|
addServerHandler({ route: "/api/_better-auth/config", method: "get", handler: resolver.resolve("./runtime/server/api/_better-auth/config.get") });
|
|
316
420
|
if (hasHubDb) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import createAppAuthClient from "#auth/client";
|
|
2
2
|
import { computed, nextTick, useRequestHeaders, useRequestURL, useRuntimeConfig, useState, watch } from "#imports";
|
|
3
3
|
let _client = null;
|
|
4
4
|
function getClient(baseURL) {
|
package/dist/runtime/config.d.ts
CHANGED
|
@@ -2,12 +2,13 @@ import type { BetterAuthOptions } from 'better-auth';
|
|
|
2
2
|
import type { ClientOptions } from 'better-auth/client';
|
|
3
3
|
import type { CasingOption } from '../schema-generator.js';
|
|
4
4
|
import type { ServerAuthContext } from './types/augment.js';
|
|
5
|
+
import { createAuthClient } from 'better-auth/vue';
|
|
5
6
|
export type { ServerAuthContext };
|
|
6
7
|
export interface ClientAuthContext {
|
|
7
8
|
siteUrl: string;
|
|
8
9
|
}
|
|
9
|
-
type ServerAuthConfig = Omit<BetterAuthOptions, 'database' | 'secret' | 'baseURL'>;
|
|
10
|
-
type ClientAuthConfig = Omit<ClientOptions, 'baseURL'> & {
|
|
10
|
+
export type ServerAuthConfig = Omit<BetterAuthOptions, 'database' | 'secret' | 'baseURL'>;
|
|
11
|
+
export type ClientAuthConfig = Omit<ClientOptions, 'baseURL'> & {
|
|
11
12
|
baseURL?: string;
|
|
12
13
|
};
|
|
13
14
|
export type ServerAuthConfigFn = (ctx: ServerAuthContext) => ServerAuthConfig;
|
|
@@ -44,5 +45,5 @@ export interface AuthRuntimeConfig {
|
|
|
44
45
|
export interface AuthPrivateRuntimeConfig {
|
|
45
46
|
secondaryStorage: boolean;
|
|
46
47
|
}
|
|
47
|
-
export declare function defineServerAuth<T extends ServerAuthConfig>(config: (ctx: ServerAuthContext) => T): (ctx: ServerAuthContext) => T;
|
|
48
|
-
export declare function defineClientAuth(config:
|
|
48
|
+
export declare function defineServerAuth<T extends ServerAuthConfig>(config: T | ((ctx: ServerAuthContext) => T)): (ctx: ServerAuthContext) => T;
|
|
49
|
+
export declare function defineClientAuth<T extends ClientAuthConfig>(config: T | ((ctx: ClientAuthContext) => T)): (baseURL: string) => ReturnType<typeof createAuthClient<T>>;
|
package/dist/runtime/config.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { createAuthClient } from "better-auth/vue";
|
|
1
2
|
export function defineServerAuth(config) {
|
|
2
|
-
return config;
|
|
3
|
+
return typeof config === "function" ? config : () => config;
|
|
3
4
|
}
|
|
4
5
|
export function defineClientAuth(config) {
|
|
5
|
-
return
|
|
6
|
+
return (baseURL) => {
|
|
7
|
+
const ctx = { siteUrl: baseURL };
|
|
8
|
+
const resolved = typeof config === "function" ? config(ctx) : config;
|
|
9
|
+
return createAuthClient({ ...resolved, baseURL });
|
|
10
|
+
};
|
|
6
11
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onmax/nuxt-better-auth",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.2-alpha.
|
|
4
|
+
"version": "0.0.2-alpha.15",
|
|
5
5
|
"packageManager": "pnpm@10.15.1",
|
|
6
6
|
"description": "Nuxt module for Better Auth integration with NuxtHub, route protection, session management, and role-based access",
|
|
7
7
|
"author": "onmax",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"dev:prepare": "nuxt-module-build build --stub && nuxi prepare playground",
|
|
51
51
|
"dev:docs": "nuxi dev docs",
|
|
52
52
|
"build:docs": "nuxi build docs",
|
|
53
|
-
"release": "bumpp --push",
|
|
53
|
+
"release": "bumpp --push --no-push-all",
|
|
54
54
|
"lint": "eslint .",
|
|
55
55
|
"lint:fix": "eslint . --fix",
|
|
56
56
|
"typecheck": "vue-tsc --noEmit",
|
|
@@ -70,10 +70,12 @@
|
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"@better-auth/cli": "^1.5.0-beta.3",
|
|
72
72
|
"@nuxt/kit": "^4.2.2",
|
|
73
|
+
"@nuxt/ui": "^4.2.1",
|
|
73
74
|
"defu": "^6.1.4",
|
|
74
75
|
"jiti": "^2.4.2",
|
|
75
76
|
"pathe": "^2.0.3",
|
|
76
|
-
"radix3": "^1.1.2"
|
|
77
|
+
"radix3": "^1.1.2",
|
|
78
|
+
"std-env": "^3.10.0"
|
|
77
79
|
},
|
|
78
80
|
"devDependencies": {
|
|
79
81
|
"@antfu/eslint-config": "^4.12.0",
|
|
@@ -18,13 +18,11 @@ export default defineNuxtConfig({
|
|
|
18
18
|
### 2. Point client to external server
|
|
19
19
|
|
|
20
20
|
```ts [app/auth.config.ts]
|
|
21
|
-
import {
|
|
21
|
+
import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
|
|
22
22
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
27
|
-
}
|
|
23
|
+
export default defineClientAuth({
|
|
24
|
+
baseURL: 'https://auth.example.com', // External auth server
|
|
25
|
+
})
|
|
28
26
|
```
|
|
29
27
|
|
|
30
28
|
### 3. Set frontend URL
|
|
@@ -81,7 +81,7 @@ Database adapter injected via context:
|
|
|
81
81
|
|
|
82
82
|
```ts
|
|
83
83
|
// server/auth.config.ts
|
|
84
|
-
import { defineServerAuth } from '
|
|
84
|
+
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
|
|
85
85
|
|
|
86
86
|
export default defineServerAuth(({ db }) => ({
|
|
87
87
|
database: db, // Already configured when hub.database: true
|
|
@@ -96,13 +96,13 @@ Without NuxtHub, configure manually:
|
|
|
96
96
|
```ts
|
|
97
97
|
// server/auth.config.ts
|
|
98
98
|
import { drizzle } from 'drizzle-orm/...'
|
|
99
|
-
import { defineServerAuth } from '
|
|
99
|
+
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
|
|
100
100
|
|
|
101
101
|
const db = drizzle(...)
|
|
102
102
|
|
|
103
|
-
export default defineServerAuth(
|
|
103
|
+
export default defineServerAuth({
|
|
104
104
|
database: drizzleAdapter(db, { provider: 'sqlite' })
|
|
105
|
-
})
|
|
105
|
+
})
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
## Migrations
|
|
@@ -44,18 +44,29 @@ NUXT_PUBLIC_SITE_URL=https://your-domain.com
|
|
|
44
44
|
|
|
45
45
|
```ts
|
|
46
46
|
// server/auth.config.ts
|
|
47
|
-
import { defineServerAuth } from '
|
|
47
|
+
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
// Object syntax (simplest)
|
|
50
|
+
export default defineServerAuth({
|
|
50
51
|
emailAndPassword: { enabled: true },
|
|
51
52
|
// OAuth providers
|
|
53
|
+
socialProviders: {
|
|
54
|
+
github: {
|
|
55
|
+
clientId: process.env.GITHUB_CLIENT_ID as string,
|
|
56
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET as string
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
// Or function syntax (access context like runtimeConfig, db)
|
|
62
|
+
export default defineServerAuth(({ runtimeConfig, db }) => ({
|
|
63
|
+
emailAndPassword: { enabled: true },
|
|
52
64
|
socialProviders: {
|
|
53
65
|
github: {
|
|
54
66
|
clientId: runtimeConfig.github.clientId,
|
|
55
67
|
clientSecret: runtimeConfig.github.clientSecret
|
|
56
68
|
}
|
|
57
69
|
},
|
|
58
|
-
// Session configuration (optional)
|
|
59
70
|
session: {
|
|
60
71
|
expiresIn: 60 * 60 * 24 * 7, // 7 days (default)
|
|
61
72
|
updateAge: 60 * 60 * 24, // Update every 24h (default)
|
|
@@ -88,11 +99,17 @@ Context available in `defineServerAuth`:
|
|
|
88
99
|
|
|
89
100
|
```ts
|
|
90
101
|
// app/auth.config.ts
|
|
91
|
-
import {
|
|
102
|
+
import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
|
|
92
103
|
|
|
93
|
-
|
|
104
|
+
// Object syntax (simplest)
|
|
105
|
+
export default defineClientAuth({
|
|
94
106
|
// Client-side plugin options (e.g., passkey, twoFactor)
|
|
95
107
|
})
|
|
108
|
+
|
|
109
|
+
// Or function syntax (access context like siteUrl)
|
|
110
|
+
export default defineClientAuth(({ siteUrl }) => ({
|
|
111
|
+
// siteUrl contains the resolved base URL
|
|
112
|
+
}))
|
|
96
113
|
```
|
|
97
114
|
|
|
98
115
|
## NuxtHub Integration
|
|
@@ -6,9 +6,10 @@ The module supports all Better Auth plugins. Configure in both server and client
|
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
// server/auth.config.ts
|
|
9
|
-
import { defineServerAuth } from '
|
|
9
|
+
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
|
|
10
|
+
import { admin, twoFactor, passkey, multiSession } from 'better-auth/plugins'
|
|
10
11
|
|
|
11
|
-
export default defineServerAuth(
|
|
12
|
+
export default defineServerAuth({
|
|
12
13
|
emailAndPassword: { enabled: true },
|
|
13
14
|
plugins: [
|
|
14
15
|
admin(),
|
|
@@ -16,17 +17,17 @@ export default defineServerAuth(({ runtimeConfig }) => ({
|
|
|
16
17
|
passkey(),
|
|
17
18
|
multiSession()
|
|
18
19
|
]
|
|
19
|
-
})
|
|
20
|
+
})
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
## Client Plugin Setup
|
|
23
24
|
|
|
24
25
|
```ts
|
|
25
26
|
// app/auth.config.ts
|
|
26
|
-
import {
|
|
27
|
+
import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
|
|
27
28
|
import { adminClient, twoFactorClient, passkeyClient, multiSessionClient } from 'better-auth/client/plugins'
|
|
28
29
|
|
|
29
|
-
export default
|
|
30
|
+
export default defineClientAuth({
|
|
30
31
|
plugins: [
|
|
31
32
|
adminClient(),
|
|
32
33
|
twoFactorClient(),
|
|
@@ -111,14 +111,16 @@ Extend user type via Better Auth config:
|
|
|
111
111
|
|
|
112
112
|
```ts
|
|
113
113
|
// server/auth.config.ts
|
|
114
|
-
|
|
114
|
+
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
|
|
115
|
+
|
|
116
|
+
export default defineServerAuth({
|
|
115
117
|
user: {
|
|
116
118
|
additionalFields: {
|
|
117
119
|
plan: { type: 'string' },
|
|
118
120
|
credits: { type: 'number' }
|
|
119
121
|
}
|
|
120
122
|
}
|
|
121
|
-
})
|
|
123
|
+
})
|
|
122
124
|
```
|
|
123
125
|
|
|
124
126
|
Types automatically include these fields:
|