nuxt-users 1.34.7 → 1.36.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 +98 -0
- package/dist/cli.mjs +111 -0
- package/dist/module.d.mts +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +38 -3
- package/dist/runtime/assets/nuxt-users.css +1 -1
- package/dist/runtime/components/NUsersEmailConfirmation.d.vue.ts +38 -0
- package/dist/runtime/components/NUsersEmailConfirmation.vue.d.ts +3 -2
- package/dist/runtime/components/NUsersGoogleLoginButton.d.vue.ts +31 -0
- package/dist/runtime/components/NUsersGoogleLoginButton.vue +75 -0
- package/dist/runtime/components/NUsersGoogleLoginButton.vue.d.ts +31 -0
- package/dist/runtime/components/NUsersList.d.vue.ts +0 -0
- package/dist/runtime/components/NUsersLoginForm.d.vue.ts +48 -0
- package/dist/runtime/components/NUsersLoginForm.vue.d.ts +5 -4
- package/dist/runtime/components/NUsersLogoutLink.d.vue.ts +38 -0
- package/dist/runtime/components/NUsersLogoutLink.vue.d.ts +5 -4
- package/dist/runtime/components/NUsersPasswordStrengthIndicator.d.vue.ts +13 -0
- package/dist/runtime/components/NUsersPasswordStrengthIndicator.vue.d.ts +2 -1
- package/dist/runtime/components/NUsersProfileInfo.d.vue.ts +3 -0
- package/dist/runtime/components/NUsersProfileInfo.vue.d.ts +2 -1
- package/dist/runtime/components/NUsersRegisterForm.d.vue.ts +61 -0
- package/dist/runtime/components/NUsersRegisterForm.vue.d.ts +5 -4
- package/dist/runtime/components/NUsersResetPasswordForm.d.vue.ts +18 -0
- package/dist/runtime/components/NUsersResetPasswordForm.vue.d.ts +4 -3
- package/dist/runtime/components/NUsersUserCard.d.vue.ts +44 -0
- package/dist/runtime/components/NUsersUserCard.vue.d.ts +3 -2
- package/dist/runtime/components/NUsersUserForm.d.vue.ts +15 -0
- package/dist/runtime/components/NUsersUserForm.vue.d.ts +2 -1
- package/dist/runtime/composables/useAuthentication.d.ts +1 -1
- package/dist/runtime/composables/useAuthentication.js +26 -8
- package/dist/runtime/middleware/authorization.client.js +9 -7
- package/dist/runtime/server/api/nuxt-users/auth/google/callback.get.d.ts +2 -0
- package/dist/runtime/server/api/nuxt-users/auth/google/callback.get.js +68 -0
- package/dist/runtime/server/api/nuxt-users/auth/google/redirect.get.d.ts +2 -0
- package/dist/runtime/server/api/nuxt-users/auth/google/redirect.get.js +39 -0
- package/dist/runtime/server/api/nuxt-users/inactive.get.js +1 -1
- package/dist/runtime/server/api/nuxt-users/index.get.js +1 -1
- package/dist/runtime/server/api/nuxt-users/session/index.post.d.ts +1 -1
- package/dist/runtime/server/api/nuxt-users/session/index.post.js +6 -0
- package/dist/runtime/server/services/password.js +8 -0
- package/dist/runtime/server/services/registration.js +14 -1
- package/dist/runtime/server/utils/add-google-oauth-fields.d.ts +2 -0
- package/dist/runtime/server/utils/add-google-oauth-fields.js +22 -0
- package/dist/runtime/server/utils/create-users-table.js +7 -1
- package/dist/runtime/server/utils/google-oauth.d.ts +33 -0
- package/dist/runtime/server/utils/google-oauth.js +142 -0
- package/dist/runtime/server/utils/index.d.ts +1 -0
- package/dist/runtime/server/utils/index.js +1 -0
- package/dist/runtime/server/utils/migrate.js +5 -0
- package/dist/runtime/server/utils/user.js +24 -3
- package/dist/shared/{nuxt-users.BTVH9EyH.d.mts → nuxt-users.SXaMnaEL.d.mts} +45 -1
- package/dist/shared/{nuxt-users.BTVH9EyH.d.ts → nuxt-users.SXaMnaEL.d.ts} +45 -1
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/package.json +8 -6
- package/scripts/check-peer-dependencies.js +0 -0
- package/scripts/post-build.js +0 -0
|
@@ -25,20 +25,21 @@ type __VLS_Slots = {} & {
|
|
|
25
25
|
} & {
|
|
26
26
|
'error-message'?: (props: typeof __VLS_15) => any;
|
|
27
27
|
};
|
|
28
|
-
declare const
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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;
|
|
@@ -4,6 +4,6 @@ export declare const useAuthentication: () => {
|
|
|
4
4
|
isAuthenticated: import("vue").ComputedRef<boolean>;
|
|
5
5
|
login: (userData: User, rememberMe?: boolean) => void;
|
|
6
6
|
logout: () => Promise<void>;
|
|
7
|
-
fetchUser: () => Promise<any>;
|
|
7
|
+
fetchUser: (useSSR?: boolean) => Promise<any>;
|
|
8
8
|
initializeUser: () => Promise<void>;
|
|
9
9
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useRuntimeConfig } from "#app";
|
|
1
|
+
import { useState, useRuntimeConfig, useFetch } from "#app";
|
|
2
2
|
import { computed, readonly } from "vue";
|
|
3
3
|
let initializationPromise = null;
|
|
4
4
|
export const useAuthentication = () => {
|
|
@@ -36,22 +36,40 @@ export const useAuthentication = () => {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
|
-
const fetchUser = async () => {
|
|
39
|
+
const fetchUser = async (useSSR = false) => {
|
|
40
40
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
let userData = null;
|
|
42
|
+
if (useSSR) {
|
|
43
|
+
const { data, error } = await useFetch(`${apiBasePath}/me`, {
|
|
44
|
+
server: true,
|
|
45
|
+
lazy: false
|
|
46
|
+
});
|
|
47
|
+
if (error.value) {
|
|
48
|
+
throw new Error(error.value.message || "Failed to fetch user");
|
|
49
|
+
}
|
|
50
|
+
userData = data.value?.user || null;
|
|
51
|
+
} else {
|
|
52
|
+
const response = await $fetch(`${apiBasePath}/me`, {
|
|
53
|
+
method: "GET"
|
|
54
|
+
});
|
|
55
|
+
userData = response.user;
|
|
56
|
+
}
|
|
57
|
+
if (!userData) {
|
|
58
|
+
throw new Error("No user data received");
|
|
59
|
+
}
|
|
60
|
+
user.value = userData;
|
|
43
61
|
if (import.meta.client) {
|
|
44
62
|
const wasInLocalStorage = localStorage.getItem("user") !== null;
|
|
45
63
|
const wasInSessionStorage = sessionStorage.getItem("user") !== null;
|
|
46
64
|
if (wasInLocalStorage) {
|
|
47
|
-
localStorage.setItem("user", JSON.stringify(
|
|
65
|
+
localStorage.setItem("user", JSON.stringify(userData));
|
|
48
66
|
} else if (wasInSessionStorage) {
|
|
49
|
-
sessionStorage.setItem("user", JSON.stringify(
|
|
67
|
+
sessionStorage.setItem("user", JSON.stringify(userData));
|
|
50
68
|
} else {
|
|
51
|
-
sessionStorage.setItem("user", JSON.stringify(
|
|
69
|
+
sessionStorage.setItem("user", JSON.stringify(userData));
|
|
52
70
|
}
|
|
53
71
|
}
|
|
54
|
-
return
|
|
72
|
+
return userData;
|
|
55
73
|
} catch (error) {
|
|
56
74
|
console.error("Failed to fetch user:", error);
|
|
57
75
|
user.value = null;
|
|
@@ -2,7 +2,7 @@ import { defineNuxtRouteMiddleware, navigateTo, useRuntimeConfig } from "#app";
|
|
|
2
2
|
import { useAuthentication } from "../composables/useAuthentication.js";
|
|
3
3
|
import { hasPermission, isWhitelisted } from "../utils/permissions.js";
|
|
4
4
|
import { NO_AUTH_PATHS, NO_AUTH_API_PATHS } from "../constants.js";
|
|
5
|
-
export default defineNuxtRouteMiddleware((to) => {
|
|
5
|
+
export default defineNuxtRouteMiddleware(async (to) => {
|
|
6
6
|
const { public: { nuxtUsers: publicNuxtUsers } } = useRuntimeConfig();
|
|
7
7
|
const publicOptions = publicNuxtUsers;
|
|
8
8
|
const base = publicOptions.apiBasePath || "/api/nuxt-users";
|
|
@@ -18,7 +18,14 @@ export default defineNuxtRouteMiddleware((to) => {
|
|
|
18
18
|
console.log(`[Nuxt Users] client.middleware.auth.global: Whitelisted: ${to.path}`);
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
-
const { isAuthenticated, user } = useAuthentication();
|
|
21
|
+
const { isAuthenticated, user, fetchUser } = useAuthentication();
|
|
22
|
+
if (!isAuthenticated.value && to.query?.oauth_success === "true") {
|
|
23
|
+
try {
|
|
24
|
+
await fetchUser(true);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error("[Nuxt Users] Failed to fetch user after OAuth:", error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
22
29
|
if (!isAuthenticated.value) {
|
|
23
30
|
console.log(`[Nuxt Users] client.middleware.auth.global: Unauthenticated ${to.path}, redirecting to /login`);
|
|
24
31
|
return navigateTo("/login");
|
|
@@ -27,9 +34,4 @@ export default defineNuxtRouteMiddleware((to) => {
|
|
|
27
34
|
console.log(`[Nuxt Users] client.middleware.auth.global: User with role ${user.value?.role} denied access to ${to.path}`);
|
|
28
35
|
return navigateTo("/login");
|
|
29
36
|
}
|
|
30
|
-
console.log("[Nuxt Users] client.middleware.auth.global", {
|
|
31
|
-
isAuthenticated: isAuthenticated.value,
|
|
32
|
-
userRole: user.value?.role,
|
|
33
|
-
to: to.path
|
|
34
|
-
});
|
|
35
37
|
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { defineEventHandler, sendRedirect, getQuery, setCookie } from "h3";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
import {
|
|
4
|
+
createGoogleOAuth2Client,
|
|
5
|
+
getGoogleUserFromCode,
|
|
6
|
+
findOrCreateGoogleUser,
|
|
7
|
+
createAuthTokenForUser
|
|
8
|
+
} from "../../../../utils/google-oauth.js";
|
|
9
|
+
export default defineEventHandler(async (event) => {
|
|
10
|
+
const { nuxtUsers } = useRuntimeConfig();
|
|
11
|
+
const options = nuxtUsers;
|
|
12
|
+
const query = getQuery(event);
|
|
13
|
+
if (!options.auth.google) {
|
|
14
|
+
return sendRedirect(event, "/login?error=oauth_not_configured");
|
|
15
|
+
}
|
|
16
|
+
if (query.error) {
|
|
17
|
+
console.error("[Nuxt Users] Google OAuth error:", query.error);
|
|
18
|
+
const errorRedirect = options.auth.google.errorRedirect || "/login?error=oauth_failed";
|
|
19
|
+
return sendRedirect(event, errorRedirect);
|
|
20
|
+
}
|
|
21
|
+
if (!query.code || typeof query.code !== "string") {
|
|
22
|
+
console.error("[Nuxt Users] Missing authorization code in OAuth callback");
|
|
23
|
+
const errorRedirect = options.auth.google.errorRedirect || "/login?error=oauth_failed";
|
|
24
|
+
return sendRedirect(event, errorRedirect);
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const baseUrl = getRequestURL(event).origin;
|
|
28
|
+
const callbackPath = options.auth.google.callbackUrl || `${options.apiBasePath}/auth/google/callback`;
|
|
29
|
+
const callbackUrl = `${baseUrl}${callbackPath}`;
|
|
30
|
+
const oauth2Client = createGoogleOAuth2Client(options.auth.google, callbackUrl);
|
|
31
|
+
const googleUser = await getGoogleUserFromCode(oauth2Client, query.code);
|
|
32
|
+
const user = await findOrCreateGoogleUser(googleUser, options);
|
|
33
|
+
if (!user) {
|
|
34
|
+
console.warn(`[Nuxt Users] User not registered attempted Google OAuth login: ${googleUser.email}`);
|
|
35
|
+
const errorRedirect = options.auth.google.errorRedirect || "/login?error=user_not_registered";
|
|
36
|
+
return sendRedirect(event, errorRedirect);
|
|
37
|
+
}
|
|
38
|
+
if (!user.active) {
|
|
39
|
+
console.warn(`[Nuxt Users] Inactive user attempted Google OAuth login: ${user.email}`);
|
|
40
|
+
const errorRedirect = options.auth.google.errorRedirect || "/login?error=account_inactive";
|
|
41
|
+
return sendRedirect(event, errorRedirect);
|
|
42
|
+
}
|
|
43
|
+
const token = await createAuthTokenForUser(user, options, true);
|
|
44
|
+
const cookieOptions = {
|
|
45
|
+
httpOnly: true,
|
|
46
|
+
secure: process.env.NODE_ENV === "production",
|
|
47
|
+
sameSite: "lax",
|
|
48
|
+
path: "/",
|
|
49
|
+
maxAge: 60 * 60 * 24 * (options.auth.rememberMeExpiration || 30)
|
|
50
|
+
// 30 days default
|
|
51
|
+
};
|
|
52
|
+
setCookie(event, "auth_token", token, cookieOptions);
|
|
53
|
+
console.log(`[Nuxt Users] Google OAuth login successful for user: ${user.email}`);
|
|
54
|
+
const successRedirect = options.auth.google.successRedirect || "/";
|
|
55
|
+
const redirectUrl = successRedirect.includes("?") ? `${successRedirect}&oauth_success=true` : `${successRedirect}?oauth_success=true`;
|
|
56
|
+
return sendRedirect(event, redirectUrl);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error("[Nuxt Users] Google OAuth callback error:", error);
|
|
59
|
+
const errorRedirect = options.auth.google?.errorRedirect || "/login?error=oauth_failed";
|
|
60
|
+
return sendRedirect(event, errorRedirect);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const getRequestURL = (event) => {
|
|
64
|
+
const headers = event.node.req.headers;
|
|
65
|
+
const host = headers.host || headers[":authority"];
|
|
66
|
+
const protocol = headers["x-forwarded-proto"] || "https";
|
|
67
|
+
return new URL(`${protocol}://${host}`);
|
|
68
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { defineEventHandler, sendRedirect, createError } from "h3";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
import { createGoogleOAuth2Client, getGoogleAuthUrl } from "../../../../utils/google-oauth.js";
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const { nuxtUsers } = useRuntimeConfig();
|
|
6
|
+
const options = nuxtUsers;
|
|
7
|
+
if (!options.auth.google) {
|
|
8
|
+
throw createError({
|
|
9
|
+
statusCode: 500,
|
|
10
|
+
statusMessage: "Google OAuth is not configured"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
if (!options.auth.google.clientId || !options.auth.google.clientSecret) {
|
|
14
|
+
throw createError({
|
|
15
|
+
statusCode: 500,
|
|
16
|
+
statusMessage: "Google OAuth client ID and secret are required"
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const baseUrl = getRequestURL(event).origin;
|
|
21
|
+
const callbackPath = options.auth.google.callbackUrl || `${options.apiBasePath}/auth/google/callback`;
|
|
22
|
+
const callbackUrl = `${baseUrl}${callbackPath}`;
|
|
23
|
+
const oauth2Client = createGoogleOAuth2Client(options.auth.google, callbackUrl);
|
|
24
|
+
const authUrl = getGoogleAuthUrl(oauth2Client, options.auth.google);
|
|
25
|
+
return sendRedirect(event, authUrl);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error("[Nuxt Users] Google OAuth redirect error:", error);
|
|
28
|
+
throw createError({
|
|
29
|
+
statusCode: 500,
|
|
30
|
+
statusMessage: "Failed to initiate Google OAuth"
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const getRequestURL = (event) => {
|
|
35
|
+
const headers = event.node.req.headers;
|
|
36
|
+
const host = headers.host || headers[":authority"];
|
|
37
|
+
const protocol = headers["x-forwarded-proto"];
|
|
38
|
+
return new URL(`${protocol}://${host}`);
|
|
39
|
+
};
|
|
@@ -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]
|
|
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]
|
|
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}}
|
|
@@ -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;
|