@lenne.tech/nuxt-extensions 1.18.0 → 1.18.2
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/dist/module.d.mts +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/composables/auth/use-lt-auth.js +14 -4
- package/dist/runtime/composables/use-lt-auth-client.d.ts +7 -0
- package/dist/runtime/composables/use-lt-auth-client.js +2 -1
- package/dist/runtime/lib/auth-client.d.ts +7 -0
- package/dist/runtime/testing/playwright-helpers.js +14 -1
- package/package.json +12 -11
package/dist/module.d.mts
CHANGED
|
@@ -3,7 +3,7 @@ import { LtExtensionsModuleOptions } from '../dist/runtime/types/index.js';
|
|
|
3
3
|
export * from '../dist/runtime/types/index.js';
|
|
4
4
|
|
|
5
5
|
declare const name = "@lenne.tech/nuxt-extensions";
|
|
6
|
-
declare const version = "1.18.
|
|
6
|
+
declare const version = "1.18.2";
|
|
7
7
|
declare const configKey = "ltExtensions";
|
|
8
8
|
declare const DEFAULT_LT_AUTH_STATE_COOKIE = "lt-auth-state";
|
|
9
9
|
declare const DEFAULT_LT_JWT_TOKEN_COOKIE = "lt-jwt-token";
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { defineNuxtModule, createResolver, tryResolveModule, addImports, addComp
|
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
3
|
|
|
4
4
|
const name = "@lenne.tech/nuxt-extensions";
|
|
5
|
-
const version = "1.18.
|
|
5
|
+
const version = "1.18.2";
|
|
6
6
|
const configKey = "ltExtensions";
|
|
7
7
|
const DEFAULT_LT_AUTH_STATE_COOKIE = "lt-auth-state";
|
|
8
8
|
const DEFAULT_LT_JWT_TOKEN_COOKIE = "lt-jwt-token";
|
|
@@ -2,6 +2,7 @@ import { useNuxtApp, useCookie, useState, useRequestHeaders, ref, computed, watc
|
|
|
2
2
|
import { ltArrayBufferToBase64Url, ltBase64UrlToUint8Array } from "../../utils/crypto.js";
|
|
3
3
|
import { clearLtAuthCookies, getLtApiBase, getLtAuthCookieNames, resolveLtAuthState } from "../../lib/auth-state.js";
|
|
4
4
|
import { useLtAuthClient } from "../use-lt-auth-client.js";
|
|
5
|
+
const VALIDATE_SESSION_TIMEOUT_MS = 1e4;
|
|
5
6
|
function useTranslation() {
|
|
6
7
|
const nuxtApp = useNuxtApp();
|
|
7
8
|
const i18n = nuxtApp.$i18n;
|
|
@@ -155,15 +156,24 @@ export function useLtAuth() {
|
|
|
155
156
|
return merged;
|
|
156
157
|
}
|
|
157
158
|
async function validateSession() {
|
|
159
|
+
if (import.meta.server) {
|
|
160
|
+
return !!resolvedAuthState.value?.user;
|
|
161
|
+
}
|
|
158
162
|
try {
|
|
159
163
|
const session = authClient.useSession();
|
|
160
164
|
if (session.value.isPending) {
|
|
161
165
|
await new Promise((resolve) => {
|
|
162
|
-
|
|
166
|
+
let unwatch;
|
|
167
|
+
const timer = setTimeout(() => {
|
|
168
|
+
unwatch?.();
|
|
169
|
+
resolve(false);
|
|
170
|
+
}, VALIDATE_SESSION_TIMEOUT_MS);
|
|
171
|
+
unwatch = watch(
|
|
163
172
|
() => session.value.isPending,
|
|
164
173
|
(isPending) => {
|
|
165
174
|
if (!isPending) {
|
|
166
|
-
|
|
175
|
+
clearTimeout(timer);
|
|
176
|
+
unwatch?.();
|
|
167
177
|
resolve(true);
|
|
168
178
|
}
|
|
169
179
|
},
|
|
@@ -177,14 +187,14 @@ export function useLtAuth() {
|
|
|
177
187
|
});
|
|
178
188
|
return true;
|
|
179
189
|
}
|
|
180
|
-
if (
|
|
190
|
+
if (resolvedAuthState.value?.user) {
|
|
181
191
|
switchToJwtMode().catch(() => {
|
|
182
192
|
});
|
|
183
193
|
return true;
|
|
184
194
|
}
|
|
185
195
|
return false;
|
|
186
196
|
} catch {
|
|
187
|
-
return !!
|
|
197
|
+
return !!resolvedAuthState.value?.user;
|
|
188
198
|
}
|
|
189
199
|
}
|
|
190
200
|
async function fetchFeatures() {
|
|
@@ -33,6 +33,13 @@ export declare function resetLtAuthClient(): void;
|
|
|
33
33
|
* This ensures Docker containers can be reconfigured without rebuilding.
|
|
34
34
|
* Trailing slashes are automatically stripped.
|
|
35
35
|
*
|
|
36
|
+
* During SSR the server-only `runtimeConfig.apiUrl` (`NUXT_API_URL`) comes first,
|
|
37
|
+
* the same chain as `resolveLtApiBaseUrl()`. The client is built on the server
|
|
38
|
+
* whenever `useLtAuth()` runs in setup, and a consumer's `getSession()` from a
|
|
39
|
+
* middleware or `useAsyncData` goes through it. The public URL may be a name only
|
|
40
|
+
* the browser resolves (on Windows `*.localhost` resolves in Chromium, not in
|
|
41
|
+
* Node), so the server must not depend on it when an internal address is set.
|
|
42
|
+
*
|
|
36
43
|
* ## Proxy mode (`NUXT_PUBLIC_API_PROXY=true`)
|
|
37
44
|
* When enabled, `baseURL` is set to `""` (same-origin) and `basePath` is
|
|
38
45
|
* prefixed with `/api` (e.g., `/api/iam`). The Vite dev proxy forwards
|
|
@@ -9,12 +9,13 @@ export function useLtAuthClient() {
|
|
|
9
9
|
const runtimeConfig = useRuntimeConfig();
|
|
10
10
|
const config = runtimeConfig.public?.ltExtensions?.auth || {};
|
|
11
11
|
const publicApiUrl = String(runtimeConfig.public?.apiUrl || "");
|
|
12
|
+
const serverApiUrl = import.meta.server ? String(runtimeConfig.apiUrl || "") : "";
|
|
12
13
|
const useProxy = isLocalDevApiProxy();
|
|
13
14
|
let basePath = config.basePath || "/iam";
|
|
14
15
|
if (useProxy && basePath && !basePath.startsWith("/api")) {
|
|
15
16
|
basePath = `/api${basePath}`;
|
|
16
17
|
}
|
|
17
|
-
const authBaseURL = (publicApiUrl || config.baseURL || "").replace(/\/+$/, "");
|
|
18
|
+
const authBaseURL = (serverApiUrl || publicApiUrl || config.baseURL || "").replace(/\/+$/, "");
|
|
18
19
|
return getOrCreateLtAuthClient({
|
|
19
20
|
baseURL: useProxy ? "" : authBaseURL,
|
|
20
21
|
basePath,
|
|
@@ -79,6 +79,13 @@ export declare function resetLtAuthClientSingleton(): void;
|
|
|
79
79
|
* Get or create the auth client singleton.
|
|
80
80
|
* This is the main entry point for accessing the auth client.
|
|
81
81
|
* If plugins were registered after initial creation, the client is recreated.
|
|
82
|
+
*
|
|
83
|
+
* WARNING — on the server this singleton is shared by EVERY concurrent render in
|
|
84
|
+
* the Node process, not scoped to one request. It is safe today only because
|
|
85
|
+
* nothing user-specific hangs on it. Never attach request-scoped data to it —
|
|
86
|
+
* forwarded cookies, an Authorization header, a per-user fetch option: one
|
|
87
|
+
* user's session would be rendered into another user's response. Forwarding the
|
|
88
|
+
* browser's cookies during SSR needs a client created per request, not this one.
|
|
82
89
|
*/
|
|
83
90
|
export declare function getOrCreateLtAuthClient(config?: LtAuthClientConfig): LtAuthClient;
|
|
84
91
|
/**
|
|
@@ -7,9 +7,22 @@ export async function waitForHydration(page, options = {}) {
|
|
|
7
7
|
});
|
|
8
8
|
}
|
|
9
9
|
export async function gotoAndWaitForHydration(page, url, options = {}) {
|
|
10
|
-
await page
|
|
10
|
+
await gotoWithAbortRetry(page, url);
|
|
11
11
|
await waitForHydration(page, options);
|
|
12
12
|
}
|
|
13
|
+
async function gotoWithAbortRetry(page, url, maxAttempts = 3) {
|
|
14
|
+
for (let attempt = 1; ; attempt++) {
|
|
15
|
+
try {
|
|
16
|
+
await page.goto(url);
|
|
17
|
+
return;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
if (attempt >= maxAttempts || !message.includes("net::ERR_ABORTED")) {
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
13
26
|
export async function waitForURLAndHydration(page, url, options = {}) {
|
|
14
27
|
const { timeout = 3e4, hydrationTimeout } = options;
|
|
15
28
|
await page.waitForURL(url, { timeout });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nuxt-extensions",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.2",
|
|
4
4
|
"description": "Reusable Nuxt 4 composables, components, and Better-Auth integration for lenne.tech projects",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"dev:build": "nuxt build playground",
|
|
61
61
|
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt prepare playground",
|
|
62
62
|
"build": "nuxt-module-build build",
|
|
63
|
-
"lint": "oxlint src/",
|
|
64
|
-
"lint:fix": "oxlint --fix
|
|
63
|
+
"lint": "oxlint src/ scripts/",
|
|
64
|
+
"lint:fix": "oxlint --fix src/ scripts/",
|
|
65
65
|
"format": "oxfmt --write src/",
|
|
66
66
|
"format:check": "oxfmt --check src/",
|
|
67
67
|
"version:sync": "node scripts/sync-module-version.mjs",
|
|
@@ -102,17 +102,18 @@
|
|
|
102
102
|
"@better-auth/passkey": "1.7.1",
|
|
103
103
|
"@nuxt/module-builder": "1.0.3",
|
|
104
104
|
"@nuxt/schema": "4.5.2",
|
|
105
|
-
"@nuxt/ui": "4.11.
|
|
106
|
-
"@playwright/test": "1.
|
|
107
|
-
"@types/node": "26.
|
|
105
|
+
"@nuxt/ui": "4.11.2",
|
|
106
|
+
"@playwright/test": "1.63.0",
|
|
107
|
+
"@types/node": "26.6.3",
|
|
108
108
|
"@vitest/coverage-v8": "4.1.11",
|
|
109
|
-
"@vue/server-renderer": "3.5.
|
|
109
|
+
"@vue/server-renderer": "3.5.43",
|
|
110
110
|
"better-auth": "1.7.1",
|
|
111
|
-
"
|
|
111
|
+
"cross-spawn": "7.0.6",
|
|
112
|
+
"happy-dom": "20.14.5",
|
|
112
113
|
"nuxt": "4.5.2",
|
|
113
|
-
"oxfmt": "0.
|
|
114
|
-
"oxlint": "1.
|
|
115
|
-
"reka-ui": "2.10.
|
|
114
|
+
"oxfmt": "0.70.0",
|
|
115
|
+
"oxlint": "1.85.0",
|
|
116
|
+
"reka-ui": "2.10.4",
|
|
116
117
|
"tus-js-client": "4.3.1",
|
|
117
118
|
"typescript": "5.9.3",
|
|
118
119
|
"vitest": "4.1.11",
|