nuxt-users 1.38.0 → 1.39.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/README.md +5 -1
- package/dist/cli.mjs +10 -6
- package/dist/module.d.mts +1 -1
- package/dist/module.d.ts +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +12 -3
- package/dist/runtime/components/NUsersEmailConfirmation.d.vue.ts +5 -3
- package/dist/runtime/components/NUsersEmailConfirmation.vue +22 -15
- package/dist/runtime/components/NUsersEmailConfirmation.vue.d.ts +5 -3
- package/dist/runtime/components/NUsersGoogleLoginButton.d.vue.ts +4 -2
- package/dist/runtime/components/NUsersGoogleLoginButton.vue +5 -2
- package/dist/runtime/components/NUsersGoogleLoginButton.vue.d.ts +4 -2
- package/dist/runtime/components/NUsersList.vue +25 -11
- package/dist/runtime/components/NUsersLoginForm.d.vue.ts +13 -2
- package/dist/runtime/components/NUsersLoginForm.vue +35 -13
- package/dist/runtime/components/NUsersLoginForm.vue.d.ts +13 -2
- package/dist/runtime/components/NUsersLogoutLink.d.vue.ts +3 -4
- package/dist/runtime/components/NUsersLogoutLink.vue +8 -5
- package/dist/runtime/components/NUsersLogoutLink.vue.d.ts +3 -4
- package/dist/runtime/components/NUsersPasswordStrengthIndicator.d.vue.ts +6 -0
- package/dist/runtime/components/NUsersPasswordStrengthIndicator.vue +17 -9
- package/dist/runtime/components/NUsersPasswordStrengthIndicator.vue.d.ts +6 -0
- package/dist/runtime/components/NUsersProfileInfo.d.vue.ts +13 -1
- package/dist/runtime/components/NUsersProfileInfo.vue +23 -9
- package/dist/runtime/components/NUsersProfileInfo.vue.d.ts +13 -1
- package/dist/runtime/components/NUsersRegisterForm.d.vue.ts +26 -11
- package/dist/runtime/components/NUsersRegisterForm.vue +34 -16
- package/dist/runtime/components/NUsersRegisterForm.vue.d.ts +26 -11
- package/dist/runtime/components/NUsersResetPasswordForm.d.vue.ts +11 -2
- package/dist/runtime/components/NUsersResetPasswordForm.vue +25 -12
- package/dist/runtime/components/NUsersResetPasswordForm.vue.d.ts +11 -2
- package/dist/runtime/components/NUsersUserCard.d.vue.ts +2 -0
- package/dist/runtime/components/NUsersUserCard.vue +8 -4
- package/dist/runtime/components/NUsersUserCard.vue.d.ts +2 -0
- package/dist/runtime/components/NUsersUserForm.d.vue.ts +2 -2
- package/dist/runtime/components/NUsersUserForm.vue +5 -4
- package/dist/runtime/components/NUsersUserForm.vue.d.ts +2 -2
- package/dist/runtime/composables/useNuxtUsersLocale.d.ts +15 -0
- package/dist/runtime/composables/useNuxtUsersLocale.js +27 -0
- package/dist/runtime/composables/usePasswordValidation.d.ts +1 -1
- package/dist/runtime/composables/usePublicPaths.js +2 -1
- package/dist/runtime/locales/en.d.ts +2 -0
- package/dist/runtime/locales/en.js +130 -0
- package/dist/runtime/locales/hu.d.ts +3 -0
- package/dist/runtime/locales/hu.js +188 -0
- package/dist/runtime/locales/index.d.ts +5 -0
- package/dist/runtime/locales/index.js +8 -0
- package/dist/runtime/server/api/nuxt-users/confirm-email.get.js +3 -3
- package/dist/runtime/server/api/nuxt-users/password/forgot.post.js +2 -1
- package/dist/runtime/server/api/nuxt-users/password/reset.post.d.ts +1 -1
- package/dist/runtime/server/api/nuxt-users/password/reset.post.js +4 -2
- package/dist/runtime/server/api/nuxt-users/session/index.post.js +4 -2
- package/dist/runtime/server/middleware/authorization.server.js +6 -3
- package/dist/runtime/server/utils/google-oauth.js +2 -1
- package/dist/runtime/utils/deep-merge.d.ts +8 -0
- package/dist/runtime/utils/deep-merge.js +17 -0
- package/dist/runtime/utils/locale.d.ts +14 -0
- package/dist/runtime/utils/locale.js +38 -0
- package/dist/shared/{nuxt-users.BnOQs2LI.mjs → nuxt-users.DfZ7bc_P.mjs} +16 -8
- package/dist/shared/{nuxt-users.SXaMnaEL.d.mts → nuxt-users.FiQjvlZl.d.mts} +40 -2
- package/dist/shared/{nuxt-users.SXaMnaEL.d.ts → nuxt-users.FiQjvlZl.d.ts} +40 -2
- package/dist/utils.d.mts +4 -1
- package/dist/utils.d.ts +4 -1
- package/dist/utils.mjs +4 -1
- package/package.json +5 -3
- package/scripts/check-locale-consistency.ts +156 -0
- package/scripts/check-peer-dependencies.js +5 -5
- package/scripts/check-translations.ts +255 -0
- package/scripts/post-build.js +1 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ A user authentication module for Nuxt 3 and Nuxt 4 with database support for SQL
|
|
|
39
39
|
|
|
40
40
|
MIT
|
|
41
41
|
|
|
42
|
-
## Dev
|
|
42
|
+
## Dev Misc
|
|
43
43
|
|
|
44
44
|
### Using yalc
|
|
45
45
|
|
|
@@ -49,4 +49,8 @@ yalc publish
|
|
|
49
49
|
|
|
50
50
|
# Install the module in the consumer app
|
|
51
51
|
yalc add nuxt-users
|
|
52
|
+
|
|
53
|
+
# Clean up consumer app
|
|
54
|
+
yalc remove nuxt-users
|
|
55
|
+
yarn add nuxt-users
|
|
52
56
|
```
|
package/dist/cli.mjs
CHANGED
|
@@ -5,7 +5,10 @@ import { defaultOptions } from './module.mjs';
|
|
|
5
5
|
import { loadNuxt } from '@nuxt/kit';
|
|
6
6
|
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
|
-
import { g as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.
|
|
8
|
+
import { g as getPasswordValidationOptions, v as validatePassword } from './shared/nuxt-users.DfZ7bc_P.mjs';
|
|
9
|
+
import '../dist/runtime/locales/index.js';
|
|
10
|
+
import '../dist/runtime/utils/locale.js';
|
|
11
|
+
import '../dist/runtime/utils/deep-merge.js';
|
|
9
12
|
import { addActiveToUsers as addActiveToUsers$1 } from '../dist/runtime/server/utils/add-active-to-users.js';
|
|
10
13
|
import { useDb, checkTableExists } from '../dist/runtime/server/utils/db.js';
|
|
11
14
|
import { getAppliedMigrations } from '../dist/runtime/server/utils/migrate.js';
|
|
@@ -75,10 +78,9 @@ const loadOptions = async () => {
|
|
|
75
78
|
};
|
|
76
79
|
}
|
|
77
80
|
return mergedConfig;
|
|
78
|
-
} else {
|
|
79
|
-
console.log("[Nuxt Users] No nuxt-users configuration found, using environment variables");
|
|
80
|
-
return getOptionsFromEnv();
|
|
81
81
|
}
|
|
82
|
+
console.log("[Nuxt Users] No nuxt-users configuration found, using environment variables");
|
|
83
|
+
return getOptionsFromEnv();
|
|
82
84
|
} catch (error) {
|
|
83
85
|
console.log("[Nuxt Users] Could not load Nuxt project, using environment variables");
|
|
84
86
|
console.error("[Nuxt Users] Error:", error);
|
|
@@ -369,14 +371,16 @@ const projectInfo = defineCommand({
|
|
|
369
371
|
console.log("[Nuxt Users] -", migration);
|
|
370
372
|
});
|
|
371
373
|
}
|
|
372
|
-
}
|
|
374
|
+
}
|
|
375
|
+
if (!migrationsTableExists) {
|
|
373
376
|
console.log("[Nuxt Users] Table exists: no \u274C");
|
|
374
377
|
console.log('[Nuxt Users] \u27A1\uFE0F Run "npx nuxt-users migrate" to set up the database');
|
|
375
378
|
}
|
|
376
379
|
} catch (error) {
|
|
377
380
|
console.log("[Nuxt Users] Status: \u26A0\uFE0F Error -", error instanceof Error ? error.message : "Unknown error");
|
|
378
381
|
}
|
|
379
|
-
}
|
|
382
|
+
}
|
|
383
|
+
if (!nuxtUsersConfig) {
|
|
380
384
|
console.log("[Nuxt Users] \u26A0\uFE0F Nuxt Users module not configured in runtime config");
|
|
381
385
|
}
|
|
382
386
|
} catch (error) {
|
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.FiQjvlZl.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.FiQjvlZl.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
|
@@ -50,7 +50,12 @@ const defaultOptions = {
|
|
|
50
50
|
requireSpecialChars: true,
|
|
51
51
|
preventCommonPasswords: true
|
|
52
52
|
},
|
|
53
|
-
hardDelete: false
|
|
53
|
+
hardDelete: false,
|
|
54
|
+
locale: {
|
|
55
|
+
default: "en",
|
|
56
|
+
fallbackLocale: "en",
|
|
57
|
+
texts: {}
|
|
58
|
+
}
|
|
54
59
|
};
|
|
55
60
|
const module$1 = defineNuxtModule({
|
|
56
61
|
meta: {
|
|
@@ -63,6 +68,9 @@ const module$1 = defineNuxtModule({
|
|
|
63
68
|
const resolver = createResolver(import.meta.url);
|
|
64
69
|
const { connector: _defaultConnector, ...defaultsWithoutConnector } = defaultOptions;
|
|
65
70
|
const runtimeConfigOptions = defu(nuxt.options.runtimeConfig.nuxtUsers || {}, options, defaultsWithoutConnector);
|
|
71
|
+
if (!runtimeConfigOptions.locale) {
|
|
72
|
+
runtimeConfigOptions.locale = defaultOptions.locale;
|
|
73
|
+
}
|
|
66
74
|
const configuredConnector = nuxt.options.runtimeConfig.nuxtUsers?.connector || options.connector;
|
|
67
75
|
runtimeConfigOptions.connector = configuredConnector || defaultOptions.connector;
|
|
68
76
|
nuxt.options.runtimeConfig.nuxtUsers = {
|
|
@@ -108,6 +116,7 @@ const module$1 = defineNuxtModule({
|
|
|
108
116
|
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
109
117
|
nuxt.options.runtimeConfig.public.nuxtUsers = {
|
|
110
118
|
passwordValidation: runtimeConfigOptions.passwordValidation,
|
|
119
|
+
locale: runtimeConfigOptions.locale,
|
|
111
120
|
auth: {
|
|
112
121
|
whitelist: (() => {
|
|
113
122
|
const combinedWhitelist = [...defaultOptions.auth?.whitelist || [], ...runtimeConfigOptions.auth?.whitelist || []];
|
|
@@ -163,7 +172,7 @@ const module$1 = defineNuxtModule({
|
|
|
163
172
|
path: resolver.resolve("./runtime/middleware/authorization.client"),
|
|
164
173
|
global: true
|
|
165
174
|
});
|
|
166
|
-
const base =
|
|
175
|
+
const base = runtimeConfigOptions.apiBasePath || defaultOptions.apiBasePath;
|
|
167
176
|
addServerHandler({
|
|
168
177
|
route: `${base}/session`,
|
|
169
178
|
method: "post",
|
|
@@ -252,7 +261,7 @@ const module$1 = defineNuxtModule({
|
|
|
252
261
|
nitroConfig.scanDirs.push(resolver.resolve("./runtime/server/tasks"));
|
|
253
262
|
nitroConfig.prerender = nitroConfig.prerender || {};
|
|
254
263
|
nitroConfig.prerender.ignore = nitroConfig.prerender.ignore || [];
|
|
255
|
-
const apiBasePath =
|
|
264
|
+
const apiBasePath = runtimeConfigOptions.apiBasePath || defaultOptions.apiBasePath;
|
|
256
265
|
const ignorePattern = `${apiBasePath}/**`;
|
|
257
266
|
if (!nitroConfig.prerender.ignore.includes(ignorePattern)) {
|
|
258
267
|
nitroConfig.prerender.ignore.push(ignorePattern);
|
|
@@ -2,6 +2,11 @@ interface Props {
|
|
|
2
2
|
successTitle?: string;
|
|
3
3
|
errorTitle?: string;
|
|
4
4
|
loginButtonText?: string;
|
|
5
|
+
backToLoginText?: string;
|
|
6
|
+
processingTitle?: string;
|
|
7
|
+
processingMessage?: string;
|
|
8
|
+
successMessage?: string;
|
|
9
|
+
errorMessage?: string;
|
|
5
10
|
loginUrl?: string;
|
|
6
11
|
showLoginButton?: boolean;
|
|
7
12
|
}
|
|
@@ -22,9 +27,6 @@ type __VLS_Slots = {} & {
|
|
|
22
27
|
'loading-content'?: (props: typeof __VLS_13) => any;
|
|
23
28
|
};
|
|
24
29
|
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
30
|
loginUrl: string;
|
|
29
31
|
showLoginButton: boolean;
|
|
30
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import { useRoute } from "#app";
|
|
4
|
+
import { useNuxtUsersLocale } from "../composables/useNuxtUsersLocale";
|
|
5
|
+
const { t } = useNuxtUsersLocale();
|
|
4
6
|
const route = useRoute();
|
|
5
7
|
const status = computed(() => route.query.status);
|
|
6
8
|
const message = computed(() => route.query.message);
|
|
7
9
|
const isSuccess = computed(() => status.value === "success");
|
|
8
10
|
const isError = computed(() => status.value === "error");
|
|
9
11
|
const _props = defineProps({
|
|
10
|
-
successTitle: { type: String, required: false
|
|
11
|
-
errorTitle: { type: String, required: false
|
|
12
|
-
loginButtonText: { type: String, required: false
|
|
12
|
+
successTitle: { type: String, required: false },
|
|
13
|
+
errorTitle: { type: String, required: false },
|
|
14
|
+
loginButtonText: { type: String, required: false },
|
|
15
|
+
backToLoginText: { type: String, required: false },
|
|
16
|
+
processingTitle: { type: String, required: false },
|
|
17
|
+
processingMessage: { type: String, required: false },
|
|
18
|
+
successMessage: { type: String, required: false },
|
|
19
|
+
errorMessage: { type: String, required: false },
|
|
13
20
|
loginUrl: { type: String, required: false, default: "/login" },
|
|
14
21
|
showLoginButton: { type: Boolean, required: false, default: true }
|
|
15
22
|
});
|
|
@@ -44,10 +51,10 @@ const _props = defineProps({
|
|
|
44
51
|
<div class="n-users-section-header">
|
|
45
52
|
<slot name="success-content">
|
|
46
53
|
<h1 class="n-users-login-title">
|
|
47
|
-
{{ successTitle }}
|
|
54
|
+
{{ _props.successTitle || t("emailConfirmation.successTitle") }}
|
|
48
55
|
</h1>
|
|
49
56
|
<div class="n-users-success-message">
|
|
50
|
-
{{ message ||
|
|
57
|
+
{{ message || _props.successMessage || t("emailConfirmation.successMessage") }}
|
|
51
58
|
</div>
|
|
52
59
|
</slot>
|
|
53
60
|
</div>
|
|
@@ -58,10 +65,10 @@ const _props = defineProps({
|
|
|
58
65
|
class="n-users-form-actions"
|
|
59
66
|
>
|
|
60
67
|
<a
|
|
61
|
-
:href="loginUrl"
|
|
68
|
+
:href="_props.loginUrl"
|
|
62
69
|
class="n-users-btn n-users-btn-primary"
|
|
63
70
|
>
|
|
64
|
-
{{ loginButtonText }}
|
|
71
|
+
{{ _props.loginButtonText || t("emailConfirmation.loginButton") }}
|
|
65
72
|
</a>
|
|
66
73
|
</div>
|
|
67
74
|
</slot>
|
|
@@ -69,7 +76,7 @@ const _props = defineProps({
|
|
|
69
76
|
|
|
70
77
|
<!-- Error state -->
|
|
71
78
|
<div
|
|
72
|
-
v-
|
|
79
|
+
v-if="isError"
|
|
73
80
|
class="n-users-confirmation-content"
|
|
74
81
|
>
|
|
75
82
|
<slot name="error-icon">
|
|
@@ -104,10 +111,10 @@ const _props = defineProps({
|
|
|
104
111
|
<div class="n-users-section-header">
|
|
105
112
|
<slot name="error-content">
|
|
106
113
|
<h1 class="n-users-login-title">
|
|
107
|
-
{{ errorTitle }}
|
|
114
|
+
{{ _props.errorTitle || t("emailConfirmation.errorTitle") }}
|
|
108
115
|
</h1>
|
|
109
116
|
<div class="n-users-error-message">
|
|
110
|
-
{{ message ||
|
|
117
|
+
{{ message || _props.errorMessage || t("emailConfirmation.errorMessage") }}
|
|
111
118
|
</div>
|
|
112
119
|
</slot>
|
|
113
120
|
</div>
|
|
@@ -115,10 +122,10 @@ const _props = defineProps({
|
|
|
115
122
|
<slot name="error-actions">
|
|
116
123
|
<div class="n-users-form-actions">
|
|
117
124
|
<a
|
|
118
|
-
:href="loginUrl"
|
|
125
|
+
:href="_props.loginUrl"
|
|
119
126
|
class="n-users-btn n-users-btn-secondary"
|
|
120
127
|
>
|
|
121
|
-
|
|
128
|
+
{{ _props.backToLoginText || t("emailConfirmation.backToLogin") }}
|
|
122
129
|
</a>
|
|
123
130
|
</div>
|
|
124
131
|
</slot>
|
|
@@ -126,7 +133,7 @@ const _props = defineProps({
|
|
|
126
133
|
|
|
127
134
|
<!-- Loading/unknown state -->
|
|
128
135
|
<div
|
|
129
|
-
v-
|
|
136
|
+
v-if="!isError"
|
|
130
137
|
class="n-users-confirmation-content"
|
|
131
138
|
>
|
|
132
139
|
<slot name="loading-content">
|
|
@@ -135,10 +142,10 @@ const _props = defineProps({
|
|
|
135
142
|
</div>
|
|
136
143
|
<div class="n-users-section-header">
|
|
137
144
|
<h1 class="n-users-login-title">
|
|
138
|
-
|
|
145
|
+
{{ _props.processingTitle || t("emailConfirmation.processing") }}
|
|
139
146
|
</h1>
|
|
140
147
|
<div class="n-users-form-help">
|
|
141
|
-
|
|
148
|
+
{{ _props.processingMessage || t("emailConfirmation.processingMessage") }}
|
|
142
149
|
</div>
|
|
143
150
|
</div>
|
|
144
151
|
</slot>
|
|
@@ -2,6 +2,11 @@ interface Props {
|
|
|
2
2
|
successTitle?: string;
|
|
3
3
|
errorTitle?: string;
|
|
4
4
|
loginButtonText?: string;
|
|
5
|
+
backToLoginText?: string;
|
|
6
|
+
processingTitle?: string;
|
|
7
|
+
processingMessage?: string;
|
|
8
|
+
successMessage?: string;
|
|
9
|
+
errorMessage?: string;
|
|
5
10
|
loginUrl?: string;
|
|
6
11
|
showLoginButton?: boolean;
|
|
7
12
|
}
|
|
@@ -22,9 +27,6 @@ type __VLS_Slots = {} & {
|
|
|
22
27
|
'loading-content'?: (props: typeof __VLS_13) => any;
|
|
23
28
|
};
|
|
24
29
|
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
30
|
loginUrl: string;
|
|
29
31
|
showLoginButton: boolean;
|
|
30
32
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -6,9 +6,12 @@ interface Props {
|
|
|
6
6
|
redirectEndpoint?: string;
|
|
7
7
|
/**
|
|
8
8
|
* Button text
|
|
9
|
-
* @default 'Continue with Google'
|
|
10
9
|
*/
|
|
11
10
|
buttonText?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Redirecting text
|
|
13
|
+
*/
|
|
14
|
+
redirectingText?: string;
|
|
12
15
|
/**
|
|
13
16
|
* Show Google logo in button
|
|
14
17
|
* @default true
|
|
@@ -24,7 +27,6 @@ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {},
|
|
|
24
27
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
25
28
|
onClick?: (() => any) | undefined;
|
|
26
29
|
}>, {
|
|
27
|
-
buttonText: string;
|
|
28
30
|
showLogo: boolean;
|
|
29
31
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
32
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed } from "vue";
|
|
3
3
|
import { useRuntimeConfig, navigateTo } from "#imports";
|
|
4
|
+
import { useNuxtUsersLocale } from "../composables/useNuxtUsersLocale";
|
|
5
|
+
const { t } = useNuxtUsersLocale();
|
|
4
6
|
const props = defineProps({
|
|
5
7
|
redirectEndpoint: { type: String, required: false },
|
|
6
|
-
buttonText: { type: String, required: false
|
|
8
|
+
buttonText: { type: String, required: false },
|
|
9
|
+
redirectingText: { type: String, required: false },
|
|
7
10
|
showLogo: { type: Boolean, required: false, default: true },
|
|
8
11
|
class: { type: String, required: false }
|
|
9
12
|
});
|
|
@@ -69,7 +72,7 @@ const handleGoogleLogin = async () => {
|
|
|
69
72
|
|
|
70
73
|
<!-- Button text -->
|
|
71
74
|
<span class="n-users-google-text">
|
|
72
|
-
{{ isLoading ? "
|
|
75
|
+
{{ isLoading ? props.redirectingText || t("googleLogin.redirecting") : props.buttonText || t("googleLogin.buttonText") }}
|
|
73
76
|
</span>
|
|
74
77
|
</button>
|
|
75
78
|
</template>
|
|
@@ -6,9 +6,12 @@ interface Props {
|
|
|
6
6
|
redirectEndpoint?: string;
|
|
7
7
|
/**
|
|
8
8
|
* Button text
|
|
9
|
-
* @default 'Continue with Google'
|
|
10
9
|
*/
|
|
11
10
|
buttonText?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Redirecting text
|
|
13
|
+
*/
|
|
14
|
+
redirectingText?: string;
|
|
12
15
|
/**
|
|
13
16
|
* Show Google logo in button
|
|
14
17
|
* @default true
|
|
@@ -24,7 +27,6 @@ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {},
|
|
|
24
27
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
25
28
|
onClick?: (() => any) | undefined;
|
|
26
29
|
}>, {
|
|
27
|
-
buttonText: string;
|
|
28
30
|
showLogo: boolean;
|
|
29
31
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
30
32
|
declare const _default: typeof __VLS_export;
|
|
@@ -2,10 +2,24 @@
|
|
|
2
2
|
import { onMounted, computed, ref } from "vue";
|
|
3
3
|
import { useUsers } from "../composables/useUsers";
|
|
4
4
|
import { defaultDisplayFields, defaultFieldLabels } from "nuxt-users/utils";
|
|
5
|
+
import { useNuxtUsersLocale } from "../composables/useNuxtUsersLocale";
|
|
6
|
+
const { t } = useNuxtUsersLocale();
|
|
5
7
|
const props = defineProps({
|
|
6
8
|
displayFields: { type: Array, required: false, default: () => defaultDisplayFields },
|
|
7
9
|
fieldLabels: { type: Object, required: false, default: () => defaultFieldLabels },
|
|
8
|
-
filter: { type: [Object, Function], required: false, default: () => ({}) }
|
|
10
|
+
filter: { type: [Object, Function], required: false, default: () => ({}) },
|
|
11
|
+
title: { type: String, required: false },
|
|
12
|
+
loadingText: { type: String, required: false },
|
|
13
|
+
noUsersText: { type: String, required: false },
|
|
14
|
+
errorText: { type: String, required: false },
|
|
15
|
+
editButtonText: { type: String, required: false },
|
|
16
|
+
deleteButtonText: { type: String, required: false },
|
|
17
|
+
pageText: { type: String, required: false },
|
|
18
|
+
ofText: { type: String, required: false },
|
|
19
|
+
totalText: { type: String, required: false },
|
|
20
|
+
usersText: { type: String, required: false },
|
|
21
|
+
previousText: { type: String, required: false },
|
|
22
|
+
nextText: { type: String, required: false }
|
|
9
23
|
});
|
|
10
24
|
const emit = defineEmits(["editClick", "delete"]);
|
|
11
25
|
const usersComposable = ref(null);
|
|
@@ -59,7 +73,7 @@ const handleFetchUsers = (page, limit) => {
|
|
|
59
73
|
<div class="n-users-list">
|
|
60
74
|
<slot name="title">
|
|
61
75
|
<h2>
|
|
62
|
-
|
|
76
|
+
{{ props.title || t("usersList.title") }}
|
|
63
77
|
</h2>
|
|
64
78
|
</slot>
|
|
65
79
|
|
|
@@ -68,7 +82,7 @@ const handleFetchUsers = (page, limit) => {
|
|
|
68
82
|
:loading="loading"
|
|
69
83
|
>
|
|
70
84
|
<div v-if="loading">
|
|
71
|
-
|
|
85
|
+
{{ props.loadingText || t("usersList.loading") }}
|
|
72
86
|
</div>
|
|
73
87
|
</slot>
|
|
74
88
|
|
|
@@ -77,13 +91,13 @@ const handleFetchUsers = (page, limit) => {
|
|
|
77
91
|
:error="error"
|
|
78
92
|
>
|
|
79
93
|
<div v-if="error">
|
|
80
|
-
|
|
94
|
+
{{ props.errorText || t("usersList.error") }} {{ error }}
|
|
81
95
|
</div>
|
|
82
96
|
</slot>
|
|
83
97
|
|
|
84
98
|
<slot name="noUsers">
|
|
85
99
|
<div v-if="users.length === 0">
|
|
86
|
-
|
|
100
|
+
{{ props.noUsersText || t("usersList.noUsers") }}
|
|
87
101
|
</div>
|
|
88
102
|
</slot>
|
|
89
103
|
|
|
@@ -126,7 +140,7 @@ const handleFetchUsers = (page, limit) => {
|
|
|
126
140
|
class="n-users-edit-btn"
|
|
127
141
|
@click="editUserFn"
|
|
128
142
|
>
|
|
129
|
-
|
|
143
|
+
{{ props.editButtonText || t("common.edit") }}
|
|
130
144
|
</button>
|
|
131
145
|
</slot>
|
|
132
146
|
</template>
|
|
@@ -142,7 +156,7 @@ const handleFetchUsers = (page, limit) => {
|
|
|
142
156
|
class="n-users-delete-btn"
|
|
143
157
|
@click="deleteUserFn"
|
|
144
158
|
>
|
|
145
|
-
|
|
159
|
+
{{ props.deleteButtonText || t("common.delete") }}
|
|
146
160
|
</button>
|
|
147
161
|
</slot>
|
|
148
162
|
</template>
|
|
@@ -210,8 +224,8 @@ const handleFetchUsers = (page, limit) => {
|
|
|
210
224
|
>
|
|
211
225
|
<div v-if="pagination && pagination.totalPages > 1">
|
|
212
226
|
<div>
|
|
213
|
-
<span>
|
|
214
|
-
<span>
|
|
227
|
+
<span>{{ props.pageText || t("usersList.page") }} {{ pagination.page }} {{ props.ofText || t("usersList.of") }} {{ pagination.totalPages }}</span>
|
|
228
|
+
<span>{{ props.totalText || t("usersList.total") }} {{ pagination.total }} {{ props.usersText || t("usersList.users") }}</span>
|
|
215
229
|
</div>
|
|
216
230
|
</div>
|
|
217
231
|
</slot>
|
|
@@ -229,7 +243,7 @@ const handleFetchUsers = (page, limit) => {
|
|
|
229
243
|
:disabled="loading"
|
|
230
244
|
@click="handleFetchUsers(pagination.page - 1)"
|
|
231
245
|
>
|
|
232
|
-
|
|
246
|
+
{{ props.previousText || t("usersList.previous") }}
|
|
233
247
|
</button>
|
|
234
248
|
|
|
235
249
|
<button
|
|
@@ -237,7 +251,7 @@ const handleFetchUsers = (page, limit) => {
|
|
|
237
251
|
:disabled="loading"
|
|
238
252
|
@click="handleFetchUsers(pagination.page + 1)"
|
|
239
253
|
>
|
|
240
|
-
|
|
254
|
+
{{ props.nextText || t("usersList.next") }}
|
|
241
255
|
</button>
|
|
242
256
|
</div>
|
|
243
257
|
</div>
|
|
@@ -2,6 +2,17 @@ interface Props {
|
|
|
2
2
|
apiEndpoint?: string;
|
|
3
3
|
forgotPasswordEndpoint?: string;
|
|
4
4
|
redirectTo?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
emailLabel?: string;
|
|
8
|
+
emailPlaceholder?: string;
|
|
9
|
+
passwordLabel?: string;
|
|
10
|
+
passwordPlaceholder?: string;
|
|
11
|
+
rememberMeLabel?: string;
|
|
12
|
+
submitLabel?: string;
|
|
13
|
+
submittingLabel?: string;
|
|
14
|
+
forgotPasswordLabel?: string;
|
|
15
|
+
forgotPasswordSendingLabel?: string;
|
|
5
16
|
}
|
|
6
17
|
declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_11: {}, __VLS_13: {
|
|
7
18
|
message: string;
|
|
@@ -26,15 +37,15 @@ type __VLS_Slots = {} & {
|
|
|
26
37
|
'error-message'?: (props: typeof __VLS_15) => any;
|
|
27
38
|
};
|
|
28
39
|
declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
29
|
-
success: (user: UserWithoutPassword, rememberMe: boolean) => any;
|
|
30
40
|
error: (error: string) => any;
|
|
31
41
|
submit: (data: LoginFormData) => any;
|
|
42
|
+
success: (user: UserWithoutPassword, rememberMe: boolean) => any;
|
|
32
43
|
"forgot-password-error": (error: string) => any;
|
|
33
44
|
"forgot-password-success": () => any;
|
|
34
45
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
35
|
-
onSuccess?: ((user: UserWithoutPassword, rememberMe: boolean) => any) | undefined;
|
|
36
46
|
onError?: ((error: string) => any) | undefined;
|
|
37
47
|
onSubmit?: ((data: LoginFormData) => any) | undefined;
|
|
48
|
+
onSuccess?: ((user: UserWithoutPassword, rememberMe: boolean) => any) | undefined;
|
|
38
49
|
"onForgot-password-error"?: ((error: string) => any) | undefined;
|
|
39
50
|
"onForgot-password-success"?: (() => any) | undefined;
|
|
40
51
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -2,14 +2,36 @@
|
|
|
2
2
|
import { ref, computed } from "vue";
|
|
3
3
|
import { navigateTo } from "#app";
|
|
4
4
|
import { useRuntimeConfig } from "#imports";
|
|
5
|
+
import { useNuxtUsersLocale } from "../composables/useNuxtUsersLocale";
|
|
5
6
|
const { public: { nuxtUsers } } = useRuntimeConfig();
|
|
6
7
|
const { passwordValidation } = nuxtUsers;
|
|
8
|
+
const { t } = useNuxtUsersLocale();
|
|
7
9
|
const props = defineProps({
|
|
8
10
|
apiEndpoint: { type: String, required: false },
|
|
9
11
|
forgotPasswordEndpoint: { type: String, required: false },
|
|
10
|
-
redirectTo: { type: String, required: false }
|
|
12
|
+
redirectTo: { type: String, required: false },
|
|
13
|
+
title: { type: String, required: false },
|
|
14
|
+
subtitle: { type: String, required: false },
|
|
15
|
+
emailLabel: { type: String, required: false },
|
|
16
|
+
emailPlaceholder: { type: String, required: false },
|
|
17
|
+
passwordLabel: { type: String, required: false },
|
|
18
|
+
passwordPlaceholder: { type: String, required: false },
|
|
19
|
+
rememberMeLabel: { type: String, required: false },
|
|
20
|
+
submitLabel: { type: String, required: false },
|
|
21
|
+
submittingLabel: { type: String, required: false },
|
|
22
|
+
forgotPasswordLabel: { type: String, required: false },
|
|
23
|
+
forgotPasswordSendingLabel: { type: String, required: false }
|
|
11
24
|
});
|
|
12
25
|
const emit = defineEmits(["success", "error", "forgot-password-error", "submit", "forgot-password-success"]);
|
|
26
|
+
const extractErrorMessage = (err, defaultMessage) => {
|
|
27
|
+
if (err && typeof err === "object" && "data" in err && err.data && typeof err.data === "object" && "statusMessage" in err.data) {
|
|
28
|
+
return String(err.data.statusMessage);
|
|
29
|
+
}
|
|
30
|
+
if (err instanceof Error) {
|
|
31
|
+
return err.message;
|
|
32
|
+
}
|
|
33
|
+
return defaultMessage;
|
|
34
|
+
};
|
|
13
35
|
const apiEndpoint = computed(() => props.apiEndpoint || `${nuxtUsers?.apiBasePath}/session`);
|
|
14
36
|
const forgotPasswordEndpoint = computed(() => props.forgotPasswordEndpoint || `${nuxtUsers?.apiBasePath}/password/forgot`);
|
|
15
37
|
const isLoading = ref(false);
|
|
@@ -39,7 +61,7 @@ const handleSubmit = async () => {
|
|
|
39
61
|
await navigateTo(props.redirectTo);
|
|
40
62
|
}
|
|
41
63
|
} catch (err) {
|
|
42
|
-
const errorMessage = err
|
|
64
|
+
const errorMessage = extractErrorMessage(err, t("login.loginFailed"));
|
|
43
65
|
error.value = errorMessage;
|
|
44
66
|
emit("error", errorMessage);
|
|
45
67
|
} finally {
|
|
@@ -48,7 +70,7 @@ const handleSubmit = async () => {
|
|
|
48
70
|
};
|
|
49
71
|
const handleForgotPassword = async () => {
|
|
50
72
|
if (!formData.value.email) {
|
|
51
|
-
error.value = "
|
|
73
|
+
error.value = t("login.emailRequiredForForgotPassword");
|
|
52
74
|
return;
|
|
53
75
|
}
|
|
54
76
|
isForgotPasswordLoading.value = true;
|
|
@@ -64,7 +86,7 @@ const handleForgotPassword = async () => {
|
|
|
64
86
|
forgotPasswordMessage.value = response.message;
|
|
65
87
|
emit("forgot-password-success");
|
|
66
88
|
} catch (err) {
|
|
67
|
-
const errorMessage = err
|
|
89
|
+
const errorMessage = extractErrorMessage(err, t("login.forgotPasswordFailed"));
|
|
68
90
|
error.value = errorMessage;
|
|
69
91
|
emit("forgot-password-error", errorMessage);
|
|
70
92
|
} finally {
|
|
@@ -80,10 +102,10 @@ const handleForgotPassword = async () => {
|
|
|
80
102
|
<slot name="header">
|
|
81
103
|
<div class="n-users-login-header">
|
|
82
104
|
<h2 class="n-users-login-title">
|
|
83
|
-
|
|
105
|
+
{{ props.title || t("login.title") }}
|
|
84
106
|
</h2>
|
|
85
107
|
<p class="n-users-login-subtitle">
|
|
86
|
-
|
|
108
|
+
{{ props.subtitle || t("login.subtitle") }}
|
|
87
109
|
</p>
|
|
88
110
|
</div>
|
|
89
111
|
</slot>
|
|
@@ -91,13 +113,13 @@ const handleForgotPassword = async () => {
|
|
|
91
113
|
<!-- Email field -->
|
|
92
114
|
<slot name="email-field">
|
|
93
115
|
<div class="n-users-form-group">
|
|
94
|
-
<label for="email">
|
|
116
|
+
<label for="email">{{ props.emailLabel || t("common.email") }}</label>
|
|
95
117
|
<input
|
|
96
118
|
id="email"
|
|
97
119
|
v-model="formData.email"
|
|
98
120
|
type="email"
|
|
99
121
|
name="email"
|
|
100
|
-
placeholder="
|
|
122
|
+
:placeholder="props.emailPlaceholder || t('login.emailPlaceholder')"
|
|
101
123
|
required
|
|
102
124
|
>
|
|
103
125
|
</div>
|
|
@@ -106,13 +128,13 @@ const handleForgotPassword = async () => {
|
|
|
106
128
|
<!-- Password field -->
|
|
107
129
|
<slot name="password-field">
|
|
108
130
|
<div class="n-users-form-group">
|
|
109
|
-
<label for="password">
|
|
131
|
+
<label for="password">{{ props.passwordLabel || t("login.passwordLabel") }}</label>
|
|
110
132
|
<input
|
|
111
133
|
id="password"
|
|
112
134
|
v-model="formData.password"
|
|
113
135
|
type="password"
|
|
114
136
|
name="password"
|
|
115
|
-
placeholder="
|
|
137
|
+
:placeholder="props.passwordPlaceholder || t('login.passwordPlaceholder')"
|
|
116
138
|
required
|
|
117
139
|
:minlength="passwordValidation.minLength"
|
|
118
140
|
>
|
|
@@ -128,7 +150,7 @@ const handleForgotPassword = async () => {
|
|
|
128
150
|
type="checkbox"
|
|
129
151
|
name="rememberMe"
|
|
130
152
|
>
|
|
131
|
-
<label for="rememberMe">
|
|
153
|
+
<label for="rememberMe">{{ props.rememberMeLabel || t("login.rememberMe") }}</label>
|
|
132
154
|
</div>
|
|
133
155
|
</slot>
|
|
134
156
|
|
|
@@ -142,7 +164,7 @@ const handleForgotPassword = async () => {
|
|
|
142
164
|
v-if="isLoading"
|
|
143
165
|
class="n-users-loading-spinner"
|
|
144
166
|
/>
|
|
145
|
-
{{ isLoading ?
|
|
167
|
+
{{ isLoading ? props.submittingLabel || t("login.submitting") : props.submitLabel || t("login.submit") }}
|
|
146
168
|
</button>
|
|
147
169
|
</slot>
|
|
148
170
|
|
|
@@ -160,7 +182,7 @@ const handleForgotPassword = async () => {
|
|
|
160
182
|
v-if="isForgotPasswordLoading"
|
|
161
183
|
class="n-users-loading-spinner"
|
|
162
184
|
/>
|
|
163
|
-
{{ isForgotPasswordLoading ? "
|
|
185
|
+
{{ isForgotPasswordLoading ? props.forgotPasswordSendingLabel || t("login.forgotPasswordSending") : props.forgotPasswordLabel || t("login.forgotPassword") }}
|
|
164
186
|
</a>
|
|
165
187
|
</p>
|
|
166
188
|
</div>
|