nuxt-users 1.44.0 → 1.46.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/dist/cli.mjs CHANGED
@@ -1,16 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineCommand, runMain } from 'citty';
3
3
  import { readFileSync } from 'node:fs';
4
- import { defaultOptions } from './module.mjs';
5
- import { loadNuxt } from '@nuxt/kit';
4
+ import { d as defaultOptions } from './shared/nuxt-users.BsNZbqYb.mjs';
6
5
  import { defu } from 'defu';
7
- import { runMigrations, createUser as createUser$1, createUsersTable as createUsersTable$1, createPersonalAccessTokensTable as createPersonalAccessTokensTable$1, createPasswordResetTokensTable as createPasswordResetTokensTable$1, createMigrationsTable as createMigrationsTable$1, useDb, checkTableExists, getAppliedMigrations } from '../dist/runtime/server/utils/index.js';
8
- import { g as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.Cvjgn5KJ.mjs';
6
+ import { runMigrations, getAppliedMigrations } from '../dist/runtime/server/utils/migrate.js';
7
+ import { createUser as createUser$1 } from '../dist/runtime/server/utils/user.js';
8
+ import { b as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.9p2ye9P4.mjs';
9
9
  import '../dist/runtime/locales/index.js';
10
10
  import '../dist/runtime/utils/locale.js';
11
11
  import '../dist/runtime/utils/deep-merge.js';
12
+ import { createUsersTable as createUsersTable$1 } from '../dist/runtime/server/utils/create-users-table.js';
13
+ import { createPersonalAccessTokensTable as createPersonalAccessTokensTable$1 } from '../dist/runtime/server/utils/create-personal-access-tokens-table.js';
14
+ import { createPasswordResetTokensTable as createPasswordResetTokensTable$1 } from '../dist/runtime/server/utils/create-password-reset-tokens-table.js';
15
+ import { createMigrationsTable as createMigrationsTable$1 } from '../dist/runtime/server/utils/create-migrations-table.js';
12
16
  import { addActiveToUsers as addActiveToUsers$1 } from '../dist/runtime/server/utils/add-active-to-users.js';
13
- import '../dist/runtime/server/internal/index.js';
17
+ import { useDb, checkTableExists } from '../dist/runtime/server/utils/db.js';
14
18
 
15
19
  const getOptionsFromEnv = () => {
16
20
  const connectorName = process.env.DB_CONNECTOR || "sqlite";
@@ -56,6 +60,7 @@ const loadOptions = async () => {
56
60
  console.log("[Nuxt Users] \u2139\uFE0F Note: CLI commands read .env files. If you use .env.local in development, export variables first:");
57
61
  console.log("[Nuxt Users] set -a; source .env.local; set +a; npx nuxt-users <command>");
58
62
  console.log("[Nuxt Users] In production, environment variables are set directly in the deployment environment.");
63
+ const { loadNuxt } = await import('@nuxt/kit');
59
64
  const nuxt = await loadNuxt({ cwd: process.cwd(), ready: false });
60
65
  const topLevelConfig = nuxt.options.nuxtUsers;
61
66
  const processedRuntimeConfig = nuxt.options.runtimeConfig?.nuxtUsers;
@@ -352,6 +357,7 @@ const projectInfo = defineCommand({
352
357
  },
353
358
  async run() {
354
359
  try {
360
+ const { loadNuxt } = await import('@nuxt/kit');
355
361
  console.log("[Nuxt Users] Loading Nuxt project...");
356
362
  console.log("[Nuxt Users] \u2139\uFE0F Note: CLI commands read .env files. If you use .env.local in development, export variables first:");
357
363
  console.log("[Nuxt Users] set -a; source .env.local; set +a; npx nuxt-users <command>");
package/dist/module.d.mts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { M as ModuleOptions } from './shared/nuxt-users.DUmdxjpk.mjs';
2
+ import { M as ModuleOptions } from './shared/nuxt-users.bLYb3Bz5.mjs';
3
3
  export * from '../dist/runtime/server/internal/index.js';
4
4
 
5
5
  declare const defaultOptions: ModuleOptions;
6
+
6
7
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
7
8
 
8
9
  export { _default as default, defaultOptions };
package/dist/module.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { M as ModuleOptions } from './shared/nuxt-users.DUmdxjpk.js';
2
+ import { M as ModuleOptions } from './shared/nuxt-users.bLYb3Bz5.js';
3
3
  export * from '../dist/runtime/server/internal/index.js';
4
4
 
5
5
  declare const defaultOptions: ModuleOptions;
6
+
6
7
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
7
8
 
8
9
  export { _default as default, defaultOptions };
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0"
6
6
  },
7
- "version": "1.44.0",
7
+ "version": "1.46.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,67 +1,8 @@
1
1
  import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addServerImportsDir, addServerScanDir, addServerHandler, addServerPlugin, addRouteMiddleware, addComponentsDir } from '@nuxt/kit';
2
2
  import { defu } from 'defu';
3
+ import { d as defaultOptions } from './shared/nuxt-users.BsNZbqYb.mjs';
3
4
  export * from '../dist/runtime/server/internal/index.js';
4
5
 
5
- const defaultOptions = {
6
- connector: {
7
- name: "sqlite",
8
- options: {
9
- path: "./data/users.sqlite3"
10
- }
11
- },
12
- apiBasePath: "/api/nuxt-users",
13
- tables: {
14
- migrations: "migrations",
15
- users: "users",
16
- personalAccessTokens: "personal_access_tokens",
17
- passwordResetTokens: "password_reset_tokens"
18
- },
19
- mailer: {
20
- // Added default mailer (example using ethereal.email)
21
- host: "smtp.ethereal.email",
22
- port: 587,
23
- secure: false,
24
- auth: {
25
- user: "user@ethereal.email",
26
- // Replace with actual Ethereal user
27
- pass: "password"
28
- // Replace with actual Ethereal password
29
- },
30
- defaults: {
31
- from: '"Nuxt Users Module" <noreply@example.com>'
32
- }
33
- },
34
- passwordResetUrl: "/reset-password",
35
- emailConfirmationUrl: "/email-confirmation",
36
- auth: {
37
- whitelist: [],
38
- tokenExpiration: 24 * 60,
39
- // 24 hours in minutes
40
- rememberMeExpiration: 30,
41
- // 30 days
42
- permissions: {}
43
- // Empty by default - whitelist approach
44
- },
45
- passwordValidation: {
46
- minLength: 8,
47
- requireUppercase: true,
48
- requireLowercase: true,
49
- requireNumbers: true,
50
- requireSpecialChars: true,
51
- preventCommonPasswords: true
52
- },
53
- hardDelete: false,
54
- locale: {
55
- default: "en",
56
- fallbackLocale: "en",
57
- texts: {}
58
- },
59
- tokenCleanupSchedule: "0 2 * * *",
60
- // Daily at 2 AM
61
- theme: {
62
- enabled: true
63
- }
64
- };
65
6
  const module$1 = defineNuxtModule({
66
7
  meta: {
67
8
  name: "nuxt-users",
@@ -182,6 +123,7 @@ const module$1 = defineNuxtModule({
182
123
  handler: resolver.resolve("./runtime/server/middleware/authorization.server")
183
124
  });
184
125
  addServerPlugin(resolver.resolve("./runtime/server/plugins/auto-migrate"));
126
+ addServerPlugin(resolver.resolve("./runtime/server/plugins/validate-mailer-config"));
185
127
  addRouteMiddleware({
186
128
  name: "authorization.client",
187
129
  path: resolver.resolve("./runtime/middleware/authorization.client"),
@@ -1 +1 @@
1
- :root{--nu-color-primary:#3b82f6;--nu-color-primary-dark:#2563eb;--nu-color-primary-light:#60a5fa;--nu-color-white:#fff;--nu-color-gray-50:#f9fafb;--nu-color-gray-500:#6b7280;--nu-color-gray-600:#4b5563;--nu-color-gray-700:#374151;--nu-color-gray-900:#111827;--nu-color-success:#059669;--nu-color-success-light:#f0fdf4;--nu-color-success-border:#9ae6b4;--nu-color-success-text:#047857;--nu-color-error:#dc2626;--nu-color-error-light:#fef2f2;--nu-color-error-border:#fecaca;--nu-color-error-alt:#db5050;--nu-color-error-dark:#b91c1c;--nu-color-border:#e5e7eb;--nu-color-border-light:#d1d5db;--nu-color-border-dark:#ccc;--nu-color-bg-primary:#fff;--nu-color-bg-secondary:#f9fafb;--nu-color-bg-tertiary:#f3f4f6;--nu-color-text-primary:#000;--nu-color-text-secondary:#6b7280;--nu-color-strength-bg:#e9ecef;--nu-color-validation-passed:#15803d;--nu-color-validation-failed:#dc3545;--nu-color-validation-hint:#6c757d}@media (prefers-color-scheme:dark){:root:not(.light){--nu-color-primary:#60a5fa;--nu-color-primary-dark:#3b82f6;--nu-color-primary-light:#93c5fd;--nu-color-white:#000;--nu-color-gray-50:#111827;--nu-color-gray-500:#9ca3af;--nu-color-gray-600:#d1d5db;--nu-color-gray-700:#e5e7eb;--nu-color-gray-900:#f9fafb;--nu-color-success:#10b981;--nu-color-success-light:#064e3b;--nu-color-success-border:#065f46;--nu-color-success-text:#6ee7b7;--nu-color-error:#ef4444;--nu-color-error-light:#450a0a;--nu-color-error-border:#7f1d1d;--nu-color-error-alt:#f87171;--nu-color-error-dark:#dc2626;--nu-color-border:#374151;--nu-color-border-light:#4b5563;--nu-color-border-dark:#6b7280;--nu-color-bg-primary:#111827;--nu-color-bg-secondary:#1f2937;--nu-color-bg-tertiary:#374151;--nu-color-text-primary:#fff;--nu-color-text-secondary:#9ca3af;--nu-color-strength-bg:#374151;--nu-color-validation-passed:#22c55e;--nu-color-validation-failed:#ef4444;--nu-color-validation-hint:#9ca3af}}:root.dark{--nu-color-primary:#60a5fa;--nu-color-primary-dark:#3b82f6;--nu-color-primary-light:#93c5fd;--nu-color-white:#000;--nu-color-gray-50:#111827;--nu-color-gray-500:#9ca3af;--nu-color-gray-600:#d1d5db;--nu-color-gray-700:#e5e7eb;--nu-color-gray-900:#f9fafb;--nu-color-success:#10b981;--nu-color-success-light:#064e3b;--nu-color-success-border:#065f46;--nu-color-success-text:#6ee7b7;--nu-color-error:#ef4444;--nu-color-error-light:#450a0a;--nu-color-error-border:#7f1d1d;--nu-color-error-alt:#f87171;--nu-color-error-dark:#dc2626;--nu-color-border:#374151;--nu-color-border-light:#4b5563;--nu-color-border-dark:#6b7280;--nu-color-bg-primary:#111827;--nu-color-bg-secondary:#1f2937;--nu-color-bg-tertiary:#374151;--nu-color-text-primary:#fff;--nu-color-text-secondary:#9ca3af;--nu-color-strength-bg:#374151;--nu-color-validation-passed:#22c55e;--nu-color-validation-failed:#ef4444;--nu-color-validation-hint:#9ca3af}.n-users-form-group{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem;width:100%}.n-users-form-group.n-users-form-group-narrow{width:90%}.n-users-form-group label,.n-users-form-label{color:var(--nu-color-text-primary,#000);display:block;font-size:1rem;font-weight:500;margin-bottom:.5rem}.n-users-form-group input,.n-users-form-group select,.n-users-form-input{border:1px solid var(--nu-color-border,#ccc);border-radius:.25rem;font-size:1rem;padding:.5rem;transition:border-color .2s,box-shadow .2s;width:100%}.n-users-form-group input:focus,.n-users-form-group select:focus,.n-users-form-input:focus{border-color:var(--nu-color-primary);box-shadow:0 0 0 .1rem rgba(59,130,246,.1);outline:none}.n-users-form-group input:disabled,.n-users-form-input:disabled{background-color:var(--nu-color-bg-secondary,#f9fafb);cursor:not-allowed}.n-users-form-group input.error,.n-users-form-input.error{border-color:var(--nu-color-error,#dc3545)}.n-users-form-group input[type=email],.n-users-form-group input[type=password],.n-users-form-group input[type=text]{background-color:var(--nu-color-bg-secondary);border:1px solid var(--nu-color-border-light);border-radius:.5em;box-sizing:border-box;color:var(--nu-color-gray-700);font-size:.875rem;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-form-group input[type=email]:focus,.n-users-form-group input[type=password]:focus,.n-users-form-group input[type=text]:focus{background-color:var(--nu-color-bg-primary);border-color:var(--nu-color-primary);box-shadow:0 0 0 3px rgba(59,130,246,.1);outline:none}.n-users-form-group input[type=checkbox]{margin:0;width:auto}.n-users-google-btn{align-items:center;border:none;border-radius:.25rem;cursor:pointer;display:inline-flex;font-size:1rem;font-weight:500;gap:8px;justify-content:center;padding:.5rem 1rem;text-decoration:none;transition:background-color .2s,transform .1s}.n-users-google-logo{flex-shrink:0}.n-users-btn,.n-users-cancel-btn,.n-users-delete-btn,.n-users-edit-btn,.n-users-submit-btn{align-self:flex-start;border:none;border-radius:.25rem;cursor:pointer;display:inline-block;font-size:1rem;font-weight:500;padding:.5rem 1rem;text-decoration:none;transition:background-color .2s,transform .1s}.n-users-btn:hover,.n-users-edit-btn:hover,.n-users-submit-btn:hover{background-color:var(--nu-color-primary-dark,#2563eb);transform:translateY(-1px)}.n-users-btn:disabled,.n-users-submit-btn:disabled{cursor:not-allowed;opacity:.6;transform:none}.n-users-btn-primary,.n-users-edit-btn,.n-users-submit-btn{background-color:var(--nu-color-primary,#3b82f6);color:#fff}.n-users-btn-secondary,.n-users-cancel-btn{background-color:var(--nu-color-gray-600,#4b5563);color:#fff}.n-users-cancel-btn:hover{background-color:var(--nu-color-gray-700,#374151)}.n-users-delete-btn{background-color:var(--nu-color-error-dark,#b91c1c);color:#fff}.n-users-delete-btn:hover{background-color:#991b1b}.n-users-login-section button[type=submit],.n-users-register-section button[type=submit],.n-users-reset-password-container button[type=submit],.n-users-user-form button[type=submit],form.n-users-form button[type=submit]{align-items:center;background-color:var(--nu-color-primary);border:1px solid var(--nu-color-primary);border-radius:.5em;color:var(--nu-color-white);cursor:pointer;display:flex;font-size:.875rem;font-weight:500;gap:.5rem;justify-content:center;min-height:44px;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-login-section button[type=submit]:hover:not(:disabled),.n-users-register-section button[type=submit]:hover:not(:disabled),.n-users-reset-password-container button[type=submit]:hover:not(:disabled),.n-users-user-form button[type=submit]:hover:not(:disabled),form.n-users-form button[type=submit]:hover:not(:disabled){background-color:var(--nu-color-primary-dark);border-color:var(--nu-color-primary-dark)}.n-users-login-section button[type=submit]:disabled,.n-users-register-section button[type=submit]:disabled,.n-users-reset-password-container button[type=submit]:disabled,.n-users-user-form button[type=submit]:disabled,form.n-users-form button[type=submit]:disabled{cursor:not-allowed;opacity:.6}.n-users-error-message,.n-users-error-text{background-color:var(--nu-color-error-light,#fef2f2);border:1px solid var(--nu-color-error-border,#fecaca);border-radius:.5rem;color:var(--nu-color-error-dark,#b91c1c);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-success-message{background-color:var(--nu-color-success-light,#f0fdf4);border:1px solid var(--nu-color-success-border,#9ae6b4);border-radius:.5rem;color:var(--nu-color-success-text,#047857);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-grid{display:grid;gap:1rem}.n-users-grid-2{grid-template-columns:1fr 5fr}.n-users-grid-auto{grid-template-columns:repeat(auto-fill,minmax(12em,1fr))}.n-users-form-actions{align-items:center;display:flex;gap:1rem;margin-top:1.5rem}.n-users-loading-spinner{animation:n-users-spin 1s linear infinite;border:2px solid var(--nu-color-white,#fff);border-radius:50%;border-top:2px solid transparent;height:16px;width:16px}@keyframes n-users-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.n-users-card{background-color:var(--nu-color-bg-primary,#fff);border:1px solid var(--nu-color-border,#e5e7eb);border-radius:.5rem;padding:1rem}.n-users-section{margin:0 auto;max-width:42em;padding:1em}.n-users-section-header{border-bottom:.1em solid var(--nu-color-border,#e5e7eb);margin-bottom:1rem;padding-bottom:.5rem}.n-users-form-help{color:var(--nu-color-text-secondary,#6b7280);font-size:.75rem;margin-top:.25rem}.n-users-strength-bar{background-color:var(--nu-color-strength-bg,#e9ecef);border-radius:2px;height:4px;margin-bottom:4px;overflow:hidden;width:100%}.n-users-strength-fill{height:100%;transition:width .3s ease,background-color .3s ease}.n-users-strength-text{font-size:.75rem;font-weight:500}.n-users-validation-container{background-color:#f8f9fa;border:1px solid #e9ecef;border-radius:4px;margin-top:12px;padding:12px}.n-users-container-title{color:#495057;font-size:.875rem;font-weight:600;margin-bottom:8px}.n-users-list-unstyled{list-style:none;margin:0;padding-left:0}.n-users-list-item{align-items:center;display:flex;font-size:.875rem;margin-bottom:6px;transition:color .2s ease}.n-users-list-item:last-child{margin-bottom:0}.n-users-icon{font-weight:700;margin-right:8px;min-width:16px;text-align:center}.n-users-text{flex:1}.n-users-list ul{list-style:none}.n-users-login-section form,.n-users-register-section form,.n-users-reset-password-container form,.n-users-user-form form,form.n-users-form{display:flex;flex-direction:column;gap:1.5rem}.n-users-login-section{background:linear-gradient(135deg,var(--nu-color-bg-primary) 0,var(--nu-color-bg-secondary) 100%);border:1px solid var(--nu-color-border);border-radius:.75em;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);max-width:25rem}.n-users-login-header{margin-bottom:1em;text-align:center}.n-users-login-title{color:var(--nu-color-gray-700);font-size:1.875rem;font-weight:700;line-height:1.2;margin:0 0 .5em}.n-users-login-subtitle{color:var(--nu-color-gray-700);font-size:.875rem;line-height:1.5;margin:0}.n-users-remember-me{align-items:center;display:flex;gap:.5rem}.n-users-remember-me label{color:var(--nu-color-gray-700);font-size:.875rem;margin:0}.n-users-login-footer{margin-top:1em;text-align:center}.n-users-forgot-password{margin:0}.n-users-forgot-link{align-items:center;color:var(--nu-color-primary);display:inline-flex;font-size:.875rem;gap:.5rem;text-decoration:none;transition:color .2s ease-in-out}.n-users-forgot-link:hover:not(.loading){color:var(--nu-color-primary-dark);text-decoration:underline}.n-users-forgot-link.loading{cursor:not-allowed;opacity:.6;pointer-events:none}.n-users-link{color:var(--nu-color-primary);font-size:.875rem;text-decoration:none;transition:color .2s ease-in-out}.n-users-link:hover{color:var(--nu-color-primary-dark);text-decoration:underline}.n-users-link:visited{color:var(--nu-color-primary)}.n-users-link:visited:hover{color:var(--nu-color-primary-dark)}.n-users-password-strength{margin-top:8px}.n-users-validation-rules{margin-top:12px}.n-users-rules-title{margin-bottom:8px}.n-users-rules-list{padding-left:0}.n-users-rule-item{margin-bottom:6px}.n-users-rule-item:last-child{margin-bottom:0}.n-users-rule-passed{color:var(--nu-color-validation-passed,#15803d)}.n-users-rule-failed{color:var(--nu-color-validation-failed,#dc3545)}.n-users-rule-icon{margin-right:8px}.n-users-rule-text{flex:1}.n-users-validation-errors{margin-top:8px}.n-users-error-text:last-child{margin-bottom:0}.n-users-password-hints{margin-top:8px}.n-users-hint-title{margin-bottom:8px}.n-users-hint-list{padding-left:16px}.n-users-hint-item{color:var(--nu-color-validation-hint,#6c757d);margin-bottom:4px}.n-users-hint-item:last-child{margin-bottom:0}.n-users-logout-link{background:var(--nu-color-error-dark,#b91c1c);border:2px solid transparent;border-color:var(--nu-color-error-dark);border-radius:.5em;color:#fff;padding:.5em 1em;text-decoration:none}.n-users-logout-link:hover{border-color:var(--nu-color-primary)}.n-users-user-card dd{margin:0}.n-users-user-card-actions{display:flex;gap:.5rem;margin-top:1rem}.n-users-user-form{margin:0 auto;max-width:500px}.n-users-form-group input.error{border-color:#dc3545}.n-users-profile-info{background-color:var(--nu-color-bg-primary);border-top-left-radius:.5em;border-top-right-radius:.5em}.n-users-profile-details{font-size:1rem;list-style:none;margin:0;padding:0}.n-users-reset-password-container{background-color:var(--nu-color-bg-primary);border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}@media (max-width:480px){.n-users-login-title{font-size:1.5rem}}.n-users-list-enter-active,.n-users-list-leave-active,.n-users-list-move{transition:all .3s ease}.n-users-list-enter-from,.n-users-list-leave-to{opacity:0;transform:translateX(2rem)}.n-users-list-leave-active{position:absolute}.n-users-list-move{transition-timing-function:ease}
1
+ :root{--nu-color-primary:#3b82f6;--nu-color-primary-dark:#2563eb;--nu-color-primary-light:#60a5fa;--nu-color-white:#fff;--nu-color-gray-50:#f9fafb;--nu-color-gray-500:#6b7280;--nu-color-gray-600:#4b5563;--nu-color-gray-700:#374151;--nu-color-gray-900:#111827;--nu-color-success:#059669;--nu-color-success-light:#f0fdf4;--nu-color-success-border:#9ae6b4;--nu-color-success-text:#047857;--nu-color-error:#dc2626;--nu-color-error-light:#fef2f2;--nu-color-error-border:#fecaca;--nu-color-error-alt:#db5050;--nu-color-error-dark:#b91c1c;--nu-color-border:#e5e7eb;--nu-color-border-light:#d1d5db;--nu-color-border-dark:#ccc;--nu-color-bg-primary:#fff;--nu-color-bg-secondary:#f9fafb;--nu-color-bg-tertiary:#f3f4f6;--nu-color-text-primary:#000;--nu-color-text-secondary:#6b7280;--nu-color-strength-bg:#e9ecef;--nu-color-validation-passed:#15803d;--nu-color-validation-failed:#dc3545;--nu-color-validation-hint:#6c757d}@media (prefers-color-scheme:dark){:root:not(.light){--nu-color-primary:#60a5fa;--nu-color-primary-dark:#3b82f6;--nu-color-primary-light:#93c5fd;--nu-color-white:#000;--nu-color-gray-50:#111827;--nu-color-gray-500:#9ca3af;--nu-color-gray-600:#d1d5db;--nu-color-gray-700:#e5e7eb;--nu-color-gray-900:#f9fafb;--nu-color-success:#10b981;--nu-color-success-light:#064e3b;--nu-color-success-border:#065f46;--nu-color-success-text:#6ee7b7;--nu-color-error:#ef4444;--nu-color-error-light:#450a0a;--nu-color-error-border:#7f1d1d;--nu-color-error-alt:#f87171;--nu-color-error-dark:#dc2626;--nu-color-border:#374151;--nu-color-border-light:#4b5563;--nu-color-border-dark:#6b7280;--nu-color-bg-primary:#111827;--nu-color-bg-secondary:#1f2937;--nu-color-bg-tertiary:#374151;--nu-color-text-primary:#fff;--nu-color-text-secondary:#9ca3af;--nu-color-strength-bg:#374151;--nu-color-validation-passed:#22c55e;--nu-color-validation-failed:#ef4444;--nu-color-validation-hint:#9ca3af}}:root.dark{--nu-color-primary:#60a5fa;--nu-color-primary-dark:#3b82f6;--nu-color-primary-light:#93c5fd;--nu-color-white:#000;--nu-color-gray-50:#111827;--nu-color-gray-500:#9ca3af;--nu-color-gray-600:#d1d5db;--nu-color-gray-700:#e5e7eb;--nu-color-gray-900:#f9fafb;--nu-color-success:#10b981;--nu-color-success-light:#064e3b;--nu-color-success-border:#065f46;--nu-color-success-text:#6ee7b7;--nu-color-error:#ef4444;--nu-color-error-light:#450a0a;--nu-color-error-border:#7f1d1d;--nu-color-error-alt:#f87171;--nu-color-error-dark:#dc2626;--nu-color-border:#374151;--nu-color-border-light:#4b5563;--nu-color-border-dark:#6b7280;--nu-color-bg-primary:#111827;--nu-color-bg-secondary:#1f2937;--nu-color-bg-tertiary:#374151;--nu-color-text-primary:#fff;--nu-color-text-secondary:#9ca3af;--nu-color-strength-bg:#374151;--nu-color-validation-passed:#22c55e;--nu-color-validation-failed:#ef4444;--nu-color-validation-hint:#9ca3af}.n-users-form-group{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem;width:100%}.n-users-form-group.n-users-form-group-narrow{width:90%}.n-users-form-group label,.n-users-form-label{color:var(--nu-color-text-primary,#000);display:block;font-size:1rem;font-weight:500;margin-bottom:.5rem}.n-users-form-group input,.n-users-form-group select,.n-users-form-input{border:1px solid var(--nu-color-border,#ccc);border-radius:.25rem;font-size:1rem;padding:.5rem;transition:border-color .2s,box-shadow .2s;width:100%}.n-users-form-group input:focus,.n-users-form-group select:focus,.n-users-form-input:focus{border-color:var(--nu-color-primary);box-shadow:0 0 0 .1rem rgba(59,130,246,.1);outline:none}.n-users-form-group input:disabled,.n-users-form-input:disabled{background-color:var(--nu-color-bg-secondary,#f9fafb);cursor:not-allowed}.n-users-form-group input.error,.n-users-form-input.error{border-color:var(--nu-color-error,#dc3545)}.n-users-form-group input[type=email],.n-users-form-group input[type=password],.n-users-form-group input[type=text]{background-color:var(--nu-color-bg-secondary);border:1px solid var(--nu-color-border-light);border-radius:.5em;box-sizing:border-box;color:var(--nu-color-gray-700);font-size:.875rem;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-form-group input[type=email]:focus,.n-users-form-group input[type=password]:focus,.n-users-form-group input[type=text]:focus{background-color:var(--nu-color-bg-primary);border-color:var(--nu-color-primary);box-shadow:0 0 0 3px rgba(59,130,246,.1);outline:none}.n-users-form-group input[type=checkbox]{margin-right:.5rem;width:auto}.n-users-password-wrapper{align-items:center;display:flex;position:relative}.n-users-password-wrapper input{padding-right:2.5rem}.n-users-password-toggle{align-items:center;background:none;border:none;color:var(--nu-color-text-secondary,#6b7280);cursor:pointer;display:flex;justify-content:center;padding:.25rem;position:absolute;right:.5rem;transition:color .2s}.n-users-password-toggle:hover{color:var(--nu-color-text-primary,#000)}.n-users-google-btn{align-items:center;border:none;border-radius:.25rem;cursor:pointer;display:inline-flex;font-size:1rem;font-weight:500;gap:8px;justify-content:center;padding:.5rem 1rem;text-decoration:none;transition:background-color .2s,transform .1s}.n-users-google-logo{flex-shrink:0}.n-users-btn,.n-users-cancel-btn,.n-users-delete-btn,.n-users-edit-btn,.n-users-submit-btn{align-self:flex-start;border:none;border-radius:.25rem;cursor:pointer;display:inline-block;font-size:1rem;font-weight:500;padding:.5rem 1rem;text-decoration:none;transition:background-color .2s,transform .1s}.n-users-btn:hover,.n-users-edit-btn:hover,.n-users-submit-btn:hover{background-color:var(--nu-color-primary-dark,#2563eb);transform:translateY(-1px)}.n-users-btn:disabled,.n-users-submit-btn:disabled{cursor:not-allowed;opacity:.6;transform:none}.n-users-btn-primary,.n-users-edit-btn,.n-users-submit-btn{background-color:var(--nu-color-primary,#3b82f6);color:#fff}.n-users-btn-secondary,.n-users-cancel-btn{background-color:var(--nu-color-gray-600,#4b5563);color:#fff}.n-users-cancel-btn:hover{background-color:var(--nu-color-gray-700,#374151)}.n-users-delete-btn{background-color:var(--nu-color-error-dark,#b91c1c);color:#fff}.n-users-delete-btn:hover{background-color:#991b1b}.n-users-login-section button[type=submit],.n-users-register-section button[type=submit],.n-users-reset-password-container button[type=submit],.n-users-user-form button[type=submit],form.n-users-form button[type=submit]{align-items:center;background-color:var(--nu-color-primary);border:1px solid var(--nu-color-primary);border-radius:.5em;color:var(--nu-color-white);cursor:pointer;display:flex;font-size:.875rem;font-weight:500;gap:.5rem;justify-content:center;min-height:44px;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-login-section button[type=submit]:hover:not(:disabled),.n-users-register-section button[type=submit]:hover:not(:disabled),.n-users-reset-password-container button[type=submit]:hover:not(:disabled),.n-users-user-form button[type=submit]:hover:not(:disabled),form.n-users-form button[type=submit]:hover:not(:disabled){background-color:var(--nu-color-primary-dark);border-color:var(--nu-color-primary-dark)}.n-users-login-section button[type=submit]:disabled,.n-users-register-section button[type=submit]:disabled,.n-users-reset-password-container button[type=submit]:disabled,.n-users-user-form button[type=submit]:disabled,form.n-users-form button[type=submit]:disabled{cursor:not-allowed;opacity:.6}.n-users-error-message,.n-users-error-text{background-color:var(--nu-color-error-light,#fef2f2);border:1px solid var(--nu-color-error-border,#fecaca);border-radius:.5rem;color:var(--nu-color-error-dark,#b91c1c);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-success-message{background-color:var(--nu-color-success-light,#f0fdf4);border:1px solid var(--nu-color-success-border,#9ae6b4);border-radius:.5rem;color:var(--nu-color-success-text,#047857);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-grid{display:grid;gap:1rem}.n-users-grid-2{grid-template-columns:1fr 5fr}.n-users-grid-auto{grid-template-columns:repeat(auto-fill,minmax(12em,1fr))}.n-users-form-actions{align-items:center;display:flex;gap:1rem;margin-top:1.5rem}.n-users-loading-spinner{animation:n-users-spin 1s linear infinite;border:2px solid var(--nu-color-white,#fff);border-radius:50%;border-top:2px solid transparent;height:16px;width:16px}@keyframes n-users-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.n-users-card{background-color:var(--nu-color-bg-primary,#fff);border:1px solid var(--nu-color-border,#e5e7eb);border-radius:.5rem;padding:1rem}.n-users-section{margin:0 auto;max-width:42em;padding:1em}.n-users-section-header{border-bottom:.1em solid var(--nu-color-border,#e5e7eb);margin-bottom:1rem;padding-bottom:.5rem}.n-users-form-help{color:var(--nu-color-text-secondary,#6b7280);font-size:.75rem;margin-top:.25rem}.n-users-strength-bar{background-color:var(--nu-color-strength-bg,#e9ecef);border-radius:2px;height:4px;margin-bottom:4px;overflow:hidden;width:100%}.n-users-strength-fill{height:100%;transition:width .3s ease,background-color .3s ease}.n-users-strength-text{font-size:.75rem;font-weight:500}.n-users-validation-container{background-color:#f8f9fa;border:1px solid #e9ecef;border-radius:4px;margin-top:12px;padding:12px}.n-users-container-title{color:#495057;font-size:.875rem;font-weight:600;margin-bottom:8px}.n-users-list-unstyled{list-style:none;margin:0;padding-left:0}.n-users-list-item{align-items:center;display:flex;font-size:.875rem;margin-bottom:6px;transition:color .2s ease}.n-users-list-item:last-child{margin-bottom:0}.n-users-icon{font-weight:700;margin-right:8px;min-width:16px;text-align:center}.n-users-text{flex:1}.n-users-list ul{list-style:none}.n-users-login-section form,.n-users-register-section form,.n-users-reset-password-container form,.n-users-user-form form,form.n-users-form{display:flex;flex-direction:column;gap:1.5rem}.n-users-login-section{background:linear-gradient(135deg,var(--nu-color-bg-primary) 0,var(--nu-color-bg-secondary) 100%);border:1px solid var(--nu-color-border);border-radius:.75em;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);max-width:25rem}.n-users-login-header{margin-bottom:1em;text-align:center}.n-users-login-title{color:var(--nu-color-gray-700);font-size:1.875rem;font-weight:700;line-height:1.2;margin:0 0 .5em}.n-users-login-subtitle{color:var(--nu-color-gray-700);font-size:.875rem;line-height:1.5;margin:0}.n-users-remember-me{align-items:center;display:flex;gap:.5rem}.n-users-remember-me label{color:var(--nu-color-gray-700);font-size:.875rem;margin:0}.n-users-login-footer{margin-top:1em;text-align:center}.n-users-forgot-password{margin:0}.n-users-forgot-link{align-items:center;color:var(--nu-color-primary);display:inline-flex;font-size:.875rem;gap:.5rem;text-decoration:none;transition:color .2s ease-in-out}.n-users-forgot-link:hover:not(.loading){color:var(--nu-color-primary-dark);text-decoration:underline}.n-users-forgot-link.loading{cursor:not-allowed;opacity:.6;pointer-events:none}.n-users-link{color:var(--nu-color-primary);font-size:.875rem;text-decoration:none;transition:color .2s ease-in-out}.n-users-link:hover{color:var(--nu-color-primary-dark);text-decoration:underline}.n-users-link:visited{color:var(--nu-color-primary)}.n-users-link:visited:hover{color:var(--nu-color-primary-dark)}.n-users-password-strength{margin-top:8px}.n-users-validation-rules{margin-top:12px}.n-users-rules-title{margin-bottom:8px}.n-users-rules-list{padding-left:0}.n-users-rule-item{margin-bottom:6px}.n-users-rule-item:last-child{margin-bottom:0}.n-users-rule-passed{color:var(--nu-color-validation-passed,#15803d)}.n-users-rule-failed{color:var(--nu-color-validation-failed,#dc3545)}.n-users-rule-icon{margin-right:8px}.n-users-rule-text{flex:1}.n-users-validation-errors{margin-top:8px}.n-users-error-text:last-child{margin-bottom:0}.n-users-password-hints{margin-top:8px}.n-users-hint-title{margin-bottom:8px}.n-users-hint-list{padding-left:16px}.n-users-hint-item{color:var(--nu-color-validation-hint,#6c757d);margin-bottom:4px}.n-users-hint-item:last-child{margin-bottom:0}.n-users-logout-link{background:var(--nu-color-error-dark,#b91c1c);border:2px solid transparent;border-color:var(--nu-color-error-dark);border-radius:.5em;color:#fff;padding:.5em 1em;text-decoration:none}.n-users-logout-link:hover{border-color:var(--nu-color-primary)}.n-users-user-card dd{margin:0}.n-users-user-card-actions{display:flex;gap:.5rem;margin-top:1rem}.n-users-user-form{margin:0 auto;max-width:500px}.n-users-form-group input.error{border-color:#dc3545}.n-users-profile-info{background-color:var(--nu-color-bg-primary);border-top-left-radius:.5em;border-top-right-radius:.5em}.n-users-profile-details{font-size:1rem;list-style:none;margin:0;padding:0}.n-users-reset-password-container{background-color:var(--nu-color-bg-primary);border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}@media (max-width:480px){.n-users-login-title{font-size:1.5rem}}.n-users-list-enter-active,.n-users-list-leave-active,.n-users-list-move{transition:all .3s ease}.n-users-list-enter-from,.n-users-list-leave-to{opacity:0;transform:translateX(2rem)}.n-users-list-leave-active{position:absolute}.n-users-list-move{transition-timing-function:ease}
@@ -8,6 +8,8 @@ interface Props {
8
8
  emailPlaceholder?: string;
9
9
  passwordLabel?: string;
10
10
  passwordPlaceholder?: string;
11
+ showPasswordLabel?: string;
12
+ hidePasswordLabel?: string;
11
13
  rememberMeLabel?: string;
12
14
  submitLabel?: string;
13
15
  submittingLabel?: string;
@@ -16,6 +16,8 @@ const props = defineProps({
16
16
  emailPlaceholder: { type: String, required: false },
17
17
  passwordLabel: { type: String, required: false },
18
18
  passwordPlaceholder: { type: String, required: false },
19
+ showPasswordLabel: { type: String, required: false },
20
+ hidePasswordLabel: { type: String, required: false },
19
21
  rememberMeLabel: { type: String, required: false },
20
22
  submitLabel: { type: String, required: false },
21
23
  submittingLabel: { type: String, required: false },
@@ -36,6 +38,7 @@ const apiEndpoint = computed(() => props.apiEndpoint || `${nuxtUsers?.apiBasePat
36
38
  const forgotPasswordEndpoint = computed(() => props.forgotPasswordEndpoint || `${nuxtUsers?.apiBasePath}/password/forgot`);
37
39
  const isLoading = ref(false);
38
40
  const isForgotPasswordLoading = ref(false);
41
+ const showPassword = ref(false);
39
42
  const error = ref("");
40
43
  const forgotPasswordMessage = ref("");
41
44
  const formData = ref({
@@ -129,15 +132,63 @@ const handleForgotPassword = async () => {
129
132
  <slot name="password-field">
130
133
  <div class="n-users-form-group">
131
134
  <label for="password">{{ props.passwordLabel || t("login.passwordLabel") }}</label>
132
- <input
133
- id="password"
134
- v-model="formData.password"
135
- type="password"
136
- name="password"
137
- :placeholder="props.passwordPlaceholder || t('login.passwordPlaceholder')"
138
- required
139
- :minlength="passwordValidation?.minLength || 8"
140
- >
135
+ <div class="n-users-password-wrapper">
136
+ <input
137
+ id="password"
138
+ v-model="formData.password"
139
+ :type="showPassword ? 'text' : 'password'"
140
+ name="password"
141
+ :placeholder="props.passwordPlaceholder || t('login.passwordPlaceholder')"
142
+ required
143
+ :minlength="passwordValidation?.minLength || 8"
144
+ >
145
+ <button
146
+ type="button"
147
+ class="n-users-password-toggle"
148
+ :title="showPassword ? props.hidePasswordLabel || t('login.hidePassword') : props.showPasswordLabel || t('login.showPassword')"
149
+ @click="showPassword = !showPassword"
150
+ >
151
+ <svg
152
+ v-if="!showPassword"
153
+ xmlns="http://www.w3.org/2000/svg"
154
+ width="20"
155
+ height="20"
156
+ viewBox="0 0 24 24"
157
+ fill="none"
158
+ stroke="currentColor"
159
+ stroke-width="2"
160
+ stroke-linecap="round"
161
+ stroke-linejoin="round"
162
+ >
163
+ <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
164
+ <line
165
+ x1="1"
166
+ y1="1"
167
+ x2="23"
168
+ y2="23"
169
+ />
170
+ </svg>
171
+ <svg
172
+ v-if="showPassword"
173
+ xmlns="http://www.w3.org/2000/svg"
174
+ width="20"
175
+ height="20"
176
+ viewBox="0 0 24 24"
177
+ fill="none"
178
+ stroke="currentColor"
179
+ stroke-width="2"
180
+ stroke-linecap="round"
181
+ stroke-linejoin="round"
182
+ >
183
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
184
+ <circle
185
+ cx="12"
186
+ cy="12"
187
+ r="3"
188
+ />
189
+ </svg>
190
+ </button>
191
+ </div>
141
192
  </div>
142
193
  </slot>
143
194
 
@@ -8,6 +8,8 @@ interface Props {
8
8
  emailPlaceholder?: string;
9
9
  passwordLabel?: string;
10
10
  passwordPlaceholder?: string;
11
+ showPasswordLabel?: string;
12
+ hidePasswordLabel?: string;
11
13
  rememberMeLabel?: string;
12
14
  submitLabel?: string;
13
15
  submittingLabel?: string;
@@ -25,6 +25,8 @@ export const en = {
25
25
  emailPlaceholder: "Enter your email",
26
26
  passwordLabel: "Password",
27
27
  passwordPlaceholder: "Enter your password",
28
+ showPassword: "Show password",
29
+ hidePassword: "Hide password",
28
30
  rememberMe: "Remember me",
29
31
  submit: "Sign In",
30
32
  submitting: "Signing in...",
@@ -22,6 +22,8 @@ const huBase = {
22
22
  },
23
23
  login: {
24
24
  passwordLabel: "Jelsz\xF3",
25
+ showPassword: "Jelsz\xF3 megjelen\xEDt\xE9se",
26
+ hidePassword: "Jelsz\xF3 elrejt\xE9se",
25
27
  submit: "Bejelentkez\xE9s",
26
28
  submitting: "Bejelentkez\xE9s...",
27
29
  forgotPasswordSending: "K\xFCld\xE9s...",
@@ -0,0 +1,3 @@
1
+ import type { NitroAppPlugin } from 'nitropack';
2
+ declare const plugin: NitroAppPlugin;
3
+ export default plugin;
@@ -0,0 +1,33 @@
1
+ import { useRuntimeConfig } from "#imports";
2
+ const INSECURE_DEFAULT_FROM = /@example\.com>/i;
3
+ const DEFAULT_ETHEREAL_HOST = "smtp.ethereal.email";
4
+ const isTestEnvironment = () => process.env.NODE_ENV === "test" || !!process.env.VITEST;
5
+ const validateMailerConfig = (options) => {
6
+ if (isTestEnvironment()) {
7
+ return;
8
+ }
9
+ const mailer = options.mailer;
10
+ if (!mailer?.host || !mailer?.auth?.user || !mailer?.auth?.pass) {
11
+ return;
12
+ }
13
+ const from = mailer.defaults?.from || '"Nuxt Users" <noreply@example.com>';
14
+ if (!INSECURE_DEFAULT_FROM.test(from)) {
15
+ return;
16
+ }
17
+ const isCustomMailer = mailer.host !== DEFAULT_ETHEREAL_HOST;
18
+ if (!isCustomMailer) {
19
+ return;
20
+ }
21
+ throw new Error(
22
+ '[Nuxt Users] Invalid mailer config: mailer.defaults.from must be set to a valid sender address when using a custom SMTP host. Using noreply@example.com causes password reset emails to bounce (DMARC rejection). Set nuxtUsers.mailer.defaults.from in nuxt.config.ts or NUXT_NUXT_USERS_MAILER_DEFAULTS_FROM env var, e.g. "App" <noreply@yourdomain.com>'
23
+ );
24
+ };
25
+ const plugin = () => {
26
+ const config = useRuntimeConfig();
27
+ const options = config.nuxtUsers;
28
+ if (!options) {
29
+ return;
30
+ }
31
+ validateMailerConfig(options);
32
+ };
33
+ export default plugin;
@@ -167,4 +167,4 @@ const getPasswordStrengthText = (strength) => {
167
167
  }
168
168
  };
169
169
 
170
- export { getPasswordStrengthColor as a, getPasswordStrengthText as b, getPasswordValidationOptions as g, validatePassword as v };
170
+ export { getPasswordStrengthText as a, getPasswordValidationOptions as b, getPasswordStrengthColor as g, validatePassword as v };
@@ -0,0 +1,55 @@
1
+ const defaultOptions = {
2
+ connector: {
3
+ name: "sqlite",
4
+ options: {
5
+ path: "./data/users.sqlite3"
6
+ }
7
+ },
8
+ apiBasePath: "/api/nuxt-users",
9
+ tables: {
10
+ migrations: "migrations",
11
+ users: "users",
12
+ personalAccessTokens: "personal_access_tokens",
13
+ passwordResetTokens: "password_reset_tokens"
14
+ },
15
+ mailer: {
16
+ host: "smtp.ethereal.email",
17
+ port: 587,
18
+ secure: false,
19
+ auth: {
20
+ user: "user@ethereal.email",
21
+ pass: "password"
22
+ },
23
+ defaults: {
24
+ from: '"Nuxt Users Module" <noreply@example.com>'
25
+ }
26
+ },
27
+ passwordResetUrl: "/reset-password",
28
+ emailConfirmationUrl: "/email-confirmation",
29
+ auth: {
30
+ whitelist: [],
31
+ tokenExpiration: 24 * 60,
32
+ rememberMeExpiration: 30,
33
+ permissions: {}
34
+ },
35
+ passwordValidation: {
36
+ minLength: 8,
37
+ requireUppercase: true,
38
+ requireLowercase: true,
39
+ requireNumbers: true,
40
+ requireSpecialChars: true,
41
+ preventCommonPasswords: true
42
+ },
43
+ hardDelete: false,
44
+ locale: {
45
+ default: "en",
46
+ fallbackLocale: "en",
47
+ texts: {}
48
+ },
49
+ tokenCleanupSchedule: "0 2 * * *",
50
+ theme: {
51
+ enabled: true
52
+ }
53
+ };
54
+
55
+ export { defaultOptions as d };
@@ -337,4 +337,4 @@ declare const defaultFieldLabels: {
337
337
  };
338
338
 
339
339
  export { defaultDisplayFields as j, defaultFieldLabels as k };
340
- export type { DisplayFieldsProps as D, GoogleOAuthOptions as G, LoginFormData as L, ModuleOptions as M, PersonalAccessToken as P, RuntimeModuleOptions as R, User as U, UserWithoutPassword as a, PasswordResetToken as b, LoginFormProps as c, ResetPasswordFormProps as d, Permission as e, DatabaseType as f, DatabaseConfig as g, LocaleOptions as h, LocaleMessages as i };
340
+ export type { DatabaseConfig as D, GoogleOAuthOptions as G, LocaleMessages as L, ModuleOptions as M, PasswordResetToken as P, ResetPasswordFormProps as R, User as U, DatabaseType as a, DisplayFieldsProps as b, LocaleOptions as c, LoginFormData as d, LoginFormProps as e, Permission as f, PersonalAccessToken as g, RuntimeModuleOptions as h, UserWithoutPassword as i };
@@ -337,4 +337,4 @@ declare const defaultFieldLabels: {
337
337
  };
338
338
 
339
339
  export { defaultDisplayFields as j, defaultFieldLabels as k };
340
- export type { DisplayFieldsProps as D, GoogleOAuthOptions as G, LoginFormData as L, ModuleOptions as M, PersonalAccessToken as P, RuntimeModuleOptions as R, User as U, UserWithoutPassword as a, PasswordResetToken as b, LoginFormProps as c, ResetPasswordFormProps as d, Permission as e, DatabaseType as f, DatabaseConfig as g, LocaleOptions as h, LocaleMessages as i };
340
+ export type { DatabaseConfig as D, GoogleOAuthOptions as G, LocaleMessages as L, ModuleOptions as M, PasswordResetToken as P, ResetPasswordFormProps as R, User as U, DatabaseType as a, DisplayFieldsProps as b, LocaleOptions as c, LoginFormData as d, LoginFormProps as e, Permission as f, PersonalAccessToken as g, RuntimeModuleOptions as h, UserWithoutPassword as i };
package/dist/utils.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { defaultLocaleMessages, en, hu, huFormal } from '../dist/runtime/locales/index.js';
2
2
  export { getNestedValue, getTranslation } from '../dist/runtime/utils/locale.js';
3
3
  export { deepMerge } from '../dist/runtime/utils/deep-merge.js';
4
- export { g as DatabaseConfig, f as DatabaseType, D as DisplayFieldsProps, G as GoogleOAuthOptions, i as LocaleMessages, h as LocaleOptions, L as LoginFormData, c as LoginFormProps, M as ModuleOptions, b as PasswordResetToken, e as Permission, P as PersonalAccessToken, d as ResetPasswordFormProps, R as RuntimeModuleOptions, U as User, a as UserWithoutPassword, j as defaultDisplayFields, k as defaultFieldLabels } from './shared/nuxt-users.DUmdxjpk.mjs';
4
+ export { D as DatabaseConfig, a as DatabaseType, b as DisplayFieldsProps, G as GoogleOAuthOptions, L as LocaleMessages, c as LocaleOptions, d as LoginFormData, e as LoginFormProps, M as ModuleOptions, P as PasswordResetToken, f as Permission, g as PersonalAccessToken, R as ResetPasswordFormProps, h as RuntimeModuleOptions, U as User, i as UserWithoutPassword, j as defaultDisplayFields, k as defaultFieldLabels } from './shared/nuxt-users.bLYb3Bz5.mjs';
5
5
 
6
6
  interface PasswordValidationResult {
7
7
  isValid: boolean;
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { defaultLocaleMessages, en, hu, huFormal } from '../dist/runtime/locales/index.js';
2
2
  export { getNestedValue, getTranslation } from '../dist/runtime/utils/locale.js';
3
3
  export { deepMerge } from '../dist/runtime/utils/deep-merge.js';
4
- export { g as DatabaseConfig, f as DatabaseType, D as DisplayFieldsProps, G as GoogleOAuthOptions, i as LocaleMessages, h as LocaleOptions, L as LoginFormData, c as LoginFormProps, M as ModuleOptions, b as PasswordResetToken, e as Permission, P as PersonalAccessToken, d as ResetPasswordFormProps, R as RuntimeModuleOptions, U as User, a as UserWithoutPassword, j as defaultDisplayFields, k as defaultFieldLabels } from './shared/nuxt-users.DUmdxjpk.js';
4
+ export { D as DatabaseConfig, a as DatabaseType, b as DisplayFieldsProps, G as GoogleOAuthOptions, L as LocaleMessages, c as LocaleOptions, d as LoginFormData, e as LoginFormProps, M as ModuleOptions, P as PasswordResetToken, f as Permission, g as PersonalAccessToken, R as ResetPasswordFormProps, h as RuntimeModuleOptions, U as User, i as UserWithoutPassword, j as defaultDisplayFields, k as defaultFieldLabels } from './shared/nuxt-users.bLYb3Bz5.js';
5
5
 
6
6
  interface PasswordValidationResult {
7
7
  isValid: boolean;
package/dist/utils.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { a as getPasswordStrengthColor, b as getPasswordStrengthText, g as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.Cvjgn5KJ.mjs';
1
+ export { g as getPasswordStrengthColor, a as getPasswordStrengthText, b as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.9p2ye9P4.mjs';
2
2
  export { defaultLocaleMessages, en, hu, huFormal } from '../dist/runtime/locales/index.js';
3
3
  export { getNestedValue, getTranslation } from '../dist/runtime/utils/locale.js';
4
4
  export { deepMerge } from '../dist/runtime/utils/deep-merge.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-users",
3
- "version": "1.44.0",
3
+ "version": "1.46.0",
4
4
  "description": "A comprehensive user management module for Nuxt 3 and Nuxt 4 applications with authentication, authorization, database support, and CLI tools",
5
5
  "keywords": [
6
6
  "nuxt",
@@ -100,6 +100,7 @@
100
100
  "dependencies": {
101
101
  "bcrypt": "^6.0.0",
102
102
  "citty": "^0.2.0",
103
+ "db0": "^0.3.4",
103
104
  "defu": "^6.1.4",
104
105
  "google-auth-library": "^10.4.0",
105
106
  "nodemailer": "^7.0.5"