nuxt-users 1.6.7 → 1.7.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/CHANGELOG.md CHANGED
@@ -1,6 +1,39 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## v1.7.0
5
+
6
+ [compare changes](https://github.com/rrd108/nuxt-users/compare/v1.6.7...v1.7.0)
7
+
8
+ ### 🚀 Enhancements
9
+
10
+ - Implement RBAC closes #55 ([#55](https://github.com/rrd108/nuxt-users/issues/55))
11
+
12
+ ### 🩹 Fixes
13
+
14
+ - Type errors ([c403645](https://github.com/rrd108/nuxt-users/commit/c403645))
15
+
16
+ ### 💅 Refactors
17
+
18
+ - Token cleanup task and middleware ([d47a4a5](https://github.com/rrd108/nuxt-users/commit/d47a4a5))
19
+ - Renames `useAuth` to `useAuthentication` ([e611e62](https://github.com/rrd108/nuxt-users/commit/e611e62))
20
+
21
+ ### 🏡 Chore
22
+
23
+ - **release:** V1.6.7 ([def2d5c](https://github.com/rrd108/nuxt-users/commit/def2d5c))
24
+ - Bump cli version number ([b4daec6](https://github.com/rrd108/nuxt-users/commit/b4daec6))
25
+ - Fix for linter ([ce1db37](https://github.com/rrd108/nuxt-users/commit/ce1db37))
26
+
27
+ ### ✅ Tests
28
+
29
+ - Remove unused test ([3dc23ad](https://github.com/rrd108/nuxt-users/commit/3dc23ad))
30
+ - Fix response ([db3b03c](https://github.com/rrd108/nuxt-users/commit/db3b03c))
31
+ - Fix mysql field type ([2faf0c6](https://github.com/rrd108/nuxt-users/commit/2faf0c6))
32
+
33
+ ### ❤️ Contributors
34
+
35
+ - Rrd108 ([@rrd108](https://github.com/rrd108))
36
+
4
37
  ## v1.6.7
5
38
 
6
39
  [compare changes](https://github.com/rrd108/nuxt-users/compare/v1.6.6...v1.6.7)
package/dist/cli.mjs CHANGED
@@ -247,7 +247,7 @@ const main = defineCommand({
247
247
  meta: {
248
248
  name: "nuxt-users",
249
249
  description: "CLI for Nuxt Users Module - Manage users, migrations, and database operations",
250
- version: "1.6.6"
250
+ version: "1.6.7"
251
251
  },
252
252
  subCommands: {
253
253
  migrate,
package/dist/module.d.mts CHANGED
@@ -9,6 +9,90 @@ type DatabaseConfig = {
9
9
  password?: string;
10
10
  database?: string;
11
11
  };
12
+ interface RuntimeModuleOptions {
13
+ connector?: {
14
+ name: DatabaseType;
15
+ options: DatabaseConfig;
16
+ };
17
+ tables?: {
18
+ migrations?: string;
19
+ users?: string;
20
+ personalAccessTokens?: string;
21
+ passwordResetTokens?: string;
22
+ };
23
+ /**
24
+ * Mailer configuration options for sending emails (e.g., password resets)
25
+ * Uses nodemailer
26
+ */
27
+ mailer?: MailerOptions;
28
+ /**
29
+ * Base URL for password reset links
30
+ * @default 'http://localhost:3000' // Example, will be set in module defaults
31
+ */
32
+ passwordResetBaseUrl?: string;
33
+ /**
34
+ * Skip database checks during module setup to prevent hanging
35
+ * @default false
36
+ */
37
+ auth?: {
38
+ /**
39
+ * Whitelisted routes that do not require authentication
40
+ * @default ['/login']
41
+ * @example ['/login', '/register']
42
+ */
43
+ whitelist?: string[];
44
+ /**
45
+ * Token expiration time in minutes
46
+ * @default 1440
47
+ */
48
+ tokenExpiration?: number;
49
+ /**
50
+ * Role-based permissions configuration
51
+ * @default {}
52
+ * @example {
53
+ * admin: ['*'], // admin can access everything
54
+ * user: ['/profile', '/api/user/profile'],
55
+ * moderator: ['/admin/*', '/api/admin/*']
56
+ * }
57
+ */
58
+ permissions?: Record<string, string[]>;
59
+ };
60
+ /**
61
+ * Password validation configuration
62
+ */
63
+ passwordValidation?: {
64
+ /**
65
+ * Minimum password length
66
+ * @default 8
67
+ */
68
+ minLength?: number;
69
+ /**
70
+ * Require uppercase letters
71
+ * @default true
72
+ */
73
+ requireUppercase?: boolean;
74
+ /**
75
+ * Require lowercase letters
76
+ * @default true
77
+ */
78
+ requireLowercase?: boolean;
79
+ /**
80
+ * Require numbers
81
+ * @default true
82
+ */
83
+ requireNumbers?: boolean;
84
+ /**
85
+ * Require special characters
86
+ * @default true
87
+ */
88
+ requireSpecialChars?: boolean;
89
+ /**
90
+ * Prevent common passwords
91
+ * @default true
92
+ */
93
+ preventCommonPasswords?: boolean;
94
+ };
95
+ }
12
96
  interface ModuleOptions {
13
97
  connector: {
14
98
  name: DatabaseType;
@@ -25,6 +109,7 @@ interface ModuleOptions {
25
109
  auth: {
26
110
  whitelist: string[];
27
111
  tokenExpiration: number;
112
+ permissions: Record<string, string[]>;
28
113
  };
29
114
  passwordValidation: {
30
115
  minLength: number;
@@ -49,6 +134,6 @@ interface MailerOptions {
49
134
  }
50
135
 
51
136
  declare const defaultOptions: ModuleOptions;
52
- declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
137
+ declare const _default: _nuxt_schema.NuxtModule<RuntimeModuleOptions, RuntimeModuleOptions, false>;
53
138
 
54
139
  export { _default as default, defaultOptions };
package/dist/module.d.ts CHANGED
@@ -9,6 +9,90 @@ type DatabaseConfig = {
9
9
  password?: string;
10
10
  database?: string;
11
11
  };
12
+ interface RuntimeModuleOptions {
13
+ connector?: {
14
+ name: DatabaseType;
15
+ options: DatabaseConfig;
16
+ };
17
+ tables?: {
18
+ migrations?: string;
19
+ users?: string;
20
+ personalAccessTokens?: string;
21
+ passwordResetTokens?: string;
22
+ };
23
+ /**
24
+ * Mailer configuration options for sending emails (e.g., password resets)
25
+ * Uses nodemailer
26
+ */
27
+ mailer?: MailerOptions;
28
+ /**
29
+ * Base URL for password reset links
30
+ * @default 'http://localhost:3000' // Example, will be set in module defaults
31
+ */
32
+ passwordResetBaseUrl?: string;
33
+ /**
34
+ * Skip database checks during module setup to prevent hanging
35
+ * @default false
36
+ */
37
+ auth?: {
38
+ /**
39
+ * Whitelisted routes that do not require authentication
40
+ * @default ['/login']
41
+ * @example ['/login', '/register']
42
+ */
43
+ whitelist?: string[];
44
+ /**
45
+ * Token expiration time in minutes
46
+ * @default 1440
47
+ */
48
+ tokenExpiration?: number;
49
+ /**
50
+ * Role-based permissions configuration
51
+ * @default {}
52
+ * @example {
53
+ * admin: ['*'], // admin can access everything
54
+ * user: ['/profile', '/api/user/profile'],
55
+ * moderator: ['/admin/*', '/api/admin/*']
56
+ * }
57
+ */
58
+ permissions?: Record<string, string[]>;
59
+ };
60
+ /**
61
+ * Password validation configuration
62
+ */
63
+ passwordValidation?: {
64
+ /**
65
+ * Minimum password length
66
+ * @default 8
67
+ */
68
+ minLength?: number;
69
+ /**
70
+ * Require uppercase letters
71
+ * @default true
72
+ */
73
+ requireUppercase?: boolean;
74
+ /**
75
+ * Require lowercase letters
76
+ * @default true
77
+ */
78
+ requireLowercase?: boolean;
79
+ /**
80
+ * Require numbers
81
+ * @default true
82
+ */
83
+ requireNumbers?: boolean;
84
+ /**
85
+ * Require special characters
86
+ * @default true
87
+ */
88
+ requireSpecialChars?: boolean;
89
+ /**
90
+ * Prevent common passwords
91
+ * @default true
92
+ */
93
+ preventCommonPasswords?: boolean;
94
+ };
95
+ }
12
96
  interface ModuleOptions {
13
97
  connector: {
14
98
  name: DatabaseType;
@@ -25,6 +109,7 @@ interface ModuleOptions {
25
109
  auth: {
26
110
  whitelist: string[];
27
111
  tokenExpiration: number;
112
+ permissions: Record<string, string[]>;
28
113
  };
29
114
  passwordValidation: {
30
115
  minLength: number;
@@ -49,6 +134,6 @@ interface MailerOptions {
49
134
  }
50
135
 
51
136
  declare const defaultOptions: ModuleOptions;
52
- declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
137
+ declare const _default: _nuxt_schema.NuxtModule<RuntimeModuleOptions, RuntimeModuleOptions, false>;
53
138
 
54
139
  export { _default as default, defaultOptions };
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-users",
3
3
  "configKey": "nuxtUsers",
4
- "version": "1.6.7",
4
+ "version": "1.7.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
7
7
  "unbuild": "3.6.0"
package/dist/module.mjs CHANGED
@@ -31,9 +31,11 @@ const defaultOptions = {
31
31
  },
32
32
  passwordResetBaseUrl: "http://localhost:3000",
33
33
  auth: {
34
- whitelist: ["/login"],
35
- tokenExpiration: 24 * 60
34
+ whitelist: [],
35
+ tokenExpiration: 24 * 60,
36
36
  // 24 hours
37
+ permissions: {}
38
+ // Empty by default - whitelist approach
37
39
  },
38
40
  passwordValidation: {
39
41
  minLength: 8,
@@ -64,7 +66,8 @@ const module = defineNuxtModule({
64
66
  },
65
67
  auth: {
66
68
  whitelist: [...defaultOptions.auth?.whitelist || [], ...options.auth?.whitelist || []],
67
- tokenExpiration: options.auth?.tokenExpiration || defaultOptions.auth.tokenExpiration
69
+ tokenExpiration: options.auth?.tokenExpiration || defaultOptions.auth.tokenExpiration,
70
+ permissions: options.auth?.permissions || defaultOptions.auth.permissions
68
71
  }
69
72
  };
70
73
  nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
@@ -78,7 +81,8 @@ const module = defineNuxtModule({
78
81
  preventCommonPasswords: options.passwordValidation?.preventCommonPasswords ?? defaultOptions.passwordValidation.preventCommonPasswords
79
82
  },
80
83
  auth: {
81
- whitelist: [...defaultOptions.auth?.whitelist || [], ...options.auth?.whitelist || []]
84
+ whitelist: [...defaultOptions.auth?.whitelist || [], ...options.auth?.whitelist || []],
85
+ permissions: options.auth?.permissions || defaultOptions.auth.permissions
82
86
  }
83
87
  };
84
88
  addPlugin({
@@ -87,8 +91,8 @@ const module = defineNuxtModule({
87
91
  });
88
92
  addImportsDir(resolver.resolve("./runtime/composables"));
89
93
  addRouteMiddleware({
90
- name: "auth.client",
91
- path: resolver.resolve("./runtime/middleware/auth.client"),
94
+ name: "authorization.client",
95
+ path: resolver.resolve("./runtime/middleware/authorization.client"),
92
96
  global: true
93
97
  });
94
98
  addServerHandler({
@@ -1,7 +1,7 @@
1
1
  <script setup>
2
2
  import { ref } from "vue";
3
3
  import { navigateTo } from "#app";
4
- import { useAuth } from "../composables/useAuth";
4
+ import { useAuthentication } from "../composables/useAuthentication";
5
5
  const props = defineProps({
6
6
  redirectTo: { type: String, required: false, default: "/login" },
7
7
  linkText: { type: String, required: false, default: "Logout" },
@@ -16,7 +16,7 @@ const props = defineProps({
16
16
  containerStyle: { type: [String, Object], required: false }
17
17
  });
18
18
  const emit = defineEmits(["success", "click", "error"]);
19
- const { logout } = useAuth();
19
+ const { logout } = useAuthentication();
20
20
  const isLoading = ref(false);
21
21
  const error = ref("");
22
22
  const handleLogout = async (event) => {
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
- import { useAuth } from "../composables/useAuth";
3
- const { user } = useAuth();
2
+ import { useAuthentication } from "../composables/useAuthentication";
3
+ const { user } = useAuthentication();
4
4
  </script>
5
5
 
6
6
  <template>
@@ -1,5 +1,5 @@
1
1
  import type { User, UserWithoutPassword } from '../../types.js';
2
- export declare const useAuth: () => {
2
+ export declare const useAuthentication: () => {
3
3
  user: Readonly<import("vue").Ref<{
4
4
  readonly id: number;
5
5
  readonly email: string;
@@ -1,6 +1,6 @@
1
1
  import { useState } from "#app";
2
2
  import { computed, readonly } from "vue";
3
- export const useAuth = () => {
3
+ export const useAuthentication = () => {
4
4
  const user = useState("user", () => null);
5
5
  const isAuthenticated = computed(() => !!user.value);
6
6
  const login = (userData) => {
@@ -0,0 +1 @@
1
+ export declare const NO_AUTH_PATHS: string[];
@@ -0,0 +1 @@
1
+ export const NO_AUTH_PATHS = ["/login", "/api/auth/login", "/api/auth/forgot-password"];
@@ -0,0 +1,30 @@
1
+ import { defineNuxtRouteMiddleware, navigateTo, useRuntimeConfig } from "#app";
2
+ import { useAuthentication } from "../composables/useAuthentication.js";
3
+ import { hasPermission, isWhitelisted } from "../utils/permissions.js";
4
+ import { NO_AUTH_PATHS } from "../constants.js";
5
+ export default defineNuxtRouteMiddleware((to) => {
6
+ const { public: { nuxtUsers: publicNuxtUsers } } = useRuntimeConfig();
7
+ const publicOptions = publicNuxtUsers;
8
+ if (NO_AUTH_PATHS.includes(to.path)) {
9
+ console.log(`[Nuxt Users] client.middleware.auth.global: ${to.path}`);
10
+ return;
11
+ }
12
+ if (isWhitelisted(to.path, publicOptions.auth.whitelist)) {
13
+ console.log(`[Nuxt Users] client.middleware.auth.global: Whitelisted: ${to.path}`);
14
+ return;
15
+ }
16
+ const { isAuthenticated, user } = useAuthentication();
17
+ if (!isAuthenticated.value) {
18
+ console.log(`[Nuxt Users] client.middleware.auth.global: Unauthenticated ${to.path}, redirecting to /login`);
19
+ return navigateTo("/login");
20
+ }
21
+ if (!user.value || !hasPermission(user.value.role, to.path, publicOptions.auth.permissions)) {
22
+ console.log(`[Nuxt Users] client.middleware.auth.global: User with role ${user.value?.role} denied access to ${to.path}`);
23
+ return navigateTo("/login");
24
+ }
25
+ console.log("[Nuxt Users] client.middleware.auth.global", {
26
+ isAuthenticated: isAuthenticated.value,
27
+ userRole: user.value?.role,
28
+ to: to.path
29
+ });
30
+ });
@@ -1,7 +1,8 @@
1
1
  import { defineEventHandler, getCookie, sendRedirect } from "h3";
2
2
  import { useRuntimeConfig } from "#imports";
3
3
  import { getCurrentUserFromToken } from "../utils/index.js";
4
- const noAuthPaths = ["/login", "/api/auth/login", "/api/auth/forgot-password"];
4
+ import { hasPermission, isWhitelisted } from "../../utils/permissions.js";
5
+ import { NO_AUTH_PATHS } from "../../constants.js";
5
6
  export default defineEventHandler(async (event) => {
6
7
  const { nuxtUsers } = useRuntimeConfig();
7
8
  const options = nuxtUsers;
@@ -9,11 +10,11 @@ export default defineEventHandler(async (event) => {
9
10
  if (!isPageOrApiRoute) {
10
11
  return;
11
12
  }
12
- if (noAuthPaths.includes(event.path)) {
13
+ if (NO_AUTH_PATHS.includes(event.path)) {
13
14
  console.log("[Nuxt Users] server.middleware.auth.global: /login");
14
15
  return;
15
16
  }
16
- if (options.auth.whitelist.includes(event.path)) {
17
+ if (isWhitelisted(event.path, options.auth.whitelist)) {
17
18
  console.log(`[Nuxt Users] server.middleware.auth.global: whitelisted: ${event.path}`);
18
19
  return;
19
20
  }
@@ -27,6 +28,10 @@ export default defineEventHandler(async (event) => {
27
28
  console.log(`[Nuxt Users] server.middleware.auth.global: ${event.path} No user found redirecting to login`);
28
29
  return sendRedirect(event, "/login");
29
30
  }
30
- console.log(`[Nuxt Users] server.middleware.auth.global: Authenticated request to ${event.path} for ${user.id}`);
31
+ if (!hasPermission(user.role, event.path, options.auth.permissions)) {
32
+ console.log(`[Nuxt Users] server.middleware.auth.global: ${event.path} User ${user.id} with role ${user.role} denied access`);
33
+ return sendRedirect(event, "/login");
34
+ }
35
+ console.log(`[Nuxt Users] server.middleware.auth.global: Authenticated request to ${event.path} for ${user.id} with role ${user.role}`);
31
36
  return;
32
37
  });
@@ -30,13 +30,46 @@ export const sendPasswordResetLink = async (email, options) => {
30
30
  pass: options.mailer.auth.pass
31
31
  }
32
32
  });
33
+ const resetUrl = new URL("/reset-password", options.passwordResetBaseUrl || "http://localhost:3000");
34
+ resetUrl.searchParams.set("token", token);
35
+ resetUrl.searchParams.set("email", email);
36
+ const resetLink = resetUrl.toString();
33
37
  try {
34
38
  await transporter.sendMail({
35
39
  from: options.mailer.defaults?.from || '"Nuxt Users" <noreply@example.com>',
36
40
  to: email,
37
41
  subject: "Password Reset Request",
38
- text: `Please click the following link to reset your password: ${options.passwordResetBaseUrl}`,
39
- html: `<p>Please click the following link to reset your password:</p><p><a href="${options.passwordResetBaseUrl}">${options.passwordResetBaseUrl}</a></p><p>This link will expire in ${TOKEN_EXPIRATION_HOURS} hour(s).</p>`
42
+ text: `Please click the following link to reset your password: ${resetLink}
43
+
44
+ This link will expire in ${TOKEN_EXPIRATION_HOURS} hour(s).
45
+
46
+ If you did not request this password reset, please ignore this email.`,
47
+ html: `
48
+ <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
49
+ <h2>Password Reset Request</h2>
50
+ <p>You have requested to reset your password. Please click the button below to set a new password:</p>
51
+
52
+ <div style="text-align: center; margin: 30px 0;">
53
+ <a href="${resetLink}"
54
+ style="background-color: #007bff; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">
55
+ Reset Password
56
+ </a>
57
+ </div>
58
+
59
+ <p>Or copy and paste the following link into your browser:</p>
60
+ <p style="word-break: break-all; background-color: #f8f9fa; padding: 10px; border-radius: 3px;">
61
+ <a href="${resetLink}">${resetLink}</a>
62
+ </p>
63
+
64
+ <p style="color: #6c757d; font-size: 14px;">
65
+ This link will expire in ${TOKEN_EXPIRATION_HOURS} hour(s).
66
+ </p>
67
+
68
+ <p style="color: #6c757d; font-size: 14px;">
69
+ If you did not request this password reset, please ignore this email. Your password will remain unchanged.
70
+ </p>
71
+ </div>
72
+ `
40
73
  });
41
74
  console.log(`[Nuxt Users] Password reset email sent to ${email}`);
42
75
  } catch (error) {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Checks if a path matches a pattern (supports wildcards)
3
+ * @param path - The path to check
4
+ * @param pattern - The pattern to match against (supports * wildcard)
5
+ * @returns true if the path matches the pattern
6
+ */
7
+ export declare const pathMatchesPattern: (path: string, pattern: string) => boolean;
8
+ /**
9
+ * Checks if a user has permission to access a specific path
10
+ * @param userRole - The user's role
11
+ * @param path - The path being accessed
12
+ * @param permissions - The permissions configuration
13
+ * @returns true if the user has permission to access the path
14
+ */
15
+ export declare const hasPermission: (userRole: string, path: string, permissions: Record<string, string[]>) => boolean;
16
+ /**
17
+ * Checks if a path is accessible without authentication
18
+ * @param path - The path being accessed
19
+ * @param whitelist - Array of whitelisted paths
20
+ * @returns true if the path is whitelisted
21
+ */
22
+ export declare const isWhitelisted: (path: string, whitelist: string[]) => boolean;
@@ -0,0 +1,36 @@
1
+ export const pathMatchesPattern = (path, pattern) => {
2
+ if (path === pattern) {
3
+ return true;
4
+ }
5
+ if (pattern === "*") {
6
+ return true;
7
+ }
8
+ if ((pattern.match(/\*/g) || []).length > 1) {
9
+ const regexPattern = pattern.replace(/\*/g, "[^/]*");
10
+ const regex = new RegExp(`^${regexPattern}$`);
11
+ return regex.test(path);
12
+ }
13
+ if (pattern.endsWith("/*")) {
14
+ const basePattern = pattern.slice(0, -2);
15
+ return path === basePattern || path.startsWith(basePattern + "/");
16
+ }
17
+ if (pattern.includes("*")) {
18
+ const regexPattern = pattern.replace(/\*/g, "[^/]*");
19
+ const regex = new RegExp(`^${regexPattern}$`);
20
+ return regex.test(path);
21
+ }
22
+ return false;
23
+ };
24
+ export const hasPermission = (userRole, path, permissions) => {
25
+ if (!permissions || Object.keys(permissions).length === 0) {
26
+ return false;
27
+ }
28
+ const rolePermissions = permissions[userRole];
29
+ if (!rolePermissions) {
30
+ return false;
31
+ }
32
+ return rolePermissions.some((pattern) => pathMatchesPattern(path, pattern));
33
+ };
34
+ export const isWhitelisted = (path, whitelist) => {
35
+ return whitelist.some((whitelistedPath) => pathMatchesPattern(path, whitelistedPath));
36
+ };
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "nuxt-users",
3
- "version": "1.6.7",
4
- "description": "A comprehensive user management module for Nuxt 3 applications with authentication, database support, and CLI tools",
3
+ "version": "1.7.0",
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",
7
7
  "nuxt3",
8
8
  "nuxt-module",
9
9
  "users",
10
10
  "authentication",
11
+ "authorization",
11
12
  "auth",
12
13
  "user-management",
13
14
  "sqlite",
@@ -82,7 +83,7 @@
82
83
  "docs:dev": "vitepress dev docs",
83
84
  "docs:build": "vitepress build docs",
84
85
  "docs:preview": "vitepress preview docs",
85
- "docs:deploy": "yarn docs:build && ./scripts/deploy-docs.sh"
86
+ "docs:release": "yarn docs:build && ./scripts/deploy-docs.sh"
86
87
  },
87
88
  "dependencies": {
88
89
  "bcrypt": "^6.0.0",
@@ -98,7 +99,13 @@
98
99
  "peerDependencies": {
99
100
  "@nuxt/kit": "^3.17.6",
100
101
  "bcrypt": "^6.0.0",
101
- "nodemailer": "^7.0.5"
102
+ "nodemailer": "^7.0.5",
103
+ "nuxt-api-shield": "^0.1.0 || ^0.8.0"
104
+ },
105
+ "peerDependenciesMeta": {
106
+ "nuxt-api-shield": {
107
+ "optional": true
108
+ }
102
109
  },
103
110
  "devDependencies": {
104
111
  "@nuxt/devtools": "^2.6.2",
@@ -1,20 +0,0 @@
1
- import { defineNuxtRouteMiddleware, navigateTo, useRuntimeConfig } from "#app";
2
- import { useAuth } from "../composables/useAuth.js";
3
- export default defineNuxtRouteMiddleware((to) => {
4
- const { public: { nuxtUsers: publicNuxtUsers } } = useRuntimeConfig();
5
- const publicOptions = publicNuxtUsers;
6
- if (to.path === "/login") {
7
- console.log("[Nuxt Users] client.middleware.auth.global: /login");
8
- return;
9
- }
10
- if (publicOptions.auth.whitelist.includes(to.path)) {
11
- console.log(`[Nuxt Users] client.middleware.auth.global: Whitelisted: ${to.path}`);
12
- return;
13
- }
14
- const { isAuthenticated } = useAuth();
15
- if (!isAuthenticated.value) {
16
- console.log(`[Nuxt Users] client.middleware.auth.global: Unauthenticated ${to.path}, redirecting to /login`);
17
- return navigateTo("/login");
18
- }
19
- console.log("[Nuxt Users] client.middleware.auth.global", { isAuthenticated: isAuthenticated.value, to: to.path });
20
- });