nuxt-users 1.34.1 → 1.34.3
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 +47 -0
- package/dist/cli.mjs +22 -5
- package/dist/module.d.mts +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -1
- package/dist/runtime/components/NUsersLoginForm.vue +3 -2
- package/dist/runtime/components/NUsersLoginForm.vue.d.ts +2 -2
- package/dist/runtime/composables/useAuthentication.d.ts +1 -1
- package/dist/runtime/composables/useAuthentication.js +32 -4
- package/dist/runtime/server/api/nuxt-users/session/index.post.js +15 -6
- package/dist/shared/{nuxt-users.BOm7L39P.d.mts → nuxt-users.BTVH9EyH.d.mts} +6 -0
- package/dist/shared/{nuxt-users.BOm7L39P.d.ts → nuxt-users.BTVH9EyH.d.ts} +6 -0
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v1.34.3
|
|
5
|
+
|
|
6
|
+
[compare changes](https://github.com/rrd108/nuxt-users/compare/v1.34.2...v1.34.3)
|
|
7
|
+
|
|
8
|
+
### 🩹 Fixes
|
|
9
|
+
|
|
10
|
+
- Remember me closes #3 ([#3](https://github.com/rrd108/nuxt-users/issues/3))
|
|
11
|
+
- Hard reload ([187c828](https://github.com/rrd108/nuxt-users/commit/187c828))
|
|
12
|
+
- Conflicting runtimeconfig ([563dcca](https://github.com/rrd108/nuxt-users/commit/563dcca))
|
|
13
|
+
- Lint errors ([b590e6d](https://github.com/rrd108/nuxt-users/commit/b590e6d))
|
|
14
|
+
|
|
15
|
+
### 🏡 Chore
|
|
16
|
+
|
|
17
|
+
- **release:** V1.34.2 ([60d87dc](https://github.com/rrd108/nuxt-users/commit/60d87dc))
|
|
18
|
+
|
|
19
|
+
### ✅ Tests
|
|
20
|
+
|
|
21
|
+
- Add for config conflict ([59271e3](https://github.com/rrd108/nuxt-users/commit/59271e3))
|
|
22
|
+
|
|
23
|
+
### ❤️ Contributors
|
|
24
|
+
|
|
25
|
+
- Rrd108 ([@rrd108](https://github.com/rrd108))
|
|
26
|
+
|
|
27
|
+
## v1.34.2
|
|
28
|
+
|
|
29
|
+
[compare changes](https://github.com/rrd108/nuxt-users/compare/v1.34.1...v1.34.2)
|
|
30
|
+
|
|
31
|
+
### 🩹 Fixes
|
|
32
|
+
|
|
33
|
+
- Remember me closes #3 ([#3](https://github.com/rrd108/nuxt-users/issues/3))
|
|
34
|
+
|
|
35
|
+
### 💅 Refactors
|
|
36
|
+
|
|
37
|
+
- Component imports ([5b18736](https://github.com/rrd108/nuxt-users/commit/5b18736))
|
|
38
|
+
|
|
39
|
+
### 📖 Documentation
|
|
40
|
+
|
|
41
|
+
- Add getCurrentUser ([bc30658](https://github.com/rrd108/nuxt-users/commit/bc30658))
|
|
42
|
+
|
|
43
|
+
### 🏡 Chore
|
|
44
|
+
|
|
45
|
+
- **release:** V1.34.1 ([a335bfc](https://github.com/rrd108/nuxt-users/commit/a335bfc))
|
|
46
|
+
|
|
47
|
+
### ❤️ Contributors
|
|
48
|
+
|
|
49
|
+
- Rrd108 ([@rrd108](https://github.com/rrd108))
|
|
50
|
+
|
|
4
51
|
## v1.34.1
|
|
5
52
|
|
|
6
53
|
[compare changes](https://github.com/rrd108/nuxt-users/compare/v1.34.0...v1.34.1)
|
package/dist/cli.mjs
CHANGED
|
@@ -50,12 +50,29 @@ const getOptionsFromEnv = () => {
|
|
|
50
50
|
const loadOptions = async () => {
|
|
51
51
|
try {
|
|
52
52
|
console.log("[Nuxt Users] Loading Nuxt project...");
|
|
53
|
-
const nuxt = await loadNuxt({ cwd: process.cwd() });
|
|
54
|
-
const
|
|
53
|
+
const nuxt = await loadNuxt({ cwd: process.cwd(), ready: false });
|
|
54
|
+
const topLevelConfig = nuxt.options.nuxtUsers;
|
|
55
|
+
const originalRuntimeConfig = await (async () => {
|
|
56
|
+
try {
|
|
57
|
+
const configPath = await import('node:path').then((p) => p.resolve(process.cwd(), "nuxt.config.ts"));
|
|
58
|
+
const config = await import(configPath).then((m) => m.default);
|
|
59
|
+
return config?.runtimeConfig?.nuxtUsers;
|
|
60
|
+
} catch {
|
|
61
|
+
return nuxt.options.runtimeConfig?.nuxtUsers;
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
55
64
|
await nuxt.close();
|
|
56
|
-
if (
|
|
57
|
-
console.log("[Nuxt Users] Using configuration from
|
|
58
|
-
|
|
65
|
+
if (topLevelConfig || originalRuntimeConfig) {
|
|
66
|
+
console.log("[Nuxt Users] Using configuration from nuxt.config");
|
|
67
|
+
let mergedConfig = defu(topLevelConfig, originalRuntimeConfig, defaultOptions);
|
|
68
|
+
const configuredConnector = topLevelConfig?.connector || originalRuntimeConfig?.connector;
|
|
69
|
+
if (configuredConnector) {
|
|
70
|
+
mergedConfig = {
|
|
71
|
+
...mergedConfig,
|
|
72
|
+
connector: configuredConnector
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return mergedConfig;
|
|
59
76
|
} else {
|
|
60
77
|
console.log("[Nuxt Users] No nuxt-users configuration found, using environment variables");
|
|
61
78
|
return getOptionsFromEnv();
|
package/dist/module.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
-
import { R as RuntimeModuleOptions, M as ModuleOptions } from './shared/nuxt-users.
|
|
2
|
+
import { R as RuntimeModuleOptions, M as ModuleOptions } from './shared/nuxt-users.BTVH9EyH.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 { R as RuntimeModuleOptions, M as ModuleOptions } from './shared/nuxt-users.
|
|
2
|
+
import { R as RuntimeModuleOptions, M as ModuleOptions } from './shared/nuxt-users.BTVH9EyH.js';
|
|
3
3
|
export * from '../dist/runtime/server/internal/index.js';
|
|
4
4
|
|
|
5
5
|
declare const defaultOptions: ModuleOptions;
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -30,10 +30,11 @@ const handleSubmit = async () => {
|
|
|
30
30
|
method: "POST",
|
|
31
31
|
body: {
|
|
32
32
|
email: formData.value.email,
|
|
33
|
-
password: formData.value.password
|
|
33
|
+
password: formData.value.password,
|
|
34
|
+
rememberMe: formData.value.rememberMe
|
|
34
35
|
}
|
|
35
36
|
});
|
|
36
|
-
emit("success", response.user);
|
|
37
|
+
emit("success", response.user, formData.value.rememberMe ?? false);
|
|
37
38
|
if (props.redirectTo) {
|
|
38
39
|
await navigateTo(props.redirectTo);
|
|
39
40
|
}
|
|
@@ -26,13 +26,13 @@ type __VLS_Slots = {} & {
|
|
|
26
26
|
'error-message'?: (props: typeof __VLS_15) => any;
|
|
27
27
|
};
|
|
28
28
|
declare const __VLS_component: import("vue").DefineComponent<Props, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
29
|
-
success: (user: UserWithoutPassword) => any;
|
|
29
|
+
success: (user: UserWithoutPassword, rememberMe: boolean) => any;
|
|
30
30
|
error: (error: string) => 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) => any) | undefined;
|
|
35
|
+
onSuccess?: ((user: UserWithoutPassword, rememberMe: boolean) => any) | undefined;
|
|
36
36
|
onError?: ((error: string) => any) | undefined;
|
|
37
37
|
onSubmit?: ((data: LoginFormData) => any) | undefined;
|
|
38
38
|
"onForgot-password-error"?: ((error: string) => any) | undefined;
|
|
@@ -2,7 +2,7 @@ import type { User } from 'nuxt-users/utils';
|
|
|
2
2
|
export declare const useAuthentication: () => {
|
|
3
3
|
user: Readonly<import("vue").Ref<any, any>>;
|
|
4
4
|
isAuthenticated: import("vue").ComputedRef<boolean>;
|
|
5
|
-
login: (userData: User) => void;
|
|
5
|
+
login: (userData: User, rememberMe?: boolean) => void;
|
|
6
6
|
logout: () => Promise<void>;
|
|
7
7
|
fetchUser: () => Promise<any>;
|
|
8
8
|
initializeUser: () => Promise<void>;
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { useState, useRuntimeConfig } from "#app";
|
|
2
2
|
import { computed, readonly } from "vue";
|
|
3
|
+
let initializationPromise = null;
|
|
3
4
|
export const useAuthentication = () => {
|
|
4
5
|
const user = useState("user", () => null);
|
|
5
6
|
const { public: { nuxtUsers } } = useRuntimeConfig();
|
|
6
7
|
const apiBasePath = nuxtUsers?.apiBasePath;
|
|
7
8
|
const isAuthenticated = computed(() => !!user.value);
|
|
8
|
-
const login = (userData) => {
|
|
9
|
+
const login = (userData, rememberMe = false) => {
|
|
9
10
|
const { password: _, ...userWithoutPassword } = userData;
|
|
10
11
|
user.value = userWithoutPassword;
|
|
11
12
|
if (import.meta.client) {
|
|
12
|
-
localStorage.
|
|
13
|
+
localStorage.removeItem("user");
|
|
14
|
+
sessionStorage.removeItem("user");
|
|
15
|
+
if (rememberMe) {
|
|
16
|
+
localStorage.setItem("user", JSON.stringify(userWithoutPassword));
|
|
17
|
+
} else {
|
|
18
|
+
sessionStorage.setItem("user", JSON.stringify(userWithoutPassword));
|
|
19
|
+
}
|
|
13
20
|
}
|
|
14
21
|
};
|
|
15
22
|
const logout = async () => {
|
|
@@ -18,10 +25,15 @@ export const useAuthentication = () => {
|
|
|
18
25
|
user.value = null;
|
|
19
26
|
if (import.meta.client) {
|
|
20
27
|
localStorage.removeItem("user");
|
|
28
|
+
sessionStorage.removeItem("user");
|
|
21
29
|
}
|
|
22
30
|
} catch (error) {
|
|
23
31
|
console.error("Logout failed:", error);
|
|
24
32
|
user.value = null;
|
|
33
|
+
if (import.meta.client) {
|
|
34
|
+
localStorage.removeItem("user");
|
|
35
|
+
sessionStorage.removeItem("user");
|
|
36
|
+
}
|
|
25
37
|
}
|
|
26
38
|
};
|
|
27
39
|
const fetchUser = async () => {
|
|
@@ -29,7 +41,15 @@ export const useAuthentication = () => {
|
|
|
29
41
|
const response = await $fetch(`${apiBasePath}/me`, { method: "GET" });
|
|
30
42
|
user.value = response.user;
|
|
31
43
|
if (import.meta.client) {
|
|
32
|
-
localStorage.
|
|
44
|
+
const wasInLocalStorage = localStorage.getItem("user") !== null;
|
|
45
|
+
const wasInSessionStorage = sessionStorage.getItem("user") !== null;
|
|
46
|
+
if (wasInLocalStorage) {
|
|
47
|
+
localStorage.setItem("user", JSON.stringify(response.user));
|
|
48
|
+
} else if (wasInSessionStorage) {
|
|
49
|
+
sessionStorage.setItem("user", JSON.stringify(response.user));
|
|
50
|
+
} else {
|
|
51
|
+
sessionStorage.setItem("user", JSON.stringify(response.user));
|
|
52
|
+
}
|
|
33
53
|
}
|
|
34
54
|
return response.user;
|
|
35
55
|
} catch (error) {
|
|
@@ -37,6 +57,7 @@ export const useAuthentication = () => {
|
|
|
37
57
|
user.value = null;
|
|
38
58
|
if (import.meta.client) {
|
|
39
59
|
localStorage.removeItem("user");
|
|
60
|
+
sessionStorage.removeItem("user");
|
|
40
61
|
}
|
|
41
62
|
return null;
|
|
42
63
|
}
|
|
@@ -45,7 +66,9 @@ export const useAuthentication = () => {
|
|
|
45
66
|
if (!import.meta.client) {
|
|
46
67
|
return;
|
|
47
68
|
}
|
|
48
|
-
const
|
|
69
|
+
const storedUserLocal = localStorage.getItem("user");
|
|
70
|
+
const storedUserSession = sessionStorage.getItem("user");
|
|
71
|
+
const storedUser = storedUserLocal || storedUserSession;
|
|
49
72
|
if (storedUser) {
|
|
50
73
|
try {
|
|
51
74
|
user.value = JSON.parse(storedUser);
|
|
@@ -53,10 +76,15 @@ export const useAuthentication = () => {
|
|
|
53
76
|
} catch (error) {
|
|
54
77
|
console.error("Failed to parse stored user:", error);
|
|
55
78
|
localStorage.removeItem("user");
|
|
79
|
+
sessionStorage.removeItem("user");
|
|
56
80
|
user.value = null;
|
|
57
81
|
}
|
|
58
82
|
}
|
|
59
83
|
};
|
|
84
|
+
if (import.meta.client && !initializationPromise) {
|
|
85
|
+
initializationPromise = initializeUser().catch(() => {
|
|
86
|
+
});
|
|
87
|
+
}
|
|
60
88
|
return {
|
|
61
89
|
user: readonly(user),
|
|
62
90
|
isAuthenticated,
|
|
@@ -5,7 +5,7 @@ import { useRuntimeConfig } from "#imports";
|
|
|
5
5
|
import { useDb } from "../../../utils/db.js";
|
|
6
6
|
export default defineEventHandler(async (event) => {
|
|
7
7
|
const body = await readBody(event);
|
|
8
|
-
const { email, password } = body;
|
|
8
|
+
const { email, password, rememberMe } = body;
|
|
9
9
|
if (!email || !password) {
|
|
10
10
|
throw createError({
|
|
11
11
|
statusCode: 400,
|
|
@@ -42,21 +42,30 @@ export default defineEventHandler(async (event) => {
|
|
|
42
42
|
const token = crypto.randomBytes(64).toString("hex");
|
|
43
43
|
const tokenName = "auth_token";
|
|
44
44
|
const expiresAt = /* @__PURE__ */ new Date();
|
|
45
|
-
|
|
45
|
+
if (rememberMe) {
|
|
46
|
+
const longTermDays = options.auth.rememberMeExpiration || 30;
|
|
47
|
+
expiresAt.setDate(expiresAt.getDate() + longTermDays);
|
|
48
|
+
} else {
|
|
49
|
+
expiresAt.setMinutes(expiresAt.getMinutes() + options.auth.tokenExpiration);
|
|
50
|
+
}
|
|
46
51
|
await db.sql`
|
|
47
52
|
INSERT INTO {${personalAccessTokensTable}} (tokenable_type, tokenable_id, name, token, expires_at, created_at, updated_at)
|
|
48
53
|
VALUES ('user', ${user.id}, ${tokenName}, ${token}, ${expiresAt.toISOString().slice(0, 19).replace("T", " ")}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
49
54
|
`;
|
|
50
|
-
|
|
55
|
+
const cookieOptions = {
|
|
51
56
|
httpOnly: true,
|
|
52
57
|
secure: process.env.NODE_ENV === "production",
|
|
53
58
|
// Use secure cookies in production
|
|
54
59
|
sameSite: "lax",
|
|
55
60
|
// Adjust as needed
|
|
56
|
-
maxAge: 60 * 60 * 24 * 7,
|
|
57
|
-
// 7 days
|
|
58
61
|
path: "/"
|
|
59
|
-
}
|
|
62
|
+
};
|
|
63
|
+
if (rememberMe) {
|
|
64
|
+
const longTermDays = options.auth.rememberMeExpiration || 30;
|
|
65
|
+
cookieOptions.maxAge = 60 * 60 * 24 * longTermDays;
|
|
66
|
+
} else {
|
|
67
|
+
}
|
|
68
|
+
setCookie(event, "auth_token", token, cookieOptions);
|
|
60
69
|
const { password: _, ...userWithoutPassword } = user;
|
|
61
70
|
return { user: userWithoutPassword };
|
|
62
71
|
});
|
|
@@ -60,6 +60,11 @@ interface RuntimeModuleOptions {
|
|
|
60
60
|
* @default 1440
|
|
61
61
|
*/
|
|
62
62
|
tokenExpiration?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Remember me token expiration time in days
|
|
65
|
+
* @default 30
|
|
66
|
+
*/
|
|
67
|
+
rememberMeExpiration?: number;
|
|
63
68
|
/**
|
|
64
69
|
* Role-based permissions configuration
|
|
65
70
|
* @default {}
|
|
@@ -132,6 +137,7 @@ interface ModuleOptions {
|
|
|
132
137
|
auth: {
|
|
133
138
|
whitelist: string[];
|
|
134
139
|
tokenExpiration: number;
|
|
140
|
+
rememberMeExpiration: number;
|
|
135
141
|
permissions: Record<string, (string | Permission)[]>;
|
|
136
142
|
};
|
|
137
143
|
passwordValidation: {
|
|
@@ -60,6 +60,11 @@ interface RuntimeModuleOptions {
|
|
|
60
60
|
* @default 1440
|
|
61
61
|
*/
|
|
62
62
|
tokenExpiration?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Remember me token expiration time in days
|
|
65
|
+
* @default 30
|
|
66
|
+
*/
|
|
67
|
+
rememberMeExpiration?: number;
|
|
63
68
|
/**
|
|
64
69
|
* Role-based permissions configuration
|
|
65
70
|
* @default {}
|
|
@@ -132,6 +137,7 @@ interface ModuleOptions {
|
|
|
132
137
|
auth: {
|
|
133
138
|
whitelist: string[];
|
|
134
139
|
tokenExpiration: number;
|
|
140
|
+
rememberMeExpiration: number;
|
|
135
141
|
permissions: Record<string, (string | Permission)[]>;
|
|
136
142
|
};
|
|
137
143
|
passwordValidation: {
|
package/dist/utils.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { g as DatabaseConfig, f as DatabaseType, D as DisplayFieldsProps, L as LoginFormData, c as LoginFormProps, M as ModuleOptions, b as PasswordResetToken, e as Permission, P as PersonalAccessToken, d as ResetPasswordFormProps, R as RuntimeModuleOptions, U as User, a as UserWithoutPassword, h as defaultDisplayFields, i as defaultFieldLabels } from './shared/nuxt-users.
|
|
1
|
+
export { g as DatabaseConfig, f as DatabaseType, D as DisplayFieldsProps, L as LoginFormData, c as LoginFormProps, M as ModuleOptions, b as PasswordResetToken, e as Permission, P as PersonalAccessToken, d as ResetPasswordFormProps, R as RuntimeModuleOptions, U as User, a as UserWithoutPassword, h as defaultDisplayFields, i as defaultFieldLabels } from './shared/nuxt-users.BTVH9EyH.mjs';
|
|
2
2
|
|
|
3
3
|
interface PasswordValidationResult {
|
|
4
4
|
isValid: boolean;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { g as DatabaseConfig, f as DatabaseType, D as DisplayFieldsProps, L as LoginFormData, c as LoginFormProps, M as ModuleOptions, b as PasswordResetToken, e as Permission, P as PersonalAccessToken, d as ResetPasswordFormProps, R as RuntimeModuleOptions, U as User, a as UserWithoutPassword, h as defaultDisplayFields, i as defaultFieldLabels } from './shared/nuxt-users.
|
|
1
|
+
export { g as DatabaseConfig, f as DatabaseType, D as DisplayFieldsProps, L as LoginFormData, c as LoginFormProps, M as ModuleOptions, b as PasswordResetToken, e as Permission, P as PersonalAccessToken, d as ResetPasswordFormProps, R as RuntimeModuleOptions, U as User, a as UserWithoutPassword, h as defaultDisplayFields, i as defaultFieldLabels } from './shared/nuxt-users.BTVH9EyH.js';
|
|
2
2
|
|
|
3
3
|
interface PasswordValidationResult {
|
|
4
4
|
isValid: boolean;
|
package/package.json
CHANGED