nuxt-users 1.38.0 → 1.40.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 +13 -1
- package/dist/cli.mjs +57 -27
- package/dist/module.d.mts +2 -2
- package/dist/module.d.ts +2 -2
- package/dist/module.json +4 -1
- package/dist/module.mjs +29 -7
- package/dist/runtime/assets/nuxt-users.css +1 -1
- 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/useAuthentication.js +14 -0
- 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/[id].delete.js +1 -1
- package/dist/runtime/server/api/nuxt-users/[id].get.js +1 -1
- package/dist/runtime/server/api/nuxt-users/[id].patch.js +1 -1
- package/dist/runtime/server/api/nuxt-users/auth/google/callback.get.js +1 -1
- package/dist/runtime/server/api/nuxt-users/auth/google/redirect.get.js +1 -1
- package/dist/runtime/server/api/nuxt-users/confirm-email.get.js +3 -3
- package/dist/runtime/server/api/nuxt-users/inactive.get.js +1 -2
- package/dist/runtime/server/api/nuxt-users/index.get.js +1 -2
- package/dist/runtime/server/api/nuxt-users/index.post.js +1 -1
- package/dist/runtime/server/api/nuxt-users/me.get.js +20 -13
- package/dist/runtime/server/api/nuxt-users/me.patch.js +1 -1
- package/dist/runtime/server/api/nuxt-users/password/forgot.post.js +2 -1
- package/dist/runtime/server/api/nuxt-users/password/index.patch.js +1 -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.delete.js +1 -1
- package/dist/runtime/server/api/nuxt-users/session/index.post.js +5 -3
- package/dist/runtime/server/composables/useServerAuth.js +1 -1
- package/dist/runtime/server/internal/index.d.ts +1 -7
- package/dist/runtime/server/internal/index.js +23 -7
- package/dist/runtime/server/middleware/authorization.server.js +22 -5
- package/dist/runtime/server/tasks/cleanup-tokens.d.ts +1 -1
- package/dist/runtime/server/utils/add-indexes.d.ts +3 -0
- package/dist/runtime/server/utils/add-indexes.js +17 -0
- package/dist/runtime/server/utils/google-oauth.js +2 -1
- package/dist/runtime/server/utils/index.d.ts +2 -2
- package/dist/runtime/server/utils/index.js +2 -2
- package/dist/runtime/server/utils/migrate.d.ts +6 -0
- package/dist/runtime/server/utils/migrate.js +10 -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.XW6DYM7t.d.mts} +46 -2
- package/dist/shared/{nuxt-users.SXaMnaEL.d.ts → nuxt-users.XW6DYM7t.d.ts} +46 -2
- package/dist/utils.d.mts +4 -1
- package/dist/utils.d.ts +4 -1
- package/dist/utils.mjs +4 -1
- package/package.json +11 -6
- 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/scripts/test-nuxt3.sh +78 -0
package/README.md
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
# Nuxt Users
|
|
2
|
+
[](https://context7.com/rrd108/nuxt-users)
|
|
3
|
+
[](https://www.npmjs.com/package/nuxt-users)
|
|
4
|
+
[](https://www.npmjs.com/package/nuxt-users)
|
|
5
|
+
[](https://github.com/rrd108/nuxt-users/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/rrd108/nuxt-users/actions/workflows/ci.yml)
|
|
7
|
+
[](https://nuxt.com)
|
|
8
|
+
[](https://nuxt.com)
|
|
9
|
+
|
|
2
10
|
|
|
3
11
|
A user authentication module for Nuxt 3 and Nuxt 4 with database support for SQLite, MySQL, and PostgreSQL.
|
|
4
12
|
|
|
@@ -39,7 +47,7 @@ A user authentication module for Nuxt 3 and Nuxt 4 with database support for SQL
|
|
|
39
47
|
|
|
40
48
|
MIT
|
|
41
49
|
|
|
42
|
-
## Dev
|
|
50
|
+
## Dev Misc
|
|
43
51
|
|
|
44
52
|
### Using yalc
|
|
45
53
|
|
|
@@ -49,4 +57,8 @@ yalc publish
|
|
|
49
57
|
|
|
50
58
|
# Install the module in the consumer app
|
|
51
59
|
yalc add nuxt-users
|
|
60
|
+
|
|
61
|
+
# Clean up consumer app
|
|
62
|
+
yalc remove nuxt-users
|
|
63
|
+
yarn add nuxt-users
|
|
52
64
|
```
|
package/dist/cli.mjs
CHANGED
|
@@ -4,11 +4,12 @@ import { readFileSync } from 'node:fs';
|
|
|
4
4
|
import { defaultOptions } from './module.mjs';
|
|
5
5
|
import { loadNuxt } from '@nuxt/kit';
|
|
6
6
|
import { defu } from 'defu';
|
|
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.
|
|
7
|
+
import { runMigrations, createUser as createUser$1, createUsersTable as createUsersTable$1, createPersonalAccessTokensTable as createPersonalAccessTokensTable$1, createPasswordResetTokensTable as createPasswordResetTokensTable$1, createMigrationsTable as createMigrationsTable$1, useDb, checkTableExists, getAppliedMigrations } from '../dist/runtime/server/utils/index.js';
|
|
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
|
-
import { useDb, checkTableExists } from '../dist/runtime/server/utils/db.js';
|
|
11
|
-
import { getAppliedMigrations } from '../dist/runtime/server/utils/migrate.js';
|
|
12
13
|
import '../dist/runtime/server/internal/index.js';
|
|
13
14
|
|
|
14
15
|
const getOptionsFromEnv = () => {
|
|
@@ -52,33 +53,58 @@ const getOptionsFromEnv = () => {
|
|
|
52
53
|
const loadOptions = async () => {
|
|
53
54
|
try {
|
|
54
55
|
console.log("[Nuxt Users] Loading Nuxt project...");
|
|
56
|
+
console.log("[Nuxt Users] \u2139\uFE0F Note: CLI commands read .env files. If you use .env.local in development, export variables first:");
|
|
57
|
+
console.log("[Nuxt Users] set -a; source .env.local; set +a; npx nuxt-users <command>");
|
|
58
|
+
console.log("[Nuxt Users] In production, environment variables are set directly in the deployment environment.");
|
|
55
59
|
const nuxt = await loadNuxt({ cwd: process.cwd(), ready: false });
|
|
56
60
|
const topLevelConfig = nuxt.options.nuxtUsers;
|
|
57
|
-
const
|
|
58
|
-
try {
|
|
59
|
-
const configPath = await import('node:path').then((p) => p.resolve(process.cwd(), "nuxt.config.ts"));
|
|
60
|
-
const config = await import(configPath).then((m) => m.default);
|
|
61
|
-
return config?.runtimeConfig?.nuxtUsers;
|
|
62
|
-
} catch {
|
|
63
|
-
return nuxt.options.runtimeConfig?.nuxtUsers;
|
|
64
|
-
}
|
|
65
|
-
})();
|
|
61
|
+
const processedRuntimeConfig = nuxt.options.runtimeConfig?.nuxtUsers;
|
|
66
62
|
await nuxt.close();
|
|
67
|
-
if (topLevelConfig ||
|
|
63
|
+
if (topLevelConfig || processedRuntimeConfig) {
|
|
68
64
|
console.log("[Nuxt Users] Using configuration from nuxt.config");
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
};
|
|
65
|
+
const { connector: _defaultConnector, ...defaultsWithoutConnector } = defaultOptions;
|
|
66
|
+
const mergedConfig = defu(topLevelConfig, processedRuntimeConfig, defaultsWithoutConnector);
|
|
67
|
+
const configuredConnector = topLevelConfig?.connector || processedRuntimeConfig?.connector;
|
|
68
|
+
mergedConfig.connector = configuredConnector || defaultOptions.connector;
|
|
69
|
+
if (mergedConfig.connector.name === "mysql" || mergedConfig.connector.name === "postgresql") {
|
|
70
|
+
const options = mergedConfig.connector.options;
|
|
71
|
+
const envOptions = {};
|
|
72
|
+
if (!options.user && process.env.DB_USER) {
|
|
73
|
+
envOptions.user = process.env.DB_USER;
|
|
74
|
+
}
|
|
75
|
+
if (!options.password && process.env.DB_PASSWORD) {
|
|
76
|
+
envOptions.password = process.env.DB_PASSWORD;
|
|
77
|
+
}
|
|
78
|
+
if (!options.host && process.env.DB_HOST) {
|
|
79
|
+
envOptions.host = process.env.DB_HOST;
|
|
80
|
+
}
|
|
81
|
+
if (!options.database && process.env.DB_NAME) {
|
|
82
|
+
envOptions.database = process.env.DB_NAME;
|
|
83
|
+
}
|
|
84
|
+
if (!options.port && process.env.DB_PORT) {
|
|
85
|
+
envOptions.port = Number.parseInt(process.env.DB_PORT);
|
|
86
|
+
}
|
|
87
|
+
if (Object.keys(envOptions).length > 0) {
|
|
88
|
+
mergedConfig.connector.options = { ...options, ...envOptions };
|
|
89
|
+
console.log("[Nuxt Users] Filled in missing connector options from environment variables");
|
|
90
|
+
}
|
|
91
|
+
const finalOptions = mergedConfig.connector.options;
|
|
92
|
+
if (!finalOptions.user || !finalOptions.password || !finalOptions.host || !finalOptions.database) {
|
|
93
|
+
console.warn("[Nuxt Users] Warning: MySQL/PostgreSQL connector options are incomplete.");
|
|
94
|
+
console.warn("[Nuxt Users] Required: user, password, host, database");
|
|
95
|
+
console.warn("[Nuxt Users] Found:", {
|
|
96
|
+
user: finalOptions.user || "(missing)",
|
|
97
|
+
password: finalOptions.password ? "***" : "(missing)",
|
|
98
|
+
host: finalOptions.host || "(missing)",
|
|
99
|
+
database: finalOptions.database || "(missing)"
|
|
100
|
+
});
|
|
101
|
+
console.warn("[Nuxt Users] Please set these in nuxt.config.ts or as environment variables (DB_USER, DB_PASSWORD, DB_HOST, DB_NAME)");
|
|
102
|
+
}
|
|
76
103
|
}
|
|
77
104
|
return mergedConfig;
|
|
78
|
-
} else {
|
|
79
|
-
console.log("[Nuxt Users] No nuxt-users configuration found, using environment variables");
|
|
80
|
-
return getOptionsFromEnv();
|
|
81
105
|
}
|
|
106
|
+
console.log("[Nuxt Users] No nuxt-users configuration found, using environment variables");
|
|
107
|
+
return getOptionsFromEnv();
|
|
82
108
|
} catch (error) {
|
|
83
109
|
console.log("[Nuxt Users] Could not load Nuxt project, using environment variables");
|
|
84
110
|
console.error("[Nuxt Users] Error:", error);
|
|
@@ -327,7 +353,9 @@ const projectInfo = defineCommand({
|
|
|
327
353
|
async run() {
|
|
328
354
|
try {
|
|
329
355
|
console.log("[Nuxt Users] Loading Nuxt project...");
|
|
330
|
-
console.log("[Nuxt Users] \u2139\uFE0F Note:
|
|
356
|
+
console.log("[Nuxt Users] \u2139\uFE0F Note: CLI commands read .env files. If you use .env.local in development, export variables first:");
|
|
357
|
+
console.log("[Nuxt Users] set -a; source .env.local; set +a; npx nuxt-users <command>");
|
|
358
|
+
console.log("[Nuxt Users] In production, environment variables are set directly in the deployment environment.");
|
|
331
359
|
const nuxt = await loadNuxt({ cwd: process.cwd() });
|
|
332
360
|
console.log("[Nuxt Users] \u2705 Nuxt project loaded successfully!");
|
|
333
361
|
console.log("[Nuxt Users] \u{1F4C1} Source directory:", nuxt.options.srcDir);
|
|
@@ -369,14 +397,16 @@ const projectInfo = defineCommand({
|
|
|
369
397
|
console.log("[Nuxt Users] -", migration);
|
|
370
398
|
});
|
|
371
399
|
}
|
|
372
|
-
}
|
|
400
|
+
}
|
|
401
|
+
if (!migrationsTableExists) {
|
|
373
402
|
console.log("[Nuxt Users] Table exists: no \u274C");
|
|
374
403
|
console.log('[Nuxt Users] \u27A1\uFE0F Run "npx nuxt-users migrate" to set up the database');
|
|
375
404
|
}
|
|
376
405
|
} catch (error) {
|
|
377
406
|
console.log("[Nuxt Users] Status: \u26A0\uFE0F Error -", error instanceof Error ? error.message : "Unknown error");
|
|
378
407
|
}
|
|
379
|
-
}
|
|
408
|
+
}
|
|
409
|
+
if (!nuxtUsersConfig) {
|
|
380
410
|
console.log("[Nuxt Users] \u26A0\uFE0F Nuxt Users module not configured in runtime config");
|
|
381
411
|
}
|
|
382
412
|
} catch (error) {
|
package/dist/module.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
-
import {
|
|
2
|
+
import { M as ModuleOptions } from './shared/nuxt-users.XW6DYM7t.mjs';
|
|
3
3
|
export * from '../dist/runtime/server/internal/index.js';
|
|
4
4
|
|
|
5
5
|
declare const defaultOptions: ModuleOptions;
|
|
6
|
-
declare const _default: _nuxt_schema.NuxtModule<
|
|
6
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
7
7
|
|
|
8
8
|
export { _default as default, defaultOptions };
|
package/dist/module.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
-
import {
|
|
2
|
+
import { M as ModuleOptions } from './shared/nuxt-users.XW6DYM7t.js';
|
|
3
3
|
export * from '../dist/runtime/server/internal/index.js';
|
|
4
4
|
|
|
5
5
|
declare const defaultOptions: ModuleOptions;
|
|
6
|
-
declare const _default: _nuxt_schema.NuxtModule<
|
|
6
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
7
7
|
|
|
8
8
|
export { _default as default, defaultOptions };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addServerImportsDir, addServerHandler, addRouteMiddleware, addComponentsDir } from '@nuxt/kit';
|
|
1
|
+
import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addServerImportsDir, addServerScanDir, addServerHandler, addRouteMiddleware, addComponentsDir } from '@nuxt/kit';
|
|
2
2
|
import { defu } from 'defu';
|
|
3
3
|
export * from '../dist/runtime/server/internal/index.js';
|
|
4
4
|
|
|
@@ -50,12 +50,22 @@ 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
|
+
},
|
|
59
|
+
tokenCleanupSchedule: "0 2 * * *"
|
|
60
|
+
// Daily at 2 AM
|
|
54
61
|
};
|
|
55
62
|
const module$1 = defineNuxtModule({
|
|
56
63
|
meta: {
|
|
57
64
|
name: "nuxt-users",
|
|
58
|
-
configKey: "nuxtUsers"
|
|
65
|
+
configKey: "nuxtUsers",
|
|
66
|
+
compatibility: {
|
|
67
|
+
nuxt: ">=3.0.0"
|
|
68
|
+
}
|
|
59
69
|
},
|
|
60
70
|
// Default configuration options of the Nuxt module
|
|
61
71
|
defaults: defaultOptions,
|
|
@@ -63,6 +73,9 @@ const module$1 = defineNuxtModule({
|
|
|
63
73
|
const resolver = createResolver(import.meta.url);
|
|
64
74
|
const { connector: _defaultConnector, ...defaultsWithoutConnector } = defaultOptions;
|
|
65
75
|
const runtimeConfigOptions = defu(nuxt.options.runtimeConfig.nuxtUsers || {}, options, defaultsWithoutConnector);
|
|
76
|
+
if (!runtimeConfigOptions.locale) {
|
|
77
|
+
runtimeConfigOptions.locale = defaultOptions.locale;
|
|
78
|
+
}
|
|
66
79
|
const configuredConnector = nuxt.options.runtimeConfig.nuxtUsers?.connector || options.connector;
|
|
67
80
|
runtimeConfigOptions.connector = configuredConnector || defaultOptions.connector;
|
|
68
81
|
nuxt.options.runtimeConfig.nuxtUsers = {
|
|
@@ -108,6 +121,7 @@ const module$1 = defineNuxtModule({
|
|
|
108
121
|
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
109
122
|
nuxt.options.runtimeConfig.public.nuxtUsers = {
|
|
110
123
|
passwordValidation: runtimeConfigOptions.passwordValidation,
|
|
124
|
+
locale: runtimeConfigOptions.locale,
|
|
111
125
|
auth: {
|
|
112
126
|
whitelist: (() => {
|
|
113
127
|
const combinedWhitelist = [...defaultOptions.auth?.whitelist || [], ...runtimeConfigOptions.auth?.whitelist || []];
|
|
@@ -154,6 +168,7 @@ const module$1 = defineNuxtModule({
|
|
|
154
168
|
});
|
|
155
169
|
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
156
170
|
addServerImportsDir(resolver.resolve("./runtime/server/composables"));
|
|
171
|
+
addServerScanDir(resolver.resolve("./runtime/server"));
|
|
157
172
|
addServerHandler({
|
|
158
173
|
middleware: true,
|
|
159
174
|
handler: resolver.resolve("./runtime/server/middleware/authorization.server")
|
|
@@ -163,7 +178,7 @@ const module$1 = defineNuxtModule({
|
|
|
163
178
|
path: resolver.resolve("./runtime/middleware/authorization.client"),
|
|
164
179
|
global: true
|
|
165
180
|
});
|
|
166
|
-
const base =
|
|
181
|
+
const base = runtimeConfigOptions.apiBasePath || defaultOptions.apiBasePath;
|
|
167
182
|
addServerHandler({
|
|
168
183
|
route: `${base}/session`,
|
|
169
184
|
method: "post",
|
|
@@ -248,11 +263,18 @@ const module$1 = defineNuxtModule({
|
|
|
248
263
|
nitroConfig.experimental = nitroConfig.experimental || {};
|
|
249
264
|
nitroConfig.experimental.database = true;
|
|
250
265
|
nitroConfig.experimental.tasks = true;
|
|
251
|
-
|
|
252
|
-
|
|
266
|
+
const cleanupSchedule = runtimeConfigOptions.tokenCleanupSchedule ?? defaultOptions.tokenCleanupSchedule;
|
|
267
|
+
if (cleanupSchedule) {
|
|
268
|
+
nitroConfig.scheduledTasks = nitroConfig.scheduledTasks || {};
|
|
269
|
+
nitroConfig.scheduledTasks[cleanupSchedule] = [
|
|
270
|
+
...nitroConfig.scheduledTasks[cleanupSchedule] || [],
|
|
271
|
+
"nuxt-users:cleanup-tokens"
|
|
272
|
+
];
|
|
273
|
+
console.log(`[Nuxt Users] \u{1F504} Token cleanup scheduled: ${cleanupSchedule}`);
|
|
274
|
+
}
|
|
253
275
|
nitroConfig.prerender = nitroConfig.prerender || {};
|
|
254
276
|
nitroConfig.prerender.ignore = nitroConfig.prerender.ignore || [];
|
|
255
|
-
const apiBasePath =
|
|
277
|
+
const apiBasePath = runtimeConfigOptions.apiBasePath || defaultOptions.apiBasePath;
|
|
256
278
|
const ignorePattern = `${apiBasePath}/**`;
|
|
257
279
|
if (!nitroConfig.prerender.ignore.includes(ignorePattern)) {
|
|
258
280
|
nitroConfig.prerender.ignore.push(ignorePattern);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--nu-color-primary:#3b82f6;--nu-color-primary-dark:#2563eb;--nu-color-primary-light:#60a5fa;--nu-color-white:#fff;--nu-color-gray-50:#f9fafb;--nu-color-gray-500:#6b7280;--nu-color-gray-600:#4b5563;--nu-color-gray-700:#374151;--nu-color-gray-900:#111827;--nu-color-success:#059669;--nu-color-success-light:#f0fdf4;--nu-color-success-border:#9ae6b4;--nu-color-error:#dc2626;--nu-color-error-light:#fef2f2;--nu-color-error-border:#fecaca;--nu-color-error-alt:#db5050;--nu-color-error-dark:#b91c1c;--nu-color-border:#e5e7eb;--nu-color-border-light:#d1d5db;--nu-color-border-dark:#ccc;--nu-color-bg-primary:#fff;--nu-color-bg-secondary:#f9fafb;--nu-color-bg-tertiary:#f3f4f6;--nu-color-text-primary:#000;--nu-color-text-secondary:#6b7280;--nu-color-strength-bg:#e9ecef;--nu-color-validation-passed:#28a745;--nu-color-validation-failed:#dc3545;--nu-color-validation-hint:#6c757d}.dark :root{--nu-color-primary:#60a5fa;--nu-color-primary-dark:#3b82f6;--nu-color-primary-light:#93c5fd;--nu-color-white:#000;--nu-color-gray-50:#111827;--nu-color-gray-500:#9ca3af;--nu-color-gray-600:#d1d5db;--nu-color-gray-700:#e5e7eb;--nu-color-gray-900:#f9fafb;--nu-color-success:#10b981;--nu-color-success-light:#064e3b;--nu-color-success-border:#065f46;--nu-color-error:#ef4444;--nu-color-error-light:#450a0a;--nu-color-error-border:#7f1d1d;--nu-color-error-alt:#f87171;--nu-color-error-dark:#dc2626;--nu-color-border:#374151;--nu-color-border-light:#4b5563;--nu-color-border-dark:#6b7280;--nu-color-bg-primary:#111827;--nu-color-bg-secondary:#1f2937;--nu-color-bg-tertiary:#374151;--nu-color-text-primary:#fff;--nu-color-text-secondary:#9ca3af;--nu-color-strength-bg:#374151;--nu-color-validation-passed:#22c55e;--nu-color-validation-failed:#ef4444;--nu-color-validation-hint:#9ca3af}.n-users-form-group{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem;width:100%}.n-users-form-group.n-users-form-group-narrow{width:90%}.n-users-form-group label,.n-users-form-label{color:var(--nu-color-text-primary,#000);display:block;font-size:1rem;font-weight:500;margin-bottom:.5rem}.n-users-form-group input,.n-users-form-group select,.n-users-form-input{border:1px solid var(--nu-color-border,#ccc);border-radius:.25rem;font-size:1rem;padding:.5rem;transition:border-color .2s,box-shadow .2s;width:100%}.n-users-form-group input:focus,.n-users-form-group select:focus,.n-users-form-input:focus{border-color:var(--nu-color-primary);box-shadow:0 0 0 .1rem rgba(59,130,246,.1);outline:none}.n-users-form-group input:disabled,.n-users-form-input:disabled{background-color:var(--nu-color-bg-secondary,#f9fafb);cursor:not-allowed}.n-users-form-group input.error,.n-users-form-input.error{border-color:var(--nu-color-error,#dc3545)}.n-users-form-group input[type=email],.n-users-form-group input[type=password],.n-users-form-group input[type=text]{background-color:var(--nu-color-bg-secondary);border:1px solid var(--nu-color-border-light);border-radius:.5em;box-sizing:border-box;color:var(--nu-color-gray-700);font-size:.875rem;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-form-group input[type=email]:focus,.n-users-form-group input[type=password]:focus,.n-users-form-group input[type=text]:focus{background-color:var(--nu-color-bg-primary);border-color:var(--nu-color-primary);box-shadow:0 0 0 3px rgba(59,130,246,.1);outline:none}.n-users-form-group input[type=checkbox]{margin:0;width:auto}.n-users-google-btn{align-items:center;display:inline-flex;gap:8px;justify-content:center}.n-users-google-logo{flex-shrink:0}.n-users-btn,.n-users-cancel-btn,.n-users-delete-btn,.n-users-edit-btn,.n-users-google-btn,.n-users-submit-btn{align-self:flex-start;border:none;border-radius:.25rem;cursor:pointer;display:inline-block;font-size:1rem;font-weight:500;padding:.5rem 1rem;text-decoration:none;transition:background-color .2s,transform .1s}.n-users-btn:hover,.n-users-edit-btn:hover,.n-users-submit-btn:hover{background-color:var(--nu-color-primary-dark,#2563eb);transform:translateY(-1px)}.n-users-btn:disabled,.n-users-submit-btn:disabled{cursor:not-allowed;opacity:.6;transform:none}.n-users-btn-primary,.n-users-edit-btn,.n-users-submit-btn{background-color:var(--nu-color-primary,#3b82f6);color:#fff}.n-users-btn-secondary,.n-users-cancel-btn{background-color:var(--nu-color-gray-500,#6b7280);color:#fff}.n-users-cancel-btn:hover{background-color:var(--nu-color-gray-600,#4b5563)}.n-users-delete-btn{background-color:var(--nu-color-error,#ef4444);color:#fff}.n-users-delete-btn:hover{background-color:var(--nu-color-error-alt,#dc2626)}.n-users-login-section button[type=submit],.n-users-register-section button[type=submit],.n-users-reset-password-container button[type=submit],.n-users-user-form button[type=submit],form.n-users-form button[type=submit]{align-items:center;background-color:var(--nu-color-primary);border:1px solid var(--nu-color-primary);border-radius:.5em;color:var(--nu-color-white);cursor:pointer;display:flex;font-size:.875rem;font-weight:500;gap:.5rem;justify-content:center;min-height:44px;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-login-section button[type=submit]:hover:not(:disabled),.n-users-register-section button[type=submit]:hover:not(:disabled),.n-users-reset-password-container button[type=submit]:hover:not(:disabled),.n-users-user-form button[type=submit]:hover:not(:disabled),form.n-users-form button[type=submit]:hover:not(:disabled){background-color:var(--nu-color-primary-dark);border-color:var(--nu-color-primary-dark)}.n-users-login-section button[type=submit]:disabled,.n-users-register-section button[type=submit]:disabled,.n-users-reset-password-container button[type=submit]:disabled,.n-users-user-form button[type=submit]:disabled,form.n-users-form button[type=submit]:disabled{cursor:not-allowed;opacity:.6}.n-users-error-message,.n-users-error-text{background-color:var(--nu-color-error-light,#fef2f2);border:1px solid var(--nu-color-error-border,#fecaca);border-radius:.5rem;color:var(--nu-color-error,#dc3545);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-success-message{background-color:var(--nu-color-success-light,#f0fff4);border:1px solid var(--nu-color-success-border,#9ae6b4);border-radius:.5rem;color:var(--nu-color-success,#10b981);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-grid{display:grid;gap:1rem}.n-users-grid-2{grid-template-columns:1fr 5fr}.n-users-grid-auto{grid-template-columns:repeat(auto-fill,minmax(12em,1fr))}.n-users-form-actions{align-items:center;display:flex;gap:1rem;margin-top:1.5rem}.n-users-loading-spinner{animation:n-users-spin 1s linear infinite;border:2px solid var(--nu-color-white,#fff);border-radius:50%;border-top:2px solid transparent;height:16px;width:16px}@keyframes n-users-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.n-users-card{background-color:var(--nu-color-bg-primary,#fff);border:1px solid var(--nu-color-border,#e5e7eb);border-radius:.5rem;padding:1rem}.n-users-section{margin:0 auto;max-width:42em;padding:1em}.n-users-section-header{border-bottom:.1em solid var(--nu-color-border,#e5e7eb);margin-bottom:1rem;padding-bottom:.5rem}.n-users-form-help{color:var(--nu-color-text-secondary,#6b7280);font-size:.75rem;margin-top:.25rem}.n-users-strength-bar{background-color:var(--nu-color-strength-bg,#e9ecef);border-radius:2px;height:4px;margin-bottom:4px;overflow:hidden;width:100%}.n-users-strength-fill{height:100%;transition:width .3s ease,background-color .3s ease}.n-users-strength-text{font-size:.75rem;font-weight:500}.n-users-validation-container{background-color:#f8f9fa;border:1px solid #e9ecef;border-radius:4px;margin-top:12px;padding:12px}.n-users-container-title{color:#495057;font-size:.875rem;font-weight:600;margin-bottom:8px}.n-users-list-unstyled{list-style:none;margin:0;padding-left:0}.n-users-list-item{align-items:center;display:flex;font-size:.875rem;margin-bottom:6px;transition:color .2s ease}.n-users-list-item:last-child{margin-bottom:0}.n-users-icon{font-weight:700;margin-right:8px;min-width:16px;text-align:center}.n-users-text{flex:1}.n-users-list ul{list-style:none}.n-users-login-section form,.n-users-register-section form,.n-users-reset-password-container form,.n-users-user-form form,form.n-users-form{display:flex;flex-direction:column;gap:1.5rem}.n-users-login-section{background:linear-gradient(135deg,var(--nu-color-bg-primary) 0,var(--nu-color-bg-secondary) 100%);border:1px solid var(--nu-color-border);border-radius:.75em;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);max-width:25rem}.n-users-login-header{margin-bottom:1em;text-align:center}.n-users-login-title{color:var(--nu-color-gray-700);font-size:1.875rem;font-weight:700;line-height:1.2;margin:0 0 .5em}.n-users-login-subtitle{color:var(--nu-color-gray-700);font-size:.875rem;line-height:1.5;margin:0}.n-users-remember-me{align-items:center;display:flex;gap:.5rem}.n-users-remember-me label{color:var(--nu-color-gray-700);font-size:.875rem;margin:0}.n-users-login-footer{margin-top:1em;text-align:center}.n-users-forgot-password{margin:0}.n-users-forgot-link{align-items:center;color:var(--nu-color-primary);display:inline-flex;font-size:.875rem;gap:.5rem;text-decoration:none;transition:color .2s ease-in-out}.n-users-forgot-link:hover:not(.loading){color:var(--nu-color-primary-dark);text-decoration:underline}.n-users-forgot-link.loading{cursor:not-allowed;opacity:.6;pointer-events:none}.n-users-password-strength{margin-top:8px}.n-users-validation-rules{margin-top:12px}.n-users-rules-title{margin-bottom:8px}.n-users-rules-list{padding-left:0}.n-users-rule-item{margin-bottom:6px}.n-users-rule-item:last-child{margin-bottom:0}.n-users-rule-passed{color:var(--nu-color-validation-passed,#28a745)}.n-users-rule-failed{color:var(--nu-color-validation-failed,#dc3545)}.n-users-rule-icon{margin-right:8px}.n-users-rule-text{flex:1}.n-users-validation-errors{margin-top:8px}.n-users-error-text:last-child{margin-bottom:0}.n-users-password-hints{margin-top:8px}.n-users-hint-title{margin-bottom:8px}.n-users-hint-list{padding-left:16px}.n-users-hint-item{color:var(--nu-color-validation-hint,#6c757d);margin-bottom:4px}.n-users-hint-item:last-child{margin-bottom:0}.n-users-logout-link{background:var(--nu-color-error);border:2px solid transparent;border-color:var(--nu-color-error-dark);border-radius:.5em;color:#fff;padding:.5em 1em;text-decoration:none}.n-users-logout-link:hover{border-color:var(--nu-color-primary)}.n-users-user-card dd{margin:0}.n-users-user-card-actions{display:flex;gap:.5rem;margin-top:1rem}.n-users-user-form{margin:0 auto;max-width:500px}.n-users-form-group input.error{border-color:#dc3545}.n-users-profile-info{background-color:var(--nu-color-bg-primary);border-top-left-radius:.5em;border-top-right-radius:.5em}.n-users-profile-details{font-size:1rem;list-style:none;margin:0;padding:0}.n-users-reset-password-container{background-color:var(--nu-color-bg-primary);border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}@media (max-width:480px){.n-users-login-title{font-size:1.5rem}}.n-users-list-enter-active,.n-users-list-leave-active,.n-users-list-move{transition:all .3s ease}.n-users-list-enter-from,.n-users-list-leave-to{opacity:0;transform:translateX(2rem)}.n-users-list-leave-active{position:absolute}.n-users-list-move{transition-timing-function:ease}
|
|
1
|
+
:root{--nu-color-primary:#3b82f6;--nu-color-primary-dark:#2563eb;--nu-color-primary-light:#60a5fa;--nu-color-white:#fff;--nu-color-gray-50:#f9fafb;--nu-color-gray-500:#6b7280;--nu-color-gray-600:#4b5563;--nu-color-gray-700:#374151;--nu-color-gray-900:#111827;--nu-color-success:#059669;--nu-color-success-light:#f0fdf4;--nu-color-success-border:#9ae6b4;--nu-color-success-text:#047857;--nu-color-error:#dc2626;--nu-color-error-light:#fef2f2;--nu-color-error-border:#fecaca;--nu-color-error-alt:#db5050;--nu-color-error-dark:#b91c1c;--nu-color-border:#e5e7eb;--nu-color-border-light:#d1d5db;--nu-color-border-dark:#ccc;--nu-color-bg-primary:#fff;--nu-color-bg-secondary:#f9fafb;--nu-color-bg-tertiary:#f3f4f6;--nu-color-text-primary:#000;--nu-color-text-secondary:#6b7280;--nu-color-strength-bg:#e9ecef;--nu-color-validation-passed:#15803d;--nu-color-validation-failed:#dc3545;--nu-color-validation-hint:#6c757d}.dark :root{--nu-color-primary:#60a5fa;--nu-color-primary-dark:#3b82f6;--nu-color-primary-light:#93c5fd;--nu-color-white:#000;--nu-color-gray-50:#111827;--nu-color-gray-500:#9ca3af;--nu-color-gray-600:#d1d5db;--nu-color-gray-700:#e5e7eb;--nu-color-gray-900:#f9fafb;--nu-color-success:#10b981;--nu-color-success-light:#064e3b;--nu-color-success-border:#065f46;--nu-color-success-text:#6ee7b7;--nu-color-error:#ef4444;--nu-color-error-light:#450a0a;--nu-color-error-border:#7f1d1d;--nu-color-error-alt:#f87171;--nu-color-error-dark:#dc2626;--nu-color-border:#374151;--nu-color-border-light:#4b5563;--nu-color-border-dark:#6b7280;--nu-color-bg-primary:#111827;--nu-color-bg-secondary:#1f2937;--nu-color-bg-tertiary:#374151;--nu-color-text-primary:#fff;--nu-color-text-secondary:#9ca3af;--nu-color-strength-bg:#374151;--nu-color-validation-passed:#22c55e;--nu-color-validation-failed:#ef4444;--nu-color-validation-hint:#9ca3af}.n-users-form-group{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem;width:100%}.n-users-form-group.n-users-form-group-narrow{width:90%}.n-users-form-group label,.n-users-form-label{color:var(--nu-color-text-primary,#000);display:block;font-size:1rem;font-weight:500;margin-bottom:.5rem}.n-users-form-group input,.n-users-form-group select,.n-users-form-input{border:1px solid var(--nu-color-border,#ccc);border-radius:.25rem;font-size:1rem;padding:.5rem;transition:border-color .2s,box-shadow .2s;width:100%}.n-users-form-group input:focus,.n-users-form-group select:focus,.n-users-form-input:focus{border-color:var(--nu-color-primary);box-shadow:0 0 0 .1rem rgba(59,130,246,.1);outline:none}.n-users-form-group input:disabled,.n-users-form-input:disabled{background-color:var(--nu-color-bg-secondary,#f9fafb);cursor:not-allowed}.n-users-form-group input.error,.n-users-form-input.error{border-color:var(--nu-color-error,#dc3545)}.n-users-form-group input[type=email],.n-users-form-group input[type=password],.n-users-form-group input[type=text]{background-color:var(--nu-color-bg-secondary);border:1px solid var(--nu-color-border-light);border-radius:.5em;box-sizing:border-box;color:var(--nu-color-gray-700);font-size:.875rem;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-form-group input[type=email]:focus,.n-users-form-group input[type=password]:focus,.n-users-form-group input[type=text]:focus{background-color:var(--nu-color-bg-primary);border-color:var(--nu-color-primary);box-shadow:0 0 0 3px rgba(59,130,246,.1);outline:none}.n-users-form-group input[type=checkbox]{margin:0;width:auto}.n-users-google-btn{align-items:center;border:none;border-radius:.25rem;cursor:pointer;display:inline-flex;font-size:1rem;font-weight:500;gap:8px;justify-content:center;padding:.5rem 1rem;text-decoration:none;transition:background-color .2s,transform .1s}.n-users-google-logo{flex-shrink:0}.n-users-btn,.n-users-cancel-btn,.n-users-delete-btn,.n-users-edit-btn,.n-users-submit-btn{align-self:flex-start;border:none;border-radius:.25rem;cursor:pointer;display:inline-block;font-size:1rem;font-weight:500;padding:.5rem 1rem;text-decoration:none;transition:background-color .2s,transform .1s}.n-users-btn:hover,.n-users-edit-btn:hover,.n-users-submit-btn:hover{background-color:var(--nu-color-primary-dark,#2563eb);transform:translateY(-1px)}.n-users-btn:disabled,.n-users-submit-btn:disabled{cursor:not-allowed;opacity:.6;transform:none}.n-users-btn-primary,.n-users-edit-btn,.n-users-submit-btn{background-color:var(--nu-color-primary,#3b82f6);color:#fff}.n-users-btn-secondary,.n-users-cancel-btn{background-color:var(--nu-color-gray-600,#4b5563);color:#fff}.n-users-cancel-btn:hover{background-color:var(--nu-color-gray-700,#374151)}.n-users-delete-btn{background-color:var(--nu-color-error-dark,#b91c1c);color:#fff}.n-users-delete-btn:hover{background-color:#991b1b}.n-users-login-section button[type=submit],.n-users-register-section button[type=submit],.n-users-reset-password-container button[type=submit],.n-users-user-form button[type=submit],form.n-users-form button[type=submit]{align-items:center;background-color:var(--nu-color-primary);border:1px solid var(--nu-color-primary);border-radius:.5em;color:var(--nu-color-white);cursor:pointer;display:flex;font-size:.875rem;font-weight:500;gap:.5rem;justify-content:center;min-height:44px;padding:.75em 1em;transition:all .2s ease-in-out;width:100%}.n-users-login-section button[type=submit]:hover:not(:disabled),.n-users-register-section button[type=submit]:hover:not(:disabled),.n-users-reset-password-container button[type=submit]:hover:not(:disabled),.n-users-user-form button[type=submit]:hover:not(:disabled),form.n-users-form button[type=submit]:hover:not(:disabled){background-color:var(--nu-color-primary-dark);border-color:var(--nu-color-primary-dark)}.n-users-login-section button[type=submit]:disabled,.n-users-register-section button[type=submit]:disabled,.n-users-reset-password-container button[type=submit]:disabled,.n-users-user-form button[type=submit]:disabled,form.n-users-form button[type=submit]:disabled{cursor:not-allowed;opacity:.6}.n-users-error-message,.n-users-error-text{background-color:var(--nu-color-error-light,#fef2f2);border:1px solid var(--nu-color-error-border,#fecaca);border-radius:.5rem;color:var(--nu-color-error-dark,#b91c1c);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-success-message{background-color:var(--nu-color-success-light,#f0fdf4);border:1px solid var(--nu-color-success-border,#9ae6b4);border-radius:.5rem;color:var(--nu-color-success-text,#047857);font-size:.875rem;margin-top:.5rem;padding:.75rem 1rem}.n-users-grid{display:grid;gap:1rem}.n-users-grid-2{grid-template-columns:1fr 5fr}.n-users-grid-auto{grid-template-columns:repeat(auto-fill,minmax(12em,1fr))}.n-users-form-actions{align-items:center;display:flex;gap:1rem;margin-top:1.5rem}.n-users-loading-spinner{animation:n-users-spin 1s linear infinite;border:2px solid var(--nu-color-white,#fff);border-radius:50%;border-top:2px solid transparent;height:16px;width:16px}@keyframes n-users-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.n-users-card{background-color:var(--nu-color-bg-primary,#fff);border:1px solid var(--nu-color-border,#e5e7eb);border-radius:.5rem;padding:1rem}.n-users-section{margin:0 auto;max-width:42em;padding:1em}.n-users-section-header{border-bottom:.1em solid var(--nu-color-border,#e5e7eb);margin-bottom:1rem;padding-bottom:.5rem}.n-users-form-help{color:var(--nu-color-text-secondary,#6b7280);font-size:.75rem;margin-top:.25rem}.n-users-strength-bar{background-color:var(--nu-color-strength-bg,#e9ecef);border-radius:2px;height:4px;margin-bottom:4px;overflow:hidden;width:100%}.n-users-strength-fill{height:100%;transition:width .3s ease,background-color .3s ease}.n-users-strength-text{font-size:.75rem;font-weight:500}.n-users-validation-container{background-color:#f8f9fa;border:1px solid #e9ecef;border-radius:4px;margin-top:12px;padding:12px}.n-users-container-title{color:#495057;font-size:.875rem;font-weight:600;margin-bottom:8px}.n-users-list-unstyled{list-style:none;margin:0;padding-left:0}.n-users-list-item{align-items:center;display:flex;font-size:.875rem;margin-bottom:6px;transition:color .2s ease}.n-users-list-item:last-child{margin-bottom:0}.n-users-icon{font-weight:700;margin-right:8px;min-width:16px;text-align:center}.n-users-text{flex:1}.n-users-list ul{list-style:none}.n-users-login-section form,.n-users-register-section form,.n-users-reset-password-container form,.n-users-user-form form,form.n-users-form{display:flex;flex-direction:column;gap:1.5rem}.n-users-login-section{background:linear-gradient(135deg,var(--nu-color-bg-primary) 0,var(--nu-color-bg-secondary) 100%);border:1px solid var(--nu-color-border);border-radius:.75em;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);max-width:25rem}.n-users-login-header{margin-bottom:1em;text-align:center}.n-users-login-title{color:var(--nu-color-gray-700);font-size:1.875rem;font-weight:700;line-height:1.2;margin:0 0 .5em}.n-users-login-subtitle{color:var(--nu-color-gray-700);font-size:.875rem;line-height:1.5;margin:0}.n-users-remember-me{align-items:center;display:flex;gap:.5rem}.n-users-remember-me label{color:var(--nu-color-gray-700);font-size:.875rem;margin:0}.n-users-login-footer{margin-top:1em;text-align:center}.n-users-forgot-password{margin:0}.n-users-forgot-link{align-items:center;color:var(--nu-color-primary);display:inline-flex;font-size:.875rem;gap:.5rem;text-decoration:none;transition:color .2s ease-in-out}.n-users-forgot-link:hover:not(.loading){color:var(--nu-color-primary-dark);text-decoration:underline}.n-users-forgot-link.loading{cursor:not-allowed;opacity:.6;pointer-events:none}.n-users-password-strength{margin-top:8px}.n-users-validation-rules{margin-top:12px}.n-users-rules-title{margin-bottom:8px}.n-users-rules-list{padding-left:0}.n-users-rule-item{margin-bottom:6px}.n-users-rule-item:last-child{margin-bottom:0}.n-users-rule-passed{color:var(--nu-color-validation-passed,#15803d)}.n-users-rule-failed{color:var(--nu-color-validation-failed,#dc3545)}.n-users-rule-icon{margin-right:8px}.n-users-rule-text{flex:1}.n-users-validation-errors{margin-top:8px}.n-users-error-text:last-child{margin-bottom:0}.n-users-password-hints{margin-top:8px}.n-users-hint-title{margin-bottom:8px}.n-users-hint-list{padding-left:16px}.n-users-hint-item{color:var(--nu-color-validation-hint,#6c757d);margin-bottom:4px}.n-users-hint-item:last-child{margin-bottom:0}.n-users-logout-link{background:var(--nu-color-error-dark,#b91c1c);border:2px solid transparent;border-color:var(--nu-color-error-dark);border-radius:.5em;color:#fff;padding:.5em 1em;text-decoration:none}.n-users-logout-link:hover{border-color:var(--nu-color-primary)}.n-users-user-card dd{margin:0}.n-users-user-card-actions{display:flex;gap:.5rem;margin-top:1rem}.n-users-user-form{margin:0 auto;max-width:500px}.n-users-form-group input.error{border-color:#dc3545}.n-users-profile-info{background-color:var(--nu-color-bg-primary);border-top-left-radius:.5em;border-top-right-radius:.5em}.n-users-profile-details{font-size:1rem;list-style:none;margin:0;padding:0}.n-users-reset-password-container{background-color:var(--nu-color-bg-primary);border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}@media (max-width:480px){.n-users-login-title{font-size:1.5rem}}.n-users-list-enter-active,.n-users-list-leave-active,.n-users-list-move{transition:all .3s ease}.n-users-list-enter-from,.n-users-list-leave-to{opacity:0;transform:translateX(2rem)}.n-users-list-leave-active{position:absolute}.n-users-list-move{transition-timing-function:ease}
|
|
@@ -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;
|