UNPKG

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
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 };