nuxt-users 1.35.0 → 1.37.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/dist/cli.mjs +38 -1
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +4 -1
  5. package/dist/runtime/components/NUsersEmailConfirmation.d.vue.ts +38 -0
  6. package/dist/runtime/components/NUsersEmailConfirmation.vue.d.ts +3 -2
  7. package/dist/runtime/components/NUsersGoogleLoginButton.d.vue.ts +31 -0
  8. package/dist/runtime/components/NUsersGoogleLoginButton.vue.d.ts +2 -1
  9. package/dist/runtime/components/NUsersList.d.vue.ts +0 -0
  10. package/dist/runtime/components/NUsersLoginForm.d.vue.ts +48 -0
  11. package/dist/runtime/components/NUsersLoginForm.vue.d.ts +5 -4
  12. package/dist/runtime/components/NUsersLogoutLink.d.vue.ts +38 -0
  13. package/dist/runtime/components/NUsersLogoutLink.vue.d.ts +5 -4
  14. package/dist/runtime/components/NUsersPasswordStrengthIndicator.d.vue.ts +13 -0
  15. package/dist/runtime/components/NUsersPasswordStrengthIndicator.vue.d.ts +2 -1
  16. package/dist/runtime/components/NUsersProfileInfo.d.vue.ts +3 -0
  17. package/dist/runtime/components/NUsersProfileInfo.vue.d.ts +2 -1
  18. package/dist/runtime/components/NUsersRegisterForm.d.vue.ts +61 -0
  19. package/dist/runtime/components/NUsersRegisterForm.vue.d.ts +5 -4
  20. package/dist/runtime/components/NUsersResetPasswordForm.d.vue.ts +18 -0
  21. package/dist/runtime/components/NUsersResetPasswordForm.vue.d.ts +4 -3
  22. package/dist/runtime/components/NUsersUserCard.d.vue.ts +44 -0
  23. package/dist/runtime/components/NUsersUserCard.vue.d.ts +3 -2
  24. package/dist/runtime/components/NUsersUserForm.d.vue.ts +15 -0
  25. package/dist/runtime/components/NUsersUserForm.vue.d.ts +2 -1
  26. package/dist/runtime/server/api/nuxt-users/inactive.get.js +1 -1
  27. package/dist/runtime/server/api/nuxt-users/index.get.js +1 -1
  28. package/dist/runtime/server/api/nuxt-users/session/index.post.d.ts +1 -1
  29. package/dist/runtime/server/api/nuxt-users/session/index.post.js +6 -0
  30. package/dist/runtime/server/services/password.js +8 -0
  31. package/dist/runtime/server/services/registration.js +14 -1
  32. package/dist/runtime/server/utils/google-oauth.js +7 -1
  33. package/dist/runtime/server/utils/user.js +24 -3
  34. package/package.json +11 -9
  35. package/scripts/check-peer-dependencies.js +0 -0
  36. package/scripts/post-build.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,100 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## v1.37.0
