nuxt-users
Version:
A comprehensive user management module for Nuxt 3 and Nuxt 4 applications with authentication, authorization, database support, and CLI tools
274 lines (271 loc) • 10.3 kB
JavaScript
import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addServerImportsDir, addServerHandler, addRouteMiddleware, addComponentsDir } from '@nuxt/kit';
import { defu } from 'defu';
export * from '../dist/runtime/server/internal/index.js';
const defaultOptions = {
connector: {
name: "sqlite",
options: {
path: "./data/users.sqlite3"
}
},
apiBasePath: "/api/nuxt-users",
tables: {
migrations: "migrations",
users: "users",
personalAccessTokens: "personal_access_tokens",
passwordResetTokens: "password_reset_tokens"
},
mailer: {
// Added default mailer (example using ethereal.email)
host: "smtp.ethereal.email",
port: 587,
secure: false,
auth: {
user: "user@ethereal.email",
// Replace with actual Ethereal user
pass: "password"
// Replace with actual Ethereal password
},
defaults: {
from: '"Nuxt Users Module" <noreply@example.com>'
}
},
passwordResetUrl: "/reset-password",
emailConfirmationUrl: "/email-confirmation",
auth: {
whitelist: [],
tokenExpiration: 24 * 60,
// 24 hours in minutes
rememberMeExpiration: 30,
// 30 days
permissions: {}
// Empty by default - whitelist approach
},
passwordValidation: {
minLength: 8,
requireUppercase: true,
requireLowercase: true,
requireNumbers: true,
requireSpecialChars: true,
preventCommonPasswords: true
},
hardDelete: false
};
const module$1 = defineNuxtModule({
meta: {
name: "nuxt-users",
configKey: "nuxtUsers"
},
// Default configuration options of the Nuxt module
defaults: defaultOptions,
async setup(options, nuxt) {
const resolver = createResolver(import.meta.url);
const { connector: _defaultConnector, ...defaultsWithoutConnector } = defaultOptions;
const runtimeConfigOptions = defu(nuxt.options.runtimeConfig.nuxtUsers || {}, options, defaultsWithoutConnector);
const configuredConnector = nuxt.options.runtimeConfig.nuxtUsers?.connector || options.connector;
runtimeConfigOptions.connector = configuredConnector || defaultOptions.connector;
nuxt.options.runtimeConfig.nuxtUsers = {
...runtimeConfigOptions,
auth: {
tokenExpiration: runtimeConfigOptions.auth.tokenExpiration,
rememberMeExpiration: runtimeConfigOptions.auth.rememberMeExpiration,
permissions: runtimeConfigOptions.auth.permissions,
...runtimeConfigOptions.auth.google && { google: runtimeConfigOptions.auth.google },
whitelist: (() => {
const combinedWhitelist = [...defaultOptions.auth?.whitelist || [], ...runtimeConfigOptions.auth?.whitelist || []];
const apiBasePath = runtimeConfigOptions.apiBasePath || defaultOptions.apiBasePath;
if (combinedWhitelist.includes("/register")) {
const registrationEndpoints = [
"/confirm-email",
// Page route for email confirmation
`${apiBasePath}/register`,
// API endpoint for registration
`${apiBasePath}/confirm-email`
// API endpoint for email confirmation
];
registrationEndpoints.forEach((endpoint) => {
if (!combinedWhitelist.includes(endpoint)) {
combinedWhitelist.push(endpoint);
}
});
}
if (runtimeConfigOptions.auth?.google) {
const googleOAuthEndpoints = [
`${apiBasePath}/auth/google/redirect`,
`${apiBasePath}/auth/google/callback`
];
googleOAuthEndpoints.forEach((endpoint) => {
if (!combinedWhitelist.includes(endpoint)) {
combinedWhitelist.push(endpoint);
}
});
}
return combinedWhitelist;
})()
}
};
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
nuxt.options.runtimeConfig.public.nuxtUsers = {
passwordValidation: runtimeConfigOptions.passwordValidation,
auth: {
whitelist: (() => {
const combinedWhitelist = [...defaultOptions.auth?.whitelist || [], ...runtimeConfigOptions.auth?.whitelist || []];
const apiBasePath = runtimeConfigOptions.apiBasePath || defaultOptions.apiBasePath;
if (combinedWhitelist.includes("/register")) {
const registrationEndpoints = [
"/confirm-email",
// Page route for email confirmation
`${apiBasePath}/register`,
// API endpoint for registration
`${apiBasePath}/confirm-email`
// API endpoint for email confirmation
];
registrationEndpoints.forEach((endpoint) => {
if (!combinedWhitelist.includes(endpoint)) {
combinedWhitelist.push(endpoint);
}
});
}
if (runtimeConfigOptions.auth?.google) {
const googleOAuthEndpoints = [
`${apiBasePath}/auth/google/redirect`,
`${apiBasePath}/auth/google/callback`
];
googleOAuthEndpoints.forEach((endpoint) => {
if (!combinedWhitelist.includes(endpoint)) {
combinedWhitelist.push(endpoint);
}
});
}
return combinedWhitelist;
})(),
permissions: runtimeConfigOptions.auth?.permissions || defaultOptions.auth.permissions
},
apiBasePath: runtimeConfigOptions.apiBasePath || defaultOptions.apiBasePath
};
addPlugin({
src: resolver.resolve("./runtime/plugin.auth-init"),
name: "0-auth-init-nuxt-users"
});
addPlugin({
src: resolver.resolve("./runtime/plugin"),
mode: "server"
});
addImportsDir(resolver.resolve("./runtime/composables"));
addServerImportsDir(resolver.resolve("./runtime/server/composables"));
addServerHandler({
middleware: true,
handler: resolver.resolve("./runtime/server/middleware/authorization.server")
});
addRouteMiddleware({
name: "authorization.client",
path: resolver.resolve("./runtime/middleware/authorization.client"),
global: true
});
const base = nuxt.options.runtimeConfig.nuxtUsers.apiBasePath || defaultOptions.apiBasePath;
addServerHandler({
route: `${base}/session`,
method: "post",
handler: resolver.resolve("./runtime/server/api/nuxt-users/session/index.post")
});
addServerHandler({
route: `${base}/session`,
method: "delete",
handler: resolver.resolve("./runtime/server/api/nuxt-users/session/index.delete")
});
addServerHandler({
route: `${base}/me`,
method: "get",
handler: resolver.resolve("./runtime/server/api/nuxt-users/me.get")
});
addServerHandler({
route: `${base}/me`,
method: "patch",
handler: resolver.resolve("./runtime/server/api/nuxt-users/me.patch")
});
addServerHandler({
route: `${base}/password`,
method: "patch",
handler: resolver.resolve("./runtime/server/api/nuxt-users/password/index.patch")
});
addServerHandler({
route: `${base}/password/forgot`,
method: "post",
handler: resolver.resolve("./runtime/server/api/nuxt-users/password/forgot.post")
});
addServerHandler({
route: `${base}/password/reset`,
method: "post",
handler: resolver.resolve("./runtime/server/api/nuxt-users/password/reset.post")
});
addServerHandler({
route: `${base}/register`,
method: "post",
handler: resolver.resolve("./runtime/server/api/nuxt-users/register.post")
});
addServerHandler({
route: `${base}/confirm-email`,
method: "get",
handler: resolver.resolve("./runtime/server/api/nuxt-users/confirm-email.get")
});
addServerHandler({
route: `${base}/auth/google/redirect`,
method: "get",
handler: resolver.resolve("./runtime/server/api/nuxt-users/auth/google/redirect.get")
});
addServerHandler({
route: `${base}/auth/google/callback`,
method: "get",
handler: resolver.resolve("./runtime/server/api/nuxt-users/auth/google/callback.get")
});
addServerHandler({
route: `${base}`,
method: "get",
handler: resolver.resolve("./runtime/server/api/nuxt-users/index.get")
});
addServerHandler({
route: `${base}`,
method: "post",
handler: resolver.resolve("./runtime/server/api/nuxt-users/index.post")
});
addServerHandler({
route: `${base}/:id`,
method: "get",
handler: resolver.resolve("./runtime/server/api/nuxt-users/[id].get")
});
addServerHandler({
route: `${base}/:id`,
method: "patch",
handler: resolver.resolve("./runtime/server/api/nuxt-users/[id].patch")
});
addServerHandler({
route: `${base}/:id`,
method: "delete",
handler: resolver.resolve("./runtime/server/api/nuxt-users/[id].delete")
});
nuxt.hook("nitro:config", async (nitroConfig) => {
nitroConfig.experimental = nitroConfig.experimental || {};
nitroConfig.experimental.database = true;
nitroConfig.experimental.tasks = true;
nitroConfig.scanDirs = nitroConfig.scanDirs || [];
nitroConfig.scanDirs.push(resolver.resolve("./runtime/server/tasks"));
nitroConfig.prerender = nitroConfig.prerender || {};
nitroConfig.prerender.ignore = nitroConfig.prerender.ignore || [];
const apiBasePath = nuxt.options.runtimeConfig.nuxtUsers.apiBasePath || defaultOptions.apiBasePath;
const ignorePattern = `${apiBasePath}/**`;
if (!nitroConfig.prerender.ignore.includes(ignorePattern)) {
nitroConfig.prerender.ignore.push(ignorePattern);
console.log(`[Nuxt Users] \u{1F527} Automatically excluding "${ignorePattern}" from prerendering to prevent build hangs`);
}
});
addComponentsDir({
path: resolver.resolve("./runtime/components"),
pathPrefix: false,
prefix: "",
global: true
});
nuxt.options.css = nuxt.options.css || [];
nuxt.options.css.push(resolver.resolve("./runtime/assets/nuxt-users.css"));
}
});
export { module$1 as default, defaultOptions };