nuxt-users 1.48.0 → 1.48.2

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
@@ -5,7 +5,7 @@ import { d as defaultOptions } from './shared/nuxt-users.BsNZbqYb.mjs';
5
5
  import { defu } from 'defu';
6
6
  import { runMigrations, getAppliedMigrations } from '../dist/runtime/server/utils/migrate.js';
7
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';
8
+ import { g as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.Cvjgn5KJ.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';
@@ -392,7 +392,7 @@ const projectInfo = defineCommand({
392
392
  console.log("[Nuxt Users] Migrations:", nuxtUsersConfig.tables?.migrations);
393
393
  console.log();
394
394
  try {
395
- const migrationsTableExists = await checkTableExists(nuxtUsersConfig, "migrations");
395
+ const migrationsTableExists = await checkTableExists(nuxtUsersConfig, nuxtUsersConfig.tables?.migrations || "migrations");
396
396
  console.log("[Nuxt Users] \u{1F4CA} Migration Status:");
397
397
  if (migrationsTableExists) {
398
398
  const appliedMigrations = await getAppliedMigrations(nuxtUsersConfig);
package/dist/module.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { M as ModuleOptions } from './shared/nuxt-users.bLYb3Bz5.mjs';
2
+ import { ModuleOptions } from './utils.mjs';
3
3
  export * from '../dist/runtime/server/internal/index.js';
4
4
 
5
5
  declare const defaultOptions: ModuleOptions;
package/dist/module.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { M as ModuleOptions } from './shared/nuxt-users.bLYb3Bz5.js';
2
+ import { ModuleOptions } from './utils.js';
3
3
  export * from '../dist/runtime/server/internal/index.js';
4
4
 
5
5
  declare const defaultOptions: ModuleOptions;
package/dist/module.json CHANGED
@@ -4,9 +4,9 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0"
6
6
  },
7
- "version": "1.48.0",
7
+ "version": "1.48.2",
8
8
  "builder": {
9
- "@nuxt/module-builder": "1.0.2",
9
+ "@nuxt/module-builder": "1.0.3",
10
10
  "unbuild": "3.6.1"
11
11
  }
12
12
  }
@@ -16,9 +16,9 @@ interface Props {
16
16
  forgotPasswordLabel?: string;
17
17
  forgotPasswordSendingLabel?: string;
18
18
  }
19
- declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_11: {}, __VLS_13: {
19
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_12: {}, __VLS_14: {}, __VLS_16: {}, __VLS_18: {
20
20
  message: string;
21
- }, __VLS_15: {
21
+ }, __VLS_20: {
22
22
  error: string;
23
23
  };
24
24
  type __VLS_Slots = {} & {
@@ -28,15 +28,15 @@ type __VLS_Slots = {} & {
28
28
  } & {
29
29
  'password-field'?: (props: typeof __VLS_5) => any;
30
30
  } & {
31
- 'remember-me'?: (props: typeof __VLS_7) => any;
31
+ 'remember-me'?: (props: typeof __VLS_12) => any;
32
32
  } & {
33
- 'submit-button'?: (props: typeof __VLS_9) => any;
33
+ 'submit-button'?: (props: typeof __VLS_14) => any;
34
34
  } & {
35
- footer?: (props: typeof __VLS_11) => any;
35
+ footer?: (props: typeof __VLS_16) => any;
36
36
  } & {
37
- 'success-message'?: (props: typeof __VLS_13) => any;
37
+ 'success-message'?: (props: typeof __VLS_18) => any;
38
38
  } & {
39
- 'error-message'?: (props: typeof __VLS_15) => any;
39
+ 'error-message'?: (props: typeof __VLS_20) => any;
40
40
  };
41
41
  declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
42
42
  error: (error: string) => any;
@@ -38,7 +38,6 @@ const apiEndpoint = computed(() => props.apiEndpoint || `${nuxtUsers?.apiBasePat
38
38
  const forgotPasswordEndpoint = computed(() => props.forgotPasswordEndpoint || `${nuxtUsers?.apiBasePath}/password/forgot`);
39
39
  const isLoading = ref(false);
40
40
  const isForgotPasswordLoading = ref(false);
41
- const showPassword = ref(false);
42
41
  const error = ref("");
43
42
  const forgotPasswordMessage = ref("");
44
43
  const formData = ref({
@@ -132,63 +131,16 @@ const handleForgotPassword = async () => {
132
131
  <slot name="password-field">
133
132
  <div class="n-users-form-group">
134
133
  <label for="password">{{ props.passwordLabel || t("login.passwordLabel") }}</label>
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>
134
+ <NUsersPasswordInput
135
+ id="password"
136
+ v-model="formData.password"
137
+ name="password"
138
+ :placeholder="props.passwordPlaceholder || t('login.passwordPlaceholder')"
139
+ required
140
+ :minlength="passwordValidation?.minLength || 8"
141
+ :show-password-label="props.showPasswordLabel"
142
+ :hide-password-label="props.hidePasswordLabel"
143
+ />
192
144
  </div>
193
145
  </slot>
194
146
 
@@ -16,9 +16,9 @@ interface Props {
16
16
  forgotPasswordLabel?: string;
17
17
  forgotPasswordSendingLabel?: string;
18
18
  }
19
- declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_11: {}, __VLS_13: {
19
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_12: {}, __VLS_14: {}, __VLS_16: {}, __VLS_18: {
20
20
  message: string;
21
- }, __VLS_15: {
21
+ }, __VLS_20: {
22
22
  error: string;
23
23
  };
24
24
  type __VLS_Slots = {} & {
@@ -28,15 +28,15 @@ type __VLS_Slots = {} & {
28
28
  } & {
29
29
  'password-field'?: (props: typeof __VLS_5) => any;
30
30
  } & {
31
- 'remember-me'?: (props: typeof __VLS_7) => any;
31
+ 'remember-me'?: (props: typeof __VLS_12) => any;
32
32
  } & {
33
- 'submit-button'?: (props: typeof __VLS_9) => any;
33
+ 'submit-button'?: (props: typeof __VLS_14) => any;
34
34
  } & {
35
- footer?: (props: typeof __VLS_11) => any;
35
+ footer?: (props: typeof __VLS_16) => any;
36
36
  } & {
37
- 'success-message'?: (props: typeof __VLS_13) => any;
37
+ 'success-message'?: (props: typeof __VLS_18) => any;
38
38
  } & {
39
- 'error-message'?: (props: typeof __VLS_15) => any;
39
+ 'error-message'?: (props: typeof __VLS_20) => any;
40
40
  };
41
41
  declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
42
42
  error: (error: string) => any;
@@ -0,0 +1,24 @@
1
+ interface Props {
2
+ modelValue?: string;
3
+ id?: string;
4
+ name?: string;
5
+ placeholder?: string;
6
+ required?: boolean;
7
+ minlength?: number;
8
+ disabled?: boolean;
9
+ autocomplete?: string;
10
+ inputClass?: string | Record<string, boolean> | Array<string | Record<string, boolean>>;
11
+ showPasswordLabel?: string;
12
+ hidePasswordLabel?: string;
13
+ }
14
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
15
+ "update:modelValue": (value: string) => any;
16
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
17
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
18
+ }>, {
19
+ disabled: boolean;
20
+ required: boolean;
21
+ modelValue: string;
22
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const _default: typeof __VLS_export;
24
+ export default _default;
@@ -0,0 +1,92 @@
1
+ <script setup>
2
+ import { ref, computed } from "vue";
3
+ import { useNuxtUsersLocale } from "../composables/useNuxtUsersLocale";
4
+ const props = defineProps({
5
+ modelValue: { type: String, required: false, default: "" },
6
+ id: { type: String, required: false },
7
+ name: { type: String, required: false },
8
+ placeholder: { type: String, required: false },
9
+ required: { type: Boolean, required: false, default: false },
10
+ minlength: { type: Number, required: false },
11
+ disabled: { type: Boolean, required: false, default: false },
12
+ autocomplete: { type: String, required: false },
13
+ inputClass: { type: [String, Object, Array], required: false },
14
+ showPasswordLabel: { type: String, required: false },
15
+ hidePasswordLabel: { type: String, required: false }
16
+ });
17
+ const emit = defineEmits(["update:modelValue"]);
18
+ const { t } = useNuxtUsersLocale();
19
+ const showPassword = ref(false);
20
+ const toggleTitle = computed(
21
+ () => showPassword.value ? props.hidePasswordLabel || t("common.hidePassword") : props.showPasswordLabel || t("common.showPassword")
22
+ );
23
+ const handleInput = (event) => {
24
+ const target = event.target;
25
+ emit("update:modelValue", target.value);
26
+ };
27
+ </script>
28
+
29
+ <template>
30
+ <div class="n-users-password-wrapper">
31
+ <input
32
+ :id="id"
33
+ :value="modelValue"
34
+ :type="showPassword ? 'text' : 'password'"
35
+ :name="name"
36
+ :placeholder="placeholder"
37
+ :required="required"
38
+ :minlength="minlength"
39
+ :disabled="disabled"
40
+ :autocomplete="autocomplete"
41
+ :class="inputClass"
42
+ @input="handleInput"
43
+ >
44
+ <button
45
+ type="button"
46
+ class="n-users-password-toggle"
47
+ :title="toggleTitle"
48
+ :disabled="disabled"
49
+ @click="showPassword = !showPassword"
50
+ >
51
+ <svg
52
+ v-if="!showPassword"
53
+ xmlns="http://www.w3.org/2000/svg"
54
+ width="20"
55
+ height="20"
56
+ viewBox="0 0 24 24"
57
+ fill="none"
58
+ stroke="currentColor"
59
+ stroke-width="2"
60
+ stroke-linecap="round"
61
+ stroke-linejoin="round"
62
+ >
63
+ <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" />
64
+ <line
65
+ x1="1"
66
+ y1="1"
67
+ x2="23"
68
+ y2="23"
69
+ />
70
+ </svg>
71
+ <svg
72
+ v-if="showPassword"
73
+ xmlns="http://www.w3.org/2000/svg"
74
+ width="20"
75
+ height="20"
76
+ viewBox="0 0 24 24"
77
+ fill="none"
78
+ stroke="currentColor"
79
+ stroke-width="2"
80
+ stroke-linecap="round"
81
+ stroke-linejoin="round"
82
+ >
83
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
84
+ <circle
85
+ cx="12"
86
+ cy="12"
87
+ r="3"
88
+ />
89
+ </svg>
90
+ </button>
91
+ </div>
92
+ </template>
@@ -0,0 +1,24 @@
1
+ interface Props {
2
+ modelValue?: string;
3
+ id?: string;
4
+ name?: string;
5
+ placeholder?: string;
6
+ required?: boolean;
7
+ minlength?: number;
8
+ disabled?: boolean;
9
+ autocomplete?: string;
10
+ inputClass?: string | Record<string, boolean> | Array<string | Record<string, boolean>>;
11
+ showPasswordLabel?: string;
12
+ hidePasswordLabel?: string;
13
+ }
14
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
15
+ "update:modelValue": (value: string) => any;
16
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
17
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
18
+ }>, {
19
+ disabled: boolean;
20
+ required: boolean;
21
+ modelValue: string;
22
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const _default: typeof __VLS_export;
24
+ export default _default;
@@ -25,9 +25,9 @@ interface RegistrationFormData {
25
25
  password: string;
26
26
  confirmPassword: string;
27
27
  }
28
- declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_16: {}, __VLS_18: {}, __VLS_20: {}, __VLS_22: {
28
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_14: {}, __VLS_21: {}, __VLS_28: {}, __VLS_30: {}, __VLS_32: {
29
29
  message: string;
30
- }, __VLS_24: {
30
+ }, __VLS_34: {
31
31
  error: string;
32
32
  };
33
33
  type __VLS_Slots = {} & {
@@ -39,17 +39,17 @@ type __VLS_Slots = {} & {
39
39
  } & {
40
40
  'password-field'?: (props: typeof __VLS_7) => any;
41
41
  } & {
42
- 'password-strength'?: (props: typeof __VLS_9) => any;
42
+ 'password-strength'?: (props: typeof __VLS_14) => any;
43
43
  } & {
44
- 'confirm-password-field'?: (props: typeof __VLS_16) => any;
44
+ 'confirm-password-field'?: (props: typeof __VLS_21) => any;
45
45
  } & {
46
- 'submit-button'?: (props: typeof __VLS_18) => any;
46
+ 'submit-button'?: (props: typeof __VLS_28) => any;
47
47
  } & {
48
- footer?: (props: typeof __VLS_20) => any;
48
+ footer?: (props: typeof __VLS_30) => any;
49
49
  } & {
50
- 'success-message'?: (props: typeof __VLS_22) => any;
50
+ 'success-message'?: (props: typeof __VLS_32) => any;
51
51
  } & {
52
- 'error-message'?: (props: typeof __VLS_24) => any;
52
+ 'error-message'?: (props: typeof __VLS_34) => any;
53
53
  };
54
54
  declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
55
55
  error: (error: string) => any;
@@ -143,15 +143,14 @@ const handleSubmit = async () => {
143
143
  <slot name="password-field">
144
144
  <div class="n-users-form-group">
145
145
  <label for="password">{{ props.passwordLabel || t("register.passwordLabel") }}</label>
146
- <input
146
+ <NUsersPasswordInput
147
147
  id="password"
148
148
  v-model="formData.password"
149
- type="password"
150
149
  name="password"
151
150
  :placeholder="props.passwordPlaceholder || t('register.passwordPlaceholder')"
152
151
  required
153
152
  :minlength="passwordValidation?.minLength || 8"
154
- >
153
+ />
155
154
  </div>
156
155
  </slot>
157
156
 
@@ -170,15 +169,14 @@ const handleSubmit = async () => {
170
169
  <slot name="confirm-password-field">
171
170
  <div class="n-users-form-group">
172
171
  <label for="confirmPassword">{{ props.confirmPasswordLabel || t("register.confirmPasswordLabel") }}</label>
173
- <input
172
+ <NUsersPasswordInput
174
173
  id="confirmPassword"
175
174
  v-model="formData.confirmPassword"
176
- type="password"
177
175
  name="confirmPassword"
178
176
  :placeholder="props.confirmPasswordPlaceholder || t('register.confirmPasswordPlaceholder')"
179
177
  required
180
- :class="{ 'n-users-input-error': !passwordsMatch }"
181
- >
178
+ :input-class="{ 'n-users-input-error': !passwordsMatch }"
179
+ />
182
180
  <small
183
181
  v-if="!passwordsMatch && formData.confirmPassword"
184
182
  class="n-users-error-text"
@@ -25,9 +25,9 @@ interface RegistrationFormData {
25
25
  password: string;
26
26
  confirmPassword: string;
27
27
  }
28
- declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_16: {}, __VLS_18: {}, __VLS_20: {}, __VLS_22: {
28
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_14: {}, __VLS_21: {}, __VLS_28: {}, __VLS_30: {}, __VLS_32: {
29
29
  message: string;
30
- }, __VLS_24: {
30
+ }, __VLS_34: {
31
31
  error: string;
32
32
  };
33
33
  type __VLS_Slots = {} & {
@@ -39,17 +39,17 @@ type __VLS_Slots = {} & {
39
39
  } & {
40
40
  'password-field'?: (props: typeof __VLS_7) => any;
41
41
  } & {
42
- 'password-strength'?: (props: typeof __VLS_9) => any;
42
+ 'password-strength'?: (props: typeof __VLS_14) => any;
43
43
  } & {
44
- 'confirm-password-field'?: (props: typeof __VLS_16) => any;
44
+ 'confirm-password-field'?: (props: typeof __VLS_21) => any;
45
45
  } & {
46
- 'submit-button'?: (props: typeof __VLS_18) => any;
46
+ 'submit-button'?: (props: typeof __VLS_28) => any;
47
47
  } & {
48
- footer?: (props: typeof __VLS_20) => any;
48
+ footer?: (props: typeof __VLS_30) => any;
49
49
  } & {
50
- 'success-message'?: (props: typeof __VLS_22) => any;
50
+ 'success-message'?: (props: typeof __VLS_32) => any;
51
51
  } & {
52
- 'error-message'?: (props: typeof __VLS_24) => any;
52
+ 'error-message'?: (props: typeof __VLS_34) => any;
53
53
  };
54
54
  declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
55
55
  error: (error: string) => any;
@@ -144,14 +144,14 @@ const handleSubmit = () => {
144
144
  for="currentPassword"
145
145
  class="n-users-form-label"
146
146
  >{{ props.currentPasswordLabel || t("resetPassword.currentPasswordLabel") }}</label>
147
- <input
147
+ <NUsersPasswordInput
148
148
  id="currentPassword"
149
149
  v-model="passwordForm.currentPassword"
150
- type="password"
151
- class="n-users-form-input"
150
+ input-class="n-users-form-input"
152
151
  required
153
152
  :disabled="isPasswordLoading"
154
- >
153
+ autocomplete="current-password"
154
+ />
155
155
  </div>
156
156
 
157
157
  <div class="n-users-form-group">
@@ -159,16 +159,15 @@ const handleSubmit = () => {
159
159
  for="newPassword"
160
160
  class="n-users-form-label"
161
161
  >{{ props.newPasswordLabel || t("resetPassword.newPasswordLabel") }}</label>
162
- <input
162
+ <NUsersPasswordInput
163
163
  id="newPassword"
164
164
  v-model="passwordForm.newPassword"
165
- type="password"
166
- class="n-users-form-input"
165
+ :input-class="['n-users-form-input', { error: passwordValidation.errors.value.length > 0 && !!passwordForm.newPassword }]"
167
166
  required
168
167
  :minlength="moduleOptions.passwordValidation?.minLength || 8"
169
- :class="{ error: passwordValidation.errors.value.length > 0 && passwordForm.newPassword }"
170
168
  :disabled="isPasswordLoading"
171
- >
169
+ autocomplete="new-password"
170
+ />
172
171
 
173
172
  <NUsersPasswordStrengthIndicator
174
173
  :password="passwordForm.newPassword"
@@ -189,14 +188,14 @@ const handleSubmit = () => {
189
188
  for="newPasswordConfirmation"
190
189
  class="n-users-form-label"
191
190
  >{{ props.confirmPasswordLabel || t("resetPassword.confirmPasswordLabel") }}</label>
192
- <input
191
+ <NUsersPasswordInput
193
192
  id="newPasswordConfirmation"
194
193
  v-model="passwordForm.newPasswordConfirmation"
195
- type="password"
196
- class="n-users-form-input"
194
+ input-class="n-users-form-input"
197
195
  required
198
196
  :disabled="isPasswordLoading"
199
- >
197
+ autocomplete="new-password"
198
+ />
200
199
  </div>
201
200
 
202
201
  <div
@@ -118,11 +118,13 @@ const handleSubmit = async () => {
118
118
  <label for="password">
119
119
  {{ isEditMode ? "Password (leave blank to keep current)" : "Password:" }}
120
120
  </label>
121
- <input
121
+ <NUsersPasswordInput
122
+ id="password"
122
123
  v-model="formData.password"
123
- type="password"
124
+ name="password"
124
125
  :required="!isEditMode"
125
- >
126
+ autocomplete="new-password"
127
+ />
126
128
 
127
129
  <NUsersPasswordStrengthIndicator
128
130
  :password="formData.password"
@@ -17,7 +17,9 @@ export const en = {
17
17
  edit: "Edit",
18
18
  delete: "Delete",
19
19
  loading: "Loading...",
20
- error: "Error"
20
+ error: "Error",
21
+ showPassword: "Show password",
22
+ hidePassword: "Hide password"
21
23
  },
22
24
  login: {
23
25
  title: "Welcome Back",
@@ -18,7 +18,9 @@ const huBase = {
18
18
  edit: "Szerkeszt\xE9s",
19
19
  delete: "T\xF6rl\xE9s",
20
20
  loading: "Bet\xF6lt\xE9s...",
21
- error: "Hiba"
21
+ error: "Hiba",
22
+ showPassword: "Jelsz\xF3 megjelen\xEDt\xE9se",
23
+ hidePassword: "Jelsz\xF3 elrejt\xE9se"
22
24
  },
23
25
  login: {
24
26
  passwordLabel: "Jelsz\xF3",
@@ -103,9 +103,10 @@ export const resetPassword = async (token, email, newPassword, options) => {
103
103
  }
104
104
  const now = /* @__PURE__ */ new Date();
105
105
  const currentTimeString = now.toISOString().slice(0, 19).replace("T", " ");
106
- const [datePart, timePart] = validTokenRecord.created_at.split(/[ T]/);
106
+ const createdAtString = validTokenRecord.created_at instanceof Date ? validTokenRecord.created_at.toISOString().slice(0, 19).replace("T", " ") : String(validTokenRecord.created_at);
107
+ const [datePart, timePart] = createdAtString.split(/[ T]/);
107
108
  if (!datePart || !timePart) {
108
- console.log(`[Nuxt Users] Invalid timestamp format for token: ${validTokenRecord.created_at}`);
109
+ console.log(`[Nuxt Users] Invalid timestamp format for token: ${createdAtString}`);
109
110
  return false;
110
111
  }
111
112
  const [year, month, day] = datePart.split("-").map(Number);
@@ -138,7 +139,7 @@ export const deleteExpiredPasswordResetTokens = async (options) => {
138
139
  const passwordResetTokensTable = options.tables.passwordResetTokens;
139
140
  const expirationDate = /* @__PURE__ */ new Date();
140
141
  expirationDate.setHours(expirationDate.getHours() - TOKEN_EXPIRATION_HOURS);
141
- const expirationDateString = expirationDate.toISOString();
142
+ const expirationDateString = expirationDate.toISOString().slice(0, 19).replace("T", " ");
142
143
  await db.sql`
143
144
  DELETE FROM {${passwordResetTokensTable}}
144
145
  WHERE created_at < ${expirationDateString}
@@ -2,7 +2,7 @@ import { useDb } from "./db.js";
2
2
  export const createMigrationsTable = async (options) => {
3
3
  const connectorName = options.connector.name;
4
4
  const db = await useDb(options);
5
- const tableName = "migrations";
5
+ const tableName = options.tables.migrations;
6
6
  console.log(`[Nuxt Users] DB:Create Migrations ${connectorName} Table Creating ${tableName} table with ${connectorName} connector...`);
7
7
  if (connectorName === "sqlite") {
8
8
  await db.sql`
@@ -1,6 +1,6 @@
1
1
  import type { Database } from 'db0';
2
2
  import type { ModuleOptions } from 'nuxt-users/utils';
3
3
  export declare const closeAllDbConnections: () => Promise<void>;
4
- export declare const getConnector: (name: string) => Promise<typeof import("db0/connectors/mysql2").default | typeof import("db0/connectors/postgresql").default | typeof import("db0/connectors/better-sqlite3").default>;
4
+ export declare const getConnector: (name: string) => Promise<typeof import("./mysql-connector.js").default | typeof import("db0/connectors/postgresql").default | typeof import("db0/connectors/better-sqlite3").default>;
5
5
  export declare const useDb: (options: ModuleOptions) => Promise<Database>;
6
6
  export declare const checkTableExists: (options: ModuleOptions, tableName: string) => Promise<boolean>;
@@ -3,8 +3,8 @@ import { isBuildTime } from "./build-time.js";
3
3
  const dbCache = /* @__PURE__ */ new Map();
4
4
  export const closeAllDbConnections = async () => {
5
5
  for (const db of dbCache.values()) {
6
- if (db && typeof db.disconnect === "function") {
7
- await db.disconnect();
6
+ if (db && typeof db.dispose === "function") {
7
+ await db.dispose();
8
8
  }
9
9
  }
10
10
  dbCache.clear();
@@ -13,7 +13,7 @@ export const getConnector = async (name) => {
13
13
  try {
14
14
  switch (name) {
15
15
  case "mysql":
16
- return (await import("db0/connectors/mysql2")).default;
16
+ return (await import("./mysql-connector.js")).default;
17
17
  case "postgresql":
18
18
  return (await import("db0/connectors/postgresql")).default;
19
19
  case "sqlite":
@@ -43,7 +43,7 @@ export const migrations = [
43
43
  export const getAppliedMigrations = async (options) => {
44
44
  const db = await useDb(options);
45
45
  try {
46
- const result = await db.sql`SELECT name FROM migrations ORDER BY id`;
46
+ const result = await db.sql`SELECT name FROM {${options.tables.migrations}} ORDER BY id`;
47
47
  return result.rows.map((row) => row.name);
48
48
  } catch {
49
49
  return [];
@@ -51,7 +51,7 @@ export const getAppliedMigrations = async (options) => {
51
51
  };
52
52
  export const markMigrationAsApplied = async (options, migrationName) => {
53
53
  const db = await useDb(options);
54
- await db.sql`INSERT INTO migrations (name) VALUES (${migrationName})`;
54
+ await db.sql`INSERT INTO {${options.tables.migrations}} (name) VALUES (${migrationName})`;
55
55
  };
56
56
  export const runMigrations = async (options) => {
57
57
  console.log("[Nuxt Users] Starting migration system...");
@@ -0,0 +1,47 @@
1
+ import type { Pool, PoolOptions } from 'mysql2/promise';
2
+ interface ConnectorOptions extends PoolOptions {
3
+ host?: string;
4
+ port?: number;
5
+ user?: string;
6
+ password?: string;
7
+ database?: string;
8
+ }
9
+ interface RawStatement {
10
+ all(...args: unknown[]): Promise<unknown[]>;
11
+ run(...args: unknown[]): Promise<{
12
+ success: boolean;
13
+ }>;
14
+ get(...args: unknown[]): Promise<unknown>;
15
+ }
16
+ declare class BoundableStatement {
17
+ _statement: RawStatement | null;
18
+ constructor(rawStmt: RawStatement | null);
19
+ bind(...params: unknown[]): BoundStatement;
20
+ }
21
+ declare class BoundStatement {
22
+ #private;
23
+ constructor(statement: BoundableStatement, params: unknown[]);
24
+ bind(...params: unknown[]): BoundStatement;
25
+ all(): Promise<unknown[]>;
26
+ run(): Promise<{
27
+ success: boolean;
28
+ }>;
29
+ get(): Promise<unknown>;
30
+ }
31
+ type QueryFn = (sql: string, params?: unknown[]) => Promise<any>;
32
+ declare class StatementWrapper extends BoundableStatement {
33
+ #private;
34
+ constructor(sql: string, query: QueryFn);
35
+ all(...params: unknown[]): Promise<any>;
36
+ run(...params: unknown[]): Promise<any>;
37
+ get(...params: unknown[]): Promise<any>;
38
+ }
39
+ export default function mysqlPoolConnector(opts: ConnectorOptions): {
40
+ name: string;
41
+ dialect: "mysql";
42
+ getInstance: () => Promise<Pool>;
43
+ exec: (sql: string) => Promise<any>;
44
+ prepare: (sql: string) => StatementWrapper;
45
+ dispose: () => Promise<void>;
46
+ };
47
+ export {};
@@ -0,0 +1,85 @@
1
+ class BoundableStatement {
2
+ _statement;
3
+ constructor(rawStmt) {
4
+ this._statement = rawStmt;
5
+ }
6
+ bind(...params) {
7
+ return new BoundStatement(this, params);
8
+ }
9
+ }
10
+ class BoundStatement {
11
+ #statement;
12
+ #params;
13
+ constructor(statement, params) {
14
+ this.#statement = statement;
15
+ this.#params = params;
16
+ }
17
+ bind(...params) {
18
+ return new BoundStatement(this.#statement, params);
19
+ }
20
+ all() {
21
+ return this.#statement._statement.all(...this.#params);
22
+ }
23
+ run() {
24
+ return this.#statement._statement.run(...this.#params);
25
+ }
26
+ get() {
27
+ return this.#statement._statement.get(...this.#params);
28
+ }
29
+ }
30
+ class StatementWrapper extends BoundableStatement {
31
+ #query;
32
+ #sql;
33
+ constructor(sql, query) {
34
+ super(null);
35
+ this.#sql = sql;
36
+ this.#query = query;
37
+ }
38
+ async all(...params) {
39
+ return await this.#query(this.#sql, params);
40
+ }
41
+ async run(...params) {
42
+ const res = await this.#query(this.#sql, params);
43
+ return { success: true, ...res };
44
+ }
45
+ async get(...params) {
46
+ const res = await this.#query(this.#sql, params);
47
+ return res[0];
48
+ }
49
+ }
50
+ export default function mysqlPoolConnector(opts) {
51
+ let _pool = null;
52
+ const getPool = async () => {
53
+ if (_pool) return _pool;
54
+ const { createPool } = await import("mysql2/promise");
55
+ _pool = createPool({
56
+ ...opts,
57
+ enableKeepAlive: true,
58
+ keepAliveInitialDelay: 1e4,
59
+ maxIdle: 5,
60
+ idleTimeout: 6e4,
61
+ waitForConnections: true,
62
+ connectionLimit: 10,
63
+ queueLimit: 0
64
+ });
65
+ return _pool;
66
+ };
67
+ const query = async (sql, params) => {
68
+ const pool = await getPool();
69
+ const [rows] = await pool.query(sql, params);
70
+ return rows;
71
+ };
72
+ return {
73
+ name: "mysql",
74
+ dialect: "mysql",
75
+ getInstance: getPool,
76
+ exec: (sql) => query(sql),
77
+ prepare: (sql) => new StatementWrapper(sql, query),
78
+ dispose: async () => {
79
+ if (_pool) {
80
+ await _pool.end();
81
+ _pool = null;
82
+ }
83
+ }
84
+ };
85
+ }
@@ -167,4 +167,4 @@ const getPasswordStrengthText = (strength) => {
167
167
  }
168
168
  };
169
169
 
170
- export { getPasswordStrengthText as a, getPasswordValidationOptions as b, getPasswordStrengthColor as g, validatePassword as v };
170
+ export { getPasswordStrengthColor as a, getPasswordStrengthText as b, getPasswordValidationOptions as g, validatePassword as v };
package/dist/utils.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { g as getPasswordStrengthColor, a as getPasswordStrengthText, b as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.9p2ye9P4.mjs';
1
+ export { a as getPasswordStrengthColor, b as getPasswordStrengthText, g as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.Cvjgn5KJ.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.48.0",
3
+ "version": "1.48.2",
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",
@@ -1,8 +1,7 @@
1
1
  #!/bin/bash
2
2
 
3
3
  # Configuration
4
- SERVER_HOST="34.159.83.210"
5
- SERVER_USER="sravanam"
4
+ SERVER_HOST="sravanam"
6
5
  REMOTE_DOCS_PATH="/var/www/nuxt-users.webmania.cc"
7
6
  LOCAL_BUILD_PATH="docs/.vitepress/dist"
8
7
 
@@ -28,7 +27,7 @@ tar -czf "$TEMP_TAR" -C "$LOCAL_BUILD_PATH" .
28
27
 
29
28
  # Upload and deploy
30
29
  echo -e "${YELLOW}📤 Uploading to $SERVER_HOST...${NC}"
31
- ssh "$SERVER_USER@$SERVER_HOST" << EOF
30
+ ssh "$SERVER_HOST" << EOF
32
31
  # Create backup of current docs
33
32
  if [ -d "$REMOTE_DOCS_PATH" ]; then
34
33
  echo "📋 Creating backup of current documentation..."
@@ -45,10 +44,10 @@ ssh "$SERVER_USER@$SERVER_HOST" << EOF
45
44
  EOF
46
45
 
47
46
  # Copy the tar file to server
48
- scp "$TEMP_TAR" "$SERVER_USER@$SERVER_HOST:/tmp/"
47
+ scp "$TEMP_TAR" "$SERVER_HOST:/tmp/"
49
48
 
50
49
  # Extract and deploy on server
51
- ssh "$SERVER_USER@$SERVER_HOST" << EOF
50
+ ssh "$SERVER_HOST" << EOF
52
51
  echo "📦 Extracting documentation..."
53
52
  tar -xzf "/tmp/$TEMP_TAR" -C "$REMOTE_DOCS_PATH"
54
53