@lenne.tech/nuxt-extensions 1.19.0 → 1.19.1
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 +14 -0
- 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 +28 -0
- package/dist/runtime/composables/auth/use-system-setup.js +12 -1
- package/dist/runtime/lib/auth-state.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -583,6 +583,20 @@ absolute URL is used as it is. If your project routes uploads through its own sa
|
|
|
583
583
|
instead, set `ltExtensions.tus.resolveAgainstApi: false` and the relative endpoint stays on the app
|
|
584
584
|
origin.
|
|
585
585
|
|
|
586
|
+
**Changing it per stage.** The `tus` options are part of the public runtime config, so a deployed
|
|
587
|
+
stage can override them through the environment, without a rebuild:
|
|
588
|
+
|
|
589
|
+
```bash
|
|
590
|
+
# Send this stage's uploads to another host (absolute URLs are used as they are)
|
|
591
|
+
NUXT_PUBLIC_LT_EXTENSIONS_TUS_DEFAULT_ENDPOINT=https://uploads.example.com/tus
|
|
592
|
+
# Keep a relative endpoint on the app origin (own same-origin proxy)
|
|
593
|
+
NUXT_PUBLIC_LT_EXTENSIONS_TUS_RESOLVE_AGAINST_API=false
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
Keep the relative default where you can: `NUXT_PUBLIC_API_URL` already differs per stage, so `'/tus'`
|
|
597
|
+
follows it. Uploads are sent with credentials, so a host other than the API has to receive the
|
|
598
|
+
session cookie, or every upload answers 401.
|
|
599
|
+
|
|
586
600
|
**Which id to keep.** After a successful upload, `item.fileId` is the id of the stored file, read
|
|
587
601
|
from the `X-File-Id` response header (nest-server 11.42.13+). Use it for file links and references.
|
|
588
602
|
`item.url` is the TUS upload resource; its last segment is the upload id, not the file id. `fileId`
|
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.19.
|
|
6
|
+
declare const version = "1.19.1";
|
|
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.19.
|
|
5
|
+
const version = "1.19.1";
|
|
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";
|
|
@@ -3,6 +3,7 @@ import { ltArrayBufferToBase64Url, ltBase64UrlToUint8Array } from "../../utils/c
|
|
|
3
3
|
import { clearLtAuthCookies, getLtApiBase, getLtAuthCookieNames, resolveLtAuthState } from "../../lib/auth-state.js";
|
|
4
4
|
import { useLtAuthClient } from "../use-lt-auth-client.js";
|
|
5
5
|
const VALIDATE_SESSION_TIMEOUT_MS = 1e4;
|
|
6
|
+
let staleJwtRefresh = null;
|
|
6
7
|
function useTranslation() {
|
|
7
8
|
const nuxtApp = useNuxtApp();
|
|
8
9
|
const i18n = nuxtApp.$i18n;
|
|
@@ -139,8 +140,35 @@ export function useLtAuth() {
|
|
|
139
140
|
});
|
|
140
141
|
}
|
|
141
142
|
}
|
|
143
|
+
if (response.status === 401 && isJwtMode.value && isAuthenticated.value && !needsCookies) {
|
|
144
|
+
const freshToken = await refreshStaleJwt();
|
|
145
|
+
if (freshToken) {
|
|
146
|
+
headers.set("Authorization", `Bearer ${freshToken}`);
|
|
147
|
+
return fetch(url, {
|
|
148
|
+
...options,
|
|
149
|
+
headers,
|
|
150
|
+
credentials: "omit"
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
142
154
|
return response;
|
|
143
155
|
}
|
|
156
|
+
async function refreshStaleJwt() {
|
|
157
|
+
const mint = async () => await switchToJwtMode() ? jwtToken.value : null;
|
|
158
|
+
if (!import.meta.client) {
|
|
159
|
+
return mint();
|
|
160
|
+
}
|
|
161
|
+
if (!staleJwtRefresh) {
|
|
162
|
+
staleJwtRefresh = mint().finally(() => {
|
|
163
|
+
staleJwtRefresh = null;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const token = await staleJwtRefresh;
|
|
167
|
+
if (token && jwtToken.value !== token) {
|
|
168
|
+
jwtToken.value = token;
|
|
169
|
+
}
|
|
170
|
+
return token;
|
|
171
|
+
}
|
|
144
172
|
const AUTHZ_KEYS = ["banExpires", "banReason", "banned", "emailVerified", "role", "roles", "twoFactorEnabled"];
|
|
145
173
|
function mergeSessionUser(sessionUser) {
|
|
146
174
|
const cached = resolvedAuthState.value?.user;
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { computed, useState } from "#imports";
|
|
2
2
|
import { ltSha256 } from "../../utils/crypto.js";
|
|
3
|
-
import { buildLtApiUrl } from "../../lib/auth-state.js";
|
|
3
|
+
import { buildLtApiUrl, resolveLtApiBaseUrl, warnMissingLtApiUrl } from "../../lib/auth-state.js";
|
|
4
|
+
function isApiUrlMissing() {
|
|
5
|
+
try {
|
|
6
|
+
return resolveLtApiBaseUrl().missing;
|
|
7
|
+
} catch {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
4
11
|
export function useSystemSetup() {
|
|
5
12
|
const needsSetupState = useState("lt-needs-setup", () => null);
|
|
6
13
|
const needsSetup = computed(() => needsSetupState.value);
|
|
7
14
|
async function checkSetupStatus() {
|
|
15
|
+
if (import.meta.server && isApiUrlMissing()) {
|
|
16
|
+
warnMissingLtApiUrl("server");
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
8
19
|
try {
|
|
9
20
|
const url = buildLtApiUrl("/system-setup/status");
|
|
10
21
|
const data = await $fetch(url);
|
|
@@ -78,7 +78,7 @@ export function isLocalDevApiProxy() {
|
|
|
78
78
|
}
|
|
79
79
|
const MISSING_API_URL_WARNING = {
|
|
80
80
|
client: "[LtExtensions] No API URL configured. Set NUXT_PUBLIC_API_URL. API paths stay relative and resolve against the app origin, so auth and setup calls 404 unless the app is served behind a same-origin reverse proxy.",
|
|
81
|
-
server: "[LtExtensions] No API URL configured for SSR. Set NUXT_API_URL or NUXT_PUBLIC_API_URL. API paths stay relative, so server-side requests never reach the backend: $fetch
|
|
81
|
+
server: "[LtExtensions] No API URL configured for SSR. Set NUXT_API_URL or NUXT_PUBLIC_API_URL. API paths stay relative, so server-side requests never reach the backend: $fetch sends them to this Nitro server itself and global fetch rejects them as an invalid URL."
|
|
82
82
|
};
|
|
83
83
|
function stripTrailingSlashes(url) {
|
|
84
84
|
return url.replace(/\/+$/, "");
|