5
+
6
+ [compare changes](https://github.com/rrd108/nuxt-users/compare/v1.36.0...v1.37.0)
7
+
8
+ ### 🚀 Enhancements
9
+
10
+ - Enhances project info command output ([2d91bd9](https://github.com/rrd108/nuxt-users/commit/2d91bd9))
11
+
12
+ ### 🩹 Fixes
13
+
14
+ - **deps:** Update nuxtjs monorepo to v4 ([0c4b199](https://github.com/rrd108/nuxt-users/commit/0c4b199))
15
+ - Ts errors ([44f5d9e](https://github.com/rrd108/nuxt-users/commit/44f5d9e))
16
+ - Add nuxt builder ([aaa8288](https://github.com/rrd108/nuxt-users/commit/aaa8288))
17
+ - Ts errors ([d488513](https://github.com/rrd108/nuxt-users/commit/d488513))
18
+ - **docs:** Updates last release timestamp ([3d3e0d8](https://github.com/rrd108/nuxt-users/commit/3d3e0d8))
19
+ - Add text to emojis ([e2e0ad5](https://github.com/rrd108/nuxt-users/commit/e2e0ad5))
20
+ - Options merging bug what caused missing migrations error message with mysql ([f2d75ec](https://github.com/rrd108/nuxt-users/commit/f2d75ec))
21
+
22
+ ### 💅 Refactors
23
+
24
+ - Test scripts for efficiency ([8f0a31a](https://github.com/rrd108/nuxt-users/commit/8f0a31a))
25
+
26
+ ### 📖 Documentation
27
+
28
+ - Adds project info command to troubleshooting ([8768090](https://github.com/rrd108/nuxt-users/commit/8768090))
29
+
30
+ ### 🏡 Chore
31
+
32
+ - Add snyk ([9c932c8](https://github.com/rrd108/nuxt-users/commit/9c932c8))
33
+ - Remove unsued import ([04fd61d](https://github.com/rrd108/nuxt-users/commit/04fd61d))
34
+ - Package updates ([3173073](https://github.com/rrd108/nuxt-users/commit/3173073))
35
+ - **release:** V1.36.0 ([92bb026](https://github.com/rrd108/nuxt-users/commit/92bb026))
36
+
37
+ ### ✅ Tests
38
+
39
+ - Fix gauth ([b925cf2](https://github.com/rrd108/nuxt-users/commit/b925cf2))
40
+
41
+ ### ❤️ Contributors
42
+
43
+ - Rrd108 ([@rrd108](https://github.com/rrd108))
44
+
45
+ ## v1.36.0
46
+
47
+ [compare changes](https://github.com/rrd108/nuxt-users/compare/v1.35.0...v1.36.0)
48
+
49
+ ### 🚀 Enhancements
50
+
51
+ - Implement google authentication ([e830872](https://github.com/rrd108/nuxt-users/commit/e830872))
52
+ - Add google auth to the playground ([2b43ca0](https://github.com/rrd108/nuxt-users/commit/2b43ca0))
53
+ - Add migration ([0280eca](https://github.com/rrd108/nuxt-users/commit/0280eca))
54
+ - Unregistered user gets error message ([eefbdf5](https://github.com/rrd108/nuxt-users/commit/eefbdf5))
55
+ - Enhances project info command output ([2d91bd9](https://github.com/rrd108/nuxt-users/commit/2d91bd9))
56
+
57
+ ### 🩹 Fixes
58
+
59
+ - Add api endpoints to public endpoints ([16aefa9](https://github.com/rrd108/nuxt-users/commit/16aefa9))
60
+ - Completes Google OAuth user fetch on client ([6c95b94](https://github.com/rrd108/nuxt-users/commit/6c95b94))
61
+ - **deps:** Update nuxtjs monorepo to v4 ([0c4b199](https://github.com/rrd108/nuxt-users/commit/0c4b199))
62
+ - Ts errors ([44f5d9e](https://github.com/rrd108/nuxt-users/commit/44f5d9e))
63
+ - Add nuxt builder ([aaa8288](https://github.com/rrd108/nuxt-users/commit/aaa8288))
64
+ - Ts errors ([d488513](https://github.com/rrd108/nuxt-users/commit/d488513))
65
+ - **docs:** Updates last release timestamp ([3d3e0d8](https://github.com/rrd108/nuxt-users/commit/3d3e0d8))
66
+
67
+ ### 📖 Documentation
68
+
69
+ - Adds Google OAuth authentication ([463c19f](https://github.com/rrd108/nuxt-users/commit/463c19f))
70
+ - Adds Google OAuth registration ([2e0eebf](https://github.com/rrd108/nuxt-users/commit/2e0eebf))
71
+ - Adds project info command to troubleshooting ([8768090](https://github.com/rrd108/nuxt-users/commit/8768090))
72
+
73
+ ### 🏡 Chore
74
+
75
+ - Remove unused files ([8bd3e58](https://github.com/rrd108/nuxt-users/commit/8bd3e58))
76
+ - Replace googleapis package with google-auth ([0e8e3d4](https://github.com/rrd108/nuxt-users/commit/0e8e3d4))
77
+ - Fix lint errors ([3ed5bcc](https://github.com/rrd108/nuxt-users/commit/3ed5bcc))
78
+ - Update lock ([8cd4a97](https://github.com/rrd108/nuxt-users/commit/8cd4a97))
79
+ - **release:** V1.35.0 ([41cb690](https://github.com/rrd108/nuxt-users/commit/41cb690))
80
+ - Add snyk ([9c932c8](https://github.com/rrd108/nuxt-users/commit/9c932c8))
81
+ - Remove unsued import ([04fd61d](https://github.com/rrd108/nuxt-users/commit/04fd61d))
82
+ - Package updates ([3173073](https://github.com/rrd108/nuxt-users/commit/3173073))
83
+
84
+ ### ✅ Tests
85
+
86
+ - Google OAuth authentication ([7d7bd68](https://github.com/rrd108/nuxt-users/commit/7d7bd68))
87
+ - Add oauth flow test ([b805718](https://github.com/rrd108/nuxt-users/commit/b805718))
88
+ - Fix db setup ([a097c4a](https://github.com/rrd108/nuxt-users/commit/a097c4a))
89
+ - Replace smoke test with middleware test ([7ee1893](https://github.com/rrd108/nuxt-users/commit/7ee1893))
90
+ - Add security checks ([a206962](https://github.com/rrd108/nuxt-users/commit/a206962))
91
+ - Fix ts errors ([d7e6c61](https://github.com/rrd108/nuxt-users/commit/d7e6c61))
92
+ - Fix gauth ([b925cf2](https://github.com/rrd108/nuxt-users/commit/b925cf2))
93
+
94
+ ### ❤️ Contributors
95
+
96
+ - Rrd108 ([@rrd108](https://github.com/rrd108))
97
+
4
98
  ## v1.35.0
5
99
 
6
100
  [compare changes](https://github.com/rrd108/nuxt-users/compare/v1.34.7...v1.35.0)
package/dist/cli.mjs CHANGED
@@ -7,7 +7,8 @@ import { defu } from 'defu';
7
7
  import { runMigrations, createUser as createUser$1, createUsersTable as createUsersTable$1, createPersonalAccessTokensTable as createPersonalAccessTokensTable$1, createPasswordResetTokensTable as createPasswordResetTokensTable$1, createMigrationsTable as createMigrationsTable$1 } from '../dist/runtime/server/utils/index.js';
8
8
  import { g as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.BnOQs2LI.mjs';
9
9
  import { addActiveToUsers as addActiveToUsers$1 } from '../dist/runtime/server/utils/add-active-to-users.js';
10
- import { useDb } from '../dist/runtime/server/utils/db.js';
10
+ import { useDb, checkTableExists } from '../dist/runtime/server/utils/db.js';
11
+ import { getAppliedMigrations } from '../dist/runtime/server/utils/migrate.js';
11
12
  import '../dist/runtime/server/internal/index.js';
12
13
 
13
14
  const getOptionsFromEnv = () => {
@@ -334,9 +335,45 @@ const projectInfo = defineCommand({
334
335
  if (nuxtUsersConfig) {
335
336
  console.log("[Nuxt Users] \u{1F527} Nuxt Users module configuration:");
336
337
  console.log("[Nuxt Users] Database connector:", nuxtUsersConfig.connector?.name);
338
+ if (nuxtUsersConfig.connector?.options) {
339
+ const options = nuxtUsersConfig.connector.options;
340
+ if (options.host) {
341
+ console.log("[Nuxt Users] Database host:", options.host);
342
+ }
343
+ if (options.port) {
344
+ console.log("[Nuxt Users] Database port:", options.port);
345
+ }
346
+ if (options.user) {
347
+ console.log("[Nuxt Users] Database user:", options.user);
348
+ }
349
+ if (options.database) {
350
+ console.log("[Nuxt Users] Database name:", options.database);
351
+ }
352
+ if (options.path) {
353
+ console.log("[Nuxt Users] Database path:", options.path);
354
+ }
355
+ }
337
356
  console.log("[Nuxt Users] Users table:", nuxtUsersConfig.tables?.users);
338
357
  console.log("[Nuxt Users] Personal access tokens table:", nuxtUsersConfig.tables?.personalAccessTokens);
339
358
  console.log("[Nuxt Users] Password reset tokens table:", nuxtUsersConfig.tables?.passwordResetTokens);
359
+ try {
360
+ const migrationsTableExists = await checkTableExists(nuxtUsersConfig, "migrations");
361
+ if (migrationsTableExists) {
362
+ const appliedMigrations = await getAppliedMigrations(nuxtUsersConfig);
363
+ console.log("[Nuxt Users] \u{1F4CA} Migrations:");
364
+ console.log("[Nuxt Users] Migrations table exists: yes \u2705");
365
+ console.log("[Nuxt Users] Applied migrations count:", appliedMigrations.length);
366
+ if (appliedMigrations.length > 0) {
367
+ console.log("[Nuxt Users] Applied migrations:", appliedMigrations.join(", "));
368
+ }
369
+ } else {
370
+ console.log("[Nuxt Users] \u{1F4CA} Migrations:");
371
+ console.log("[Nuxt Users] Migrations table exists: no \u274C");
372
+ console.log('[Nuxt Users] Run "npx nuxt-users migrate" to set up the database');
373
+ }
374
+ } catch (error) {
375
+ console.log("[Nuxt Users] \u26A0\uFE0F Could not check migrations:", error instanceof Error ? error.message : "Unknown error");
376
+ }
340
377
  } else {
341
378
  console.log("[Nuxt Users] \u26A0\uFE0F Nuxt Users module not configured in runtime config");
342
379
  }
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-users",
3
3
  "configKey": "nuxtUsers",
4
- "version": "1.35.0",
4
+ "version": "1.37.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -61,7 +61,10 @@ const module = defineNuxtModule({
61
61
  defaults: defaultOptions,
62
62
  async setup(options, nuxt) {
63
63
  const resolver = createResolver(import.meta.url);
64
- const runtimeConfigOptions = defu(nuxt.options.runtimeConfig.nuxtUsers || {}, options, defaultOptions);
64
+ const { connector: _defaultConnector, ...defaultsWithoutConnector } = defaultOptions;
65
+ const runtimeConfigOptions = defu(nuxt.options.runtimeConfig.nuxtUsers || {}, options, defaultsWithoutConnector);
66
+ const configuredConnector = nuxt.options.runtimeConfig.nuxtUsers?.connector || options.connector;
67
+ runtimeConfigOptions.connector = configuredConnector || defaultOptions.connector;
65
68
  nuxt.options.runtimeConfig.nuxtUsers = {
66
69
  ...runtimeConfigOptions,
67
70
  auth: {
@@ -0,0 +1,38 @@
1
+ interface Props {
2
+ successTitle?: string;
3
+ errorTitle?: string;
4
+ loginButtonText?: string;
5
+ loginUrl?: string;
6
+ showLoginButton?: boolean;
7
+ }
8
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_11: {}, __VLS_13: {};
9
+ type __VLS_Slots = {} & {
10
+ 'success-icon'?: (props: typeof __VLS_1) => any;
11
+ } & {
12
+ 'success-content'?: (props: typeof __VLS_3) => any;
13
+ } & {
14
+ 'success-actions'?: (props: typeof __VLS_5) => any;
15
+ } & {
16
+ 'error-icon'?: (props: typeof __VLS_7) => any;
17
+ } & {
18
+ 'error-content'?: (props: typeof __VLS_9) => any;
19
+ } & {
20
+ 'error-actions'?: (props: typeof __VLS_11) => any;
21
+ } & {
22
+ 'loading-content'?: (props: typeof __VLS_13) => any;
23
+ };
24
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
25
+ successTitle: string;
26
+ errorTitle: string;
27
+ loginButtonText: string;
28
+ loginUrl: string;
29
+ showLoginButton: boolean;
30
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
+ declare const _default: typeof __VLS_export;
33
+ export default _default;
34
+ type __VLS_WithSlots<T, S> = T & {
35
+ new (): {
36
+ $slots: S;
37
+ };
38
+ };
@@ -21,14 +21,15 @@ type __VLS_Slots = {} & {
21
21
  } & {
22
22
  'loading-content'?: (props: typeof __VLS_13) => any;
23
23
  };
24
- declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
24
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
25
25
  successTitle: string;
26
26
  errorTitle: string;
27
27
  loginButtonText: string;
28
28
  loginUrl: string;
29
29
  showLoginButton: boolean;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
31
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
+ declare const _default: typeof __VLS_export;
32
33
  export default _default;
33
34
  type __VLS_WithSlots<T, S> = T & {
34
35
  new (): {
@@ -0,0 +1,31 @@
1
+ interface Props {
2
+ /**
3
+ * Custom redirect endpoint for Google OAuth
4
+ * @default '/api/nuxt-users/auth/google/redirect'
5
+ */
6
+ redirectEndpoint?: string;
7
+ /**
8
+ * Button text
9
+ * @default 'Continue with Google'
10
+ */
11
+ buttonText?: string;
12
+ /**
13
+ * Show Google logo in button
14
+ * @default true
15
+ */
16
+ showLogo?: boolean;
17
+ /**
18
+ * Custom CSS class for button
19
+ */
20
+ class?: string;
21
+ }
22
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
23
+ click: () => any;
24
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
25
+ onClick?: (() => any) | undefined;
26
+ }>, {
27
+ buttonText: string;
28
+ showLogo: boolean;
29
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ declare const _default: typeof __VLS_export;
31
+ export default _default;
@@ -19,7 +19,7 @@ interface Props {
19
19
  */
20
20
  class?: string;
21
21
  }
22
- declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
22
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
23
23
  click: () => any;
24
24
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
25
25
  onClick?: (() => any) | undefined;
@@ -27,4 +27,5 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
27
27
  buttonText: string;
28
28
  showLogo: boolean;
29
29
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ declare const _default: typeof __VLS_export;
30
31
  export default _default;
File without changes
@@ -0,0 +1,48 @@
1
+ interface Props {
2
+ apiEndpoint?: string;
3
+ forgotPasswordEndpoint?: string;
4
+ redirectTo?: string;
5
+ }
6
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_11: {}, __VLS_13: {
7
+ message: string;
8
+ }, __VLS_15: {
9
+ error: string;
10
+ };
11
+ type __VLS_Slots = {} & {
12
+ header?: (props: typeof __VLS_1) => any;
13
+ } & {
14
+ 'email-field'?: (props: typeof __VLS_3) => any;
15
+ } & {
16
+ 'password-field'?: (props: typeof __VLS_5) => any;
17
+ } & {
18
+ 'remember-me'?: (props: typeof __VLS_7) => any;
19
+ } & {
20
+ 'submit-button'?: (props: typeof __VLS_9) => any;
21
+ } & {
22
+ footer?: (props: typeof __VLS_11) => any;
23
+ } & {
24
+ 'success-message'?: (props: typeof __VLS_13) => any;
25
+ } & {
26
+ 'error-message'?: (props: typeof __VLS_15) => any;
27
+ };
28
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
29
+ error: (error: string) => any;
30
+ success: (user: UserWithoutPassword, rememberMe: boolean) => any;
31
+ submit: (data: LoginFormData) => any;
32
+ "forgot-password-error": (error: string) => any;
33
+ "forgot-password-success": () => any;
34
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
35
+ onError?: ((error: string) => any) | undefined;
36
+ onSuccess?: ((user: UserWithoutPassword, rememberMe: boolean) => any) | undefined;
37
+ onSubmit?: ((data: LoginFormData) => any) | undefined;
38
+ "onForgot-password-error"?: ((error: string) => any) | undefined;
39
+ "onForgot-password-success"?: (() => any) | undefined;
40
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
41
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
42
+ declare const _default: typeof __VLS_export;
43
+ export default _default;
44
+ type __VLS_WithSlots<T, S> = T & {
45
+ new (): {
46
+ $slots: S;
47
+ };
48
+ };
@@ -25,20 +25,21 @@ type __VLS_Slots = {} & {
25
25
  } & {
26
26
  'error-message'?: (props: typeof __VLS_15) => any;
27
27
  };
28
- declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
29
- success: (user: UserWithoutPassword, rememberMe: boolean) => any;
28
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
30
29
  error: (error: string) => any;
30
+ success: (user: UserWithoutPassword, rememberMe: boolean) => any;
31
31
  submit: (data: LoginFormData) => any;
32
32
  "forgot-password-error": (error: string) => any;
33
33
  "forgot-password-success": () => any;
34
34
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
35
- onSuccess?: ((user: UserWithoutPassword, rememberMe: boolean) => any) | undefined;
36
35
  onError?: ((error: string) => any) | undefined;
36
+ onSuccess?: ((user: UserWithoutPassword, rememberMe: boolean) => any) | undefined;
37
37
  onSubmit?: ((data: LoginFormData) => any) | undefined;
38
38
  "onForgot-password-error"?: ((error: string) => any) | undefined;
39
39
  "onForgot-password-success"?: (() => any) | undefined;
40
40
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
41
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
41
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
42
+ declare const _default: typeof __VLS_export;
42
43
  export default _default;
43
44
  type __VLS_WithSlots<T, S> = T & {
44
45
  new (): {
@@ -0,0 +1,38 @@
1
+ interface LogoutLinkProps {
2
+ redirectTo?: string;
3
+ linkText?: string;
4
+ confirmMessage?: string;
5
+ class?: string;
6
+ style?: string | Record<string, string | number>;
7
+ linkClass?: string;
8
+ linkStyle?: string | Record<string, string | number>;
9
+ errorClass?: string;
10
+ errorStyle?: string | Record<string, string | number>;
11
+ containerClass?: string;
12
+ containerStyle?: string | Record<string, string | number>;
13
+ }
14
+ declare var __VLS_1: {};
15
+ type __VLS_Slots = {} & {
16
+ default?: (props: typeof __VLS_1) => any;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<LogoutLinkProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
19
+ error: (error: string) => any;
20
+ success: () => any;
21
+ click: () => any;
22
+ }, string, import("vue").PublicProps, Readonly<LogoutLinkProps> & Readonly<{
23
+ onError?: ((error: string) => any) | undefined;
24
+ onSuccess?: (() => any) | undefined;
25
+ onClick?: (() => any) | undefined;
26
+ }>, {
27
+ redirectTo: string;
28
+ linkText: string;
29
+ confirmMessage: string;
30
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
+ declare const _default: typeof __VLS_export;
33
+ export default _default;
34
+ type __VLS_WithSlots<T, S> = T & {
35
+ new (): {
36
+ $slots: S;
37
+ };
38
+ };
@@ -15,20 +15,21 @@ declare var __VLS_1: {};
15
15
  type __VLS_Slots = {} & {
16
16
  default?: (props: typeof __VLS_1) => any;
17
17
  };
18
- declare const __VLS_component: import("vue").DefineComponent<LogoutLinkProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
19
- success: () => any;
18
+ declare const __VLS_base: import("vue").DefineComponent<LogoutLinkProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
20
19
  error: (error: string) => any;
20
+ success: () => any;
21
21
  click: () => any;
22
22
  }, string, import("vue").PublicProps, Readonly<LogoutLinkProps> & Readonly<{
23
- onSuccess?: (() => any) | undefined;
24
23
  onError?: ((error: string) => any) | undefined;
24
+ onSuccess?: (() => any) | undefined;
25
25
  onClick?: (() => any) | undefined;
26
26
  }>, {
27
27
  redirectTo: string;
28
28
  linkText: string;
29
29
  confirmMessage: string;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
31
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
+ declare const _default: typeof __VLS_export;
32
33
  export default _default;
33
34
  type __VLS_WithSlots<T, S> = T & {
34
35
  new (): {
@@ -0,0 +1,13 @@
1
+ import type { PasswordValidationResult } from 'nuxt-users/utils';
2
+ interface Props {
3
+ password: string;
4
+ validationResult: PasswordValidationResult | null;
5
+ showHints?: boolean;
6
+ showRules?: boolean;
7
+ }
8
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
9
+ showHints: boolean;
10
+ showRules: boolean;
11
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -5,8 +5,9 @@ interface Props {
5
5
  showHints?: boolean;
6
6
  showRules?: boolean;
7
7
  }
8
- declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
8
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
9
9
  showHints: boolean;
10
10
  showRules: boolean;
11
11
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
12
13
  export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -1,2 +1,3 @@
1
- declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
2
3
  export default _default;
@@ -0,0 +1,61 @@
1
+ import type { UserWithoutPassword } from 'nuxt-users/utils';
2
+ interface Props {
3
+ apiEndpoint?: string;
4
+ redirectTo?: string;
5
+ loginLink?: string;
6
+ }
7
+ interface RegistrationFormData {
8
+ email: string;
9
+ name: string;
10
+ password: string;
11
+ confirmPassword: string;
12
+ }
13
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_16: {}, __VLS_18: {}, __VLS_20: {}, __VLS_22: {
14
+ message: string;
15
+ }, __VLS_24: {
16
+ error: string;
17
+ };
18
+ type __VLS_Slots = {} & {
19
+ header?: (props: typeof __VLS_1) => any;
20
+ } & {
21
+ 'name-field'?: (props: typeof __VLS_3) => any;
22
+ } & {
23
+ 'email-field'?: (props: typeof __VLS_5) => any;
24
+ } & {
25
+ 'password-field'?: (props: typeof __VLS_7) => any;
26
+ } & {
27
+ 'password-strength'?: (props: typeof __VLS_9) => any;
28
+ } & {
29
+ 'confirm-password-field'?: (props: typeof __VLS_16) => any;
30
+ } & {
31
+ 'submit-button'?: (props: typeof __VLS_18) => any;
32
+ } & {
33
+ footer?: (props: typeof __VLS_20) => any;
34
+ } & {
35
+ 'success-message'?: (props: typeof __VLS_22) => any;
36
+ } & {
37
+ 'error-message'?: (props: typeof __VLS_24) => any;
38
+ };
39
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
40
+ error: (error: string) => any;
41
+ success: (data: {
42
+ user: Omit<UserWithoutPassword, "active">;
43
+ message: string;
44
+ }) => any;
45
+ submit: (data: RegistrationFormData) => any;
46
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
47
+ onError?: ((error: string) => any) | undefined;
48
+ onSuccess?: ((data: {
49
+ user: Omit<UserWithoutPassword, "active">;
50
+ message: string;
51
+ }) => any) | undefined;
52
+ onSubmit?: ((data: RegistrationFormData) => any) | undefined;
53
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
54
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
55
+ declare const _default: typeof __VLS_export;
56
+ export default _default;
57
+ type __VLS_WithSlots<T, S> = T & {
58
+ new (): {
59
+ $slots: S;
60
+ };
61
+ };
@@ -36,22 +36,23 @@ type __VLS_Slots = {} & {
36
36
  } & {
37
37
  'error-message'?: (props: typeof __VLS_24) => any;
38
38
  };
39
- declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
39
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
40
+ error: (error: string) => any;
40
41
  success: (data: {
41
42
  user: Omit<UserWithoutPassword, "active">;
42
43
  message: string;
43
44
  }) => any;
44
- error: (error: string) => any;
45
45
  submit: (data: RegistrationFormData) => any;
46
46
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
47
+ onError?: ((error: string) => any) | undefined;
47
48
  onSuccess?: ((data: {
48
49
  user: Omit<UserWithoutPassword, "active">;
49
50
  message: string;
50
51
  }) => any) | undefined;
51
- onError?: ((error: string) => any) | undefined;
52
52
  onSubmit?: ((data: RegistrationFormData) => any) | undefined;
53
53
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
54
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
54
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
55
+ declare const _default: typeof __VLS_export;
55
56
  export default _default;
56
57
  type __VLS_WithSlots<T, S> = T & {
57
58
  new (): {
@@ -0,0 +1,18 @@
1
+ interface Props {
2
+ updatePasswordEndpoint?: string;
3
+ resetPasswordEndpoint?: string;
4
+ redirectTo?: string;
5
+ }
6
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
7
+ error: (error: string) => any;
8
+ success: (user: UserWithoutPassword) => any;
9
+ "password-error": (error: string) => any;
10
+ "password-updated": () => any;
11
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
12
+ onError?: ((error: string) => any) | undefined;
13
+ onSuccess?: ((user: UserWithoutPassword) => any) | undefined;
14
+ "onPassword-error"?: ((error: string) => any) | undefined;
15
+ "onPassword-updated"?: (() => any) | undefined;
16
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
@@ -3,15 +3,16 @@ interface Props {
3
3
  resetPasswordEndpoint?: string;
4
4
  redirectTo?: string;
5
5
  }
6
- declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
7
- success: (user: UserWithoutPassword) => any;
6
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
8
7
  error: (error: string) => any;
8
+ success: (user: UserWithoutPassword) => any;
9
9
  "password-error": (error: string) => any;
10
10
  "password-updated": () => any;
11
11
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
12
- onSuccess?: ((user: UserWithoutPassword) => any) | undefined;
13
12
  onError?: ((error: string) => any) | undefined;
13
+ onSuccess?: ((user: UserWithoutPassword) => any) | undefined;
14
14
  "onPassword-error"?: ((error: string) => any) | undefined;
15
15
  "onPassword-updated"?: (() => any) | undefined;
16
16
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: typeof __VLS_export;
17
18
  export default _default;
@@ -0,0 +1,44 @@
1
+ import { type User } from 'nuxt-users/utils';
2
+ interface Props {
3
+ user: User;
4
+ index: number;
5
+ displayFields?: string[];
6
+ fieldLabels?: Record<string, string>;
7
+ }
8
+ declare var __VLS_1: {
9
+ user: User;
10
+ index: number;
11
+ }, __VLS_3: {
12
+ canEdit: any;
13
+ editUser: () => Promise<void>;
14
+ user: User;
15
+ }, __VLS_5: {
16
+ canDelete: any;
17
+ deleteUser: () => Promise<void>;
18
+ user: User;
19
+ };
20
+ type __VLS_Slots = {} & {
21
+ userCard?: (props: typeof __VLS_1) => any;
22
+ } & {
23
+ editButton?: (props: typeof __VLS_3) => any;
24
+ } & {
25
+ deleteButton?: (props: typeof __VLS_5) => any;
26
+ };
27
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
28
+ delete: (user: User) => void;
29
+ editClick: (user: User) => void;
30
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
31
+ onDelete?: ((user: User) => any) | undefined;
32
+ onEditClick?: ((user: User) => any) | undefined;
33
+ }>, {
34
+ displayFields: string[];
35
+ fieldLabels: Record<string, string>;
36
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
37
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
38
+ declare const _default: typeof __VLS_export;
39
+ export default _default;
40
+ type __VLS_WithSlots<T, S> = T & {
41
+ new (): {
42
+ $slots: S;
43
+ };
44
+ };
@@ -24,7 +24,7 @@ type __VLS_Slots = {} & {
24
24
  } & {
25
25
  deleteButton?: (props: typeof __VLS_5) => any;
26
26
  };
27
- declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
27
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
28
28
  delete: (user: User) => void;
29
29
  editClick: (user: User) => void;
30
30
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
@@ -34,7 +34,8 @@ declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {},
34
34
  displayFields: string[];
35
35
  fieldLabels: Record<string, string>;
36
36
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
37
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
37
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
38
+ declare const _default: typeof __VLS_export;
38
39
  export default _default;
39
40
  type __VLS_WithSlots<T, S> = T & {
40
41
  new (): {
@@ -0,0 +1,15 @@
1
+ import type { User } from 'nuxt-users/utils';
2
+ interface Props {
3
+ user?: User | null;
4
+ }
5
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
6
+ error: (error: unknown) => any;
7
+ cancel: () => any;
8
+ submit: (userData: User) => any;
9
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
10
+ onError?: ((error: unknown) => any) | undefined;
11
+ onCancel?: (() => any) | undefined;
12
+ onSubmit?: ((userData: User) => any) | undefined;
13
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
@@ -2,7 +2,7 @@ import type { User } from 'nuxt-users/utils';
2
2
  interface Props {
3
3
  user?: User | null;
4
4
  }
5
- declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
5
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
6
6
  error: (error: unknown) => any;
7
7
  cancel: () => any;
8
8
  submit: (userData: User) => any;
@@ -11,4 +11,5 @@ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, imp
11
11
  onCancel?: (() => any) | undefined;
12
12
  onSubmit?: ((userData: User) => any) | undefined;
13
13
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const _default: typeof __VLS_export;
14
15
  export default _default;
@@ -19,7 +19,7 @@ export default defineEventHandler(async (event) => {
19
19
  }
20
20
  try {
21
21
  const countResult = await db.sql`SELECT COUNT(*) as total FROM {${usersTable}} WHERE active = FALSE`;
22
- const total = countResult.rows[0].total;
22
+ const total = countResult.rows[0]?.total ?? 0;
23
23
  const usersResult = await db.sql`
24
24
  SELECT id, email, name, role, created_at, updated_at
25
25
  FROM {${usersTable}}
@@ -19,7 +19,7 @@ export default defineEventHandler(async (event) => {
19
19
  }
20
20
  try {
21
21
  const countResult = await db.sql`SELECT COUNT(*) as total FROM {${usersTable}} WHERE active = TRUE`;
22
- const total = countResult.rows[0].total;
22
+ const total = countResult.rows[0]?.total ?? 0;
23
23
  const usersResult = await db.sql`
24
24
  SELECT id, email, name, role, created_at, updated_at
25
25
  FROM {${usersTable}}
@@ -1,4 +1,4 @@
1
1
  declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
- user: User;
2
+ user: any;
3
3
  }>>;
4
4
  export default _default;
@@ -25,6 +25,12 @@ export default defineEventHandler(async (event) => {
25
25
  });
26
26
  }
27
27
  const user = userResult.rows[0];
28
+ if (!user) {
29
+ throw createError({
30
+ statusCode: 401,
31
+ statusMessage: "Invalid email or password"
32
+ });
33
+ }
28
34
  if (!user.active) {
29
35
  throw createError({
30
36
  statusCode: 403,
@@ -104,8 +104,16 @@ export const resetPassword = async (token, email, newPassword, options) => {
104
104
  const now = /* @__PURE__ */ new Date();
105
105
  const currentTimeString = now.toISOString().slice(0, 19).replace("T", " ");
106
106
  const [datePart, timePart] = validTokenRecord.created_at.split(/[ T]/);
107
+ if (!datePart || !timePart) {
108
+ console.log(`[Nuxt Users] Invalid timestamp format for token: ${validTokenRecord.created_at}`);
109
+ return false;
110
+ }
107
111
  const [year, month, day] = datePart.split("-").map(Number);
108
112
  const [hour, minute, second] = timePart.split(":").map(Number);
113
+ if (!year || !month || !day || hour === void 0 || minute === void 0 || second === void 0) {
114
+ console.log("[Nuxt Users] Invalid timestamp components");
115
+ return false;
116
+ }
109
117
  let expirationHour = hour + TOKEN_EXPIRATION_HOURS;
110
118
  let expirationDay = day;
111
119
  const expirationMonth = month;
@@ -32,6 +32,9 @@ export const registerUser = async (userData, options, baseUrl) => {
32
32
  throw new Error("Failed to create user.");
33
33
  }
34
34
  const user = result.rows[0];
35
+ if (!user) {
36
+ throw new Error("Failed to retrieve created user.");
37
+ }
35
38
  const passwordResetTokensTable = options.tables.passwordResetTokens;
36
39
  await db.sql`
37
40
  INSERT INTO {${passwordResetTokensTable}} (email, token, created_at)
@@ -149,8 +152,16 @@ export const confirmUserEmail = async (token, email, options) => {
149
152
  const currentTimeString = now.toISOString().slice(0, 19).replace("T", " ");
150
153
  const createdAtString = validTokenRecord.created_at instanceof Date ? validTokenRecord.created_at.toISOString().slice(0, 19).replace("T", " ") : String(validTokenRecord.created_at);
151
154
  const [datePart, timePart] = createdAtString.split(/[ T]/);
155
+ if (!datePart || !timePart) {
156
+ console.log(`[Nuxt Users] Invalid timestamp format for token: ${createdAtString}`);
157
+ return false;
158
+ }
152
159
  const [year, month, day] = datePart.split("-").map(Number);
153
160
  const [hour, minute, second] = timePart.split(":").map(Number);
161
+ if (!year || !month || !day || hour === void 0 || minute === void 0 || second === void 0) {
162
+ console.log("[Nuxt Users] Invalid timestamp components");
163
+ return false;
164
+ }
154
165
  let expirationHour = hour + TOKEN_EXPIRATION_HOURS;
155
166
  let expirationDay = day;
156
167
  let expirationMonth = month;
@@ -162,7 +173,9 @@ export const confirmUserEmail = async (token, email, options) => {
162
173
  if (expirationYear % 4 === 0 && (expirationYear % 100 !== 0 || expirationYear % 400 === 0)) {
163
174
  daysInMonth[1] = 29;
164
175
  }
165
- if (expirationDay > daysInMonth[expirationMonth - 1]) {
176
+ const monthIndex = expirationMonth - 1;
177
+ const daysInCurrentMonth = daysInMonth[monthIndex];
178
+ if (daysInCurrentMonth && expirationDay > daysInCurrentMonth) {
166
179
  expirationDay = 1;
167
180
  expirationMonth++;
168
181
  if (expirationMonth > 12) {
@@ -54,6 +54,9 @@ export async function findOrCreateGoogleUser(googleUser, moduleOptions) {
54
54
  `;
55
55
  if (userResult.rows.length > 0) {
56
56
  const user = userResult.rows[0];
57
+ if (!user) {
58
+ return null;
59
+ }
57
60
  if (user.profile_picture !== googleUser.picture) {
58
61
  await db.sql`
59
62
  UPDATE {${usersTable}}
@@ -70,6 +73,9 @@ export async function findOrCreateGoogleUser(googleUser, moduleOptions) {
70
73
  `;
71
74
  if (userResult.rows.length > 0) {
72
75
  const user = userResult.rows[0];
76
+ if (!user) {
77
+ return null;
78
+ }
73
79
  await db.sql`
74
80
  UPDATE {${usersTable}}
75
81
  SET google_id = ${googleUser.id},
@@ -105,7 +111,7 @@ export async function findOrCreateGoogleUser(googleUser, moduleOptions) {
105
111
  SELECT * FROM {${usersTable}}
106
112
  WHERE google_id = ${googleUser.id}
107
113
  `;
108
- return createdUserResult.rows[0];
114
+ return createdUserResult.rows[0] ?? null;
109
115
  }
110
116
  export async function createAuthTokenForUser(user, moduleOptions, rememberMe = false) {
111
117
  const db = await useDb(moduleOptions);
@@ -20,6 +20,9 @@ export const createUser = async (userData, options) => {
20
20
  throw new Error("Failed to retrieve created user.");
21
21
  }
22
22
  const user = result.rows[0];
23
+ if (!user) {
24
+ throw new Error("Failed to retrieve created user.");
25
+ }
23
26
  return {
24
27
  id: user.id,
25
28
  email: user.email,
@@ -38,6 +41,9 @@ export const findUserByEmail = async (email, options) => {
38
41
  return null;
39
42
  }
40
43
  const user = result.rows[0];
44
+ if (!user) {
45
+ return null;
46
+ }
41
47
  return {
42
48
  id: user.id,
43
49
  email: user.email,
@@ -57,6 +63,9 @@ export const findUserById = async (id, options, withPass = false) => {
57
63
  return null;
58
64
  }
59
65
  const user = result.rows[0];
66
+ if (!user) {
67
+ return null;
68
+ }
60
69
  const normalizedUser = {
61
70
  ...user,
62
71
  created_at: typeof user.created_at === "object" ? user.created_at.toISOString() : user.created_at,
@@ -126,7 +135,8 @@ export const hasAnyUsers = async (options) => {
126
135
  try {
127
136
  const db = await useDb(options);
128
137
  const users = await db.sql`SELECT COUNT(*) as count FROM {${options.tables.users}}`;
129
- return users.rows?.[0]?.count > 0;
138
+ const firstRow = users.rows?.[0];
139
+ return firstRow ? firstRow.count > 0 : false;
130
140
  } catch {
131
141
  return false;
132
142
  }
@@ -143,7 +153,11 @@ export const getCurrentUserFromToken = async (token, options, withPass = false)
143
153
  if (tokenResult.rows.length === 0) {
144
154
  return null;
145
155
  }
146
- const userId = tokenResult.rows[0].tokenable_id;
156
+ const tokenRow = tokenResult.rows[0];
157
+ if (!tokenRow) {
158
+ return null;
159
+ }
160
+ const userId = tokenRow.tokenable_id;
147
161
  await db.sql`
148
162
  UPDATE {${personalAccessTokensTable}}
149
163
  SET last_used_at = CURRENT_TIMESTAMP
@@ -157,6 +171,9 @@ export const getCurrentUserFromToken = async (token, options, withPass = false)
157
171
  return null;
158
172
  }
159
173
  const user = userResult.rows[0];
174
+ if (!user) {
175
+ return null;
176
+ }
160
177
  if (!user.active) {
161
178
  return null;
162
179
  }
@@ -217,6 +234,10 @@ export const getLastLoginTime = async (userId, options) => {
217
234
  if (result.rows.length === 0) {
218
235
  return null;
219
236
  }
220
- const lastLogin = result.rows[0].created_at;
237
+ const resultRow = result.rows[0];
238
+ if (!resultRow) {
239
+ return null;
240
+ }
241
+ const lastLogin = resultRow.created_at;
221
242
  return lastLogin instanceof Date ? lastLogin.toISOString() : lastLogin;
222
243
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-users",
3
- "version": "1.35.0",
3
+ "version": "1.37.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",
@@ -67,7 +67,8 @@
67
67
  "lint": "eslint .",
68
68
  "lint:fix": "eslint . --fix",
69
69
  "pretest": "node -v | grep -q 'v22' || (echo 'Please use Node.js v22 for testing' && exit 1)",
70
- "test:release": "yarn test:types && yarn test:unit && yarn test:integration && yarn test:sqlite && yarn build && yarn lint:fix",
70
+ "test:quick": "yarn test:unit && yarn test:sqlite",
71
+ "test:release": "yarn test && yarn build && yarn lint:fix",
71
72
  "test:types": "yarn dev:prepare && vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
72
73
  "test:unit": "./scripts/test-unit.sh",
73
74
  "test:integration": "./scripts/test-integration.sh",
@@ -86,7 +87,7 @@
86
87
  "docs:dev": "vitepress dev docs",
87
88
  "docs:build": "vitepress build docs",
88
89
  "docs:preview": "vitepress preview docs",
89
- "docs:release": "yarn docs:build && ./scripts/deploy-docs.sh"
90
+ "docs:release": "date +%Y%m%d%H%M%S > docs/.lastRelease && yarn docs:build && ./scripts/deploy-docs.sh"
90
91
  },
91
92
  "dependencies": {
92
93
  "bcrypt": "^6.0.0",
@@ -101,7 +102,7 @@
101
102
  "pg": "^8.16.3"
102
103
  },
103
104
  "peerDependencies": {
104
- "@nuxt/kit": "^3.17.6",
105
+ "@nuxt/kit": "^3.17.6 || ^4.0.0",
105
106
  "bcrypt": "^6.0.0",
106
107
  "nodemailer": "^7.0.5",
107
108
  "nuxt-api-shield": "^0.8.0"
@@ -112,24 +113,25 @@
112
113
  }
113
114
  },
114
115
  "devDependencies": {
115
- "@nuxt/devtools": "^2.6.2",
116
+ "@nuxt/devtools": "^3.0.0",
116
117
  "@nuxt/eslint-config": "^1.5.2",
117
- "@nuxt/kit": "^3.17.6",
118
+ "@nuxt/kit": "^4.0.0",
118
119
  "@nuxt/module-builder": "^1.0.2",
119
- "@nuxt/schema": "^3.17.6",
120
+ "@nuxt/schema": "^4.0.0",
120
121
  "@nuxt/test-utils": "^3.19.2",
122
+ "@nuxt/vite-builder": "^4.2.0",
121
123
  "@types/bcrypt": "^6.0.0",
122
124
  "@types/node": "latest",
123
125
  "@types/nodemailer": "^6.4.17",
124
126
  "@types/pg": "^8.15.4",
125
127
  "changelogen": "^0.6.2",
126
128
  "eslint": "^9.30.1",
127
- "nuxt": "^3.17.6",
129
+ "nuxt": "^4.0.0",
128
130
  "tsx": "^4.20.3",
129
131
  "typescript": "~5.9.0",
130
132
  "unbuild": "^3.0.0",
131
133
  "vitepress": "^1.6.3",
132
- "vitest": "^3.2.4",
134
+ "vitest": "^4.0.0",
133
135
  "vue-tsc": "^3.0.1"
134
136
  }
135
137
  }
File without changes
File without changes