@qelos/integrator-next 4.0.0 → 4.1.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 CHANGED
@@ -1,14 +1,18 @@
1
1
  # @qelos/integrator-next
2
2
 
3
- Qelos integrator middleware for **Next.js** — supports both the **App Router**
4
- and the **Pages Router**, on Next.js **14** and **15**. Drop it into your
5
- Next.js app to identify the user and active workspace via the Qelos SDK
6
- *before* your own handlers run, and to keep refresh-token cookies fresh on
7
- every request.
3
+ Next.js integrator for [Qelos](https://qelos.io). It turns your Next.js host into
4
+ a same-origin BFF for a managed Qelos app: Edge middleware resolves the current
5
+ user via `GET /api/me` with inbound cookies forwarded verbatim, a Node catch-all
6
+ route proxies `/api/**` to Qelos with `Set-Cookie` domain rewriting, and the
7
+ SDK reads live `Cookie` / `Authorization` headers on every call — no
8
+ integrator-managed access or refresh tokens.
8
9
 
9
- The package is a sibling of `@qelos/integrator-express` and
10
- `@qelos/integrator-nuxt` — they all expose the same `QelosRequestContext`
11
- shape (`{ user, workspace, workspaces, sdk, tokens }`).
10
+ Supports the **App Router** and the **Pages Router** on Next.js **14** and
11
+ **15**.
12
+
13
+ > Requires **Node 18+** — the middleware and proxy use
14
+ > [`Response.headers.getSetCookie()`](https://developer.mozilla.org/docs/Web/API/Headers/getSetCookie)
15
+ > to forward individual upstream `Set-Cookie` headers.
12
16
 
13
17
  ## Install
14
18
 
@@ -16,13 +20,11 @@ shape (`{ user, workspace, workspaces, sdk, tokens }`).
16
20
  pnpm add @qelos/integrator-next @qelos/sdk
17
21
  ```
18
22
 
19
- `next` (>=13.4) and `react` are peer dependencies. Tested with Next.js 14.2
20
- and 15.x on both the App Router and the Pages Router.
23
+ `next` (>=13.4) and `react` are peer dependencies.
21
24
 
22
25
  ## Quick start
23
26
 
24
- Set `QELOS_APP_URL` (and any optional vars below) in your environment, then
25
- re-export the pre-built middleware and use the no-arg context loader:
27
+ Set `QELOS_APP_URL`, then wire Edge middleware and a catch-all API proxy route.
26
28
 
27
29
  ```ts
28
30
  // middleware.ts
@@ -33,6 +35,16 @@ export const config = {
33
35
  };
34
36
  ```
35
37
 
38
+ ```ts
39
+ // app/api/[...qelos]/route.ts
40
+ import { createQelosApiProxyHandlers } from '@qelos/integrator-next/runtime/api-proxy';
41
+
42
+ const { runtime, GET, POST, PUT, PATCH, DELETE, OPTIONS } =
43
+ createQelosApiProxyHandlers({ appUrl: process.env.QELOS_APP_URL! });
44
+
45
+ export { runtime, GET, POST, PUT, PATCH, DELETE, OPTIONS };
46
+ ```
47
+
36
48
  ```tsx
37
49
  // app/dashboard/page.tsx
38
50
  import { getQelosContext } from '@qelos/integrator-next/context';
@@ -41,86 +53,86 @@ export default async function Dashboard() {
41
53
  const { user, sdk } = await getQelosContext();
42
54
  if (!user) return <p>Please sign in.</p>;
43
55
  const products = await sdk.entities('products').getList();
44
- return <div>Welcome {user.fullName}, you have {products.length} products</div>;
56
+ return (
57
+ <div>
58
+ Welcome {user.fullName}, you have {products.length} products
59
+ </div>
60
+ );
45
61
  }
46
62
  ```
47
63
 
48
64
  ### Environment variables
49
65
 
50
66
  | Variable | Default | Description |
51
- |---|---|---|
52
- | `QELOS_APP_URL` | — (required) | Qelos backend base URL |
53
- | `QELOS_API_TOKEN` | — | Service-to-service token (skips refresh logic) |
54
- | `QELOS_ACCESS_TOKEN_COOKIE` | `q_access_token` | Cookie name for the access token |
55
- | `QELOS_REFRESH_TOKEN_COOKIE` | `q_refresh_token` | Cookie name for the refresh token |
56
- | `QELOS_REQUIRE_AUTH` | `false` | Set `true` to reject anonymous requests with 401 |
57
- | `QELOS_SKIP_PATHS` | — | Comma-separated path prefixes to bypass entirely |
67
+ |----------|---------|-------------|
68
+ | `QELOS_APP_URL` | — (required for default exports) | Qelos managed-app base URL |
69
+ | `QELOS_API_TOKEN` | — | Service-to-service token (skips cookie identity for anonymous resolution) |
70
+ | `QELOS_REQUIRE_AUTH` | `false` | `true` / `1` → anonymous requests get `401` from middleware |
71
+ | `QELOS_SKIP_PATHS` | — | Comma-separated path prefixes to bypass middleware |
72
+ | `QELOS_DISABLE_PROXY` | `false` | `true` when you are **not** using the catch-all `/api/**` proxy — skips auto `/api/` in middleware `skipPaths` |
58
73
 
59
- ## Explicit configuration (App Router)
74
+ Dev-time proxy target overrides (same resolution order as the proxy):
60
75
 
61
- When you need control over `resolveWorkspace`, `onTokenRefresh`, or any other
62
- option, call the factory yourself.
76
+ 1. `NEXT_QELOS_PROXY_TARGET`
77
+ 2. `QELOS_IP`
78
+ 3. `QELOS_API_IP`
79
+ 4. `appUrl` from config / `QELOS_APP_URL`
63
80
 
64
- ### 1. Edge middleware
81
+ ## BFF proxy (`/api/**`)
65
82
 
66
- ```ts
67
- // middleware.ts
68
- import { createQelosMiddleware } from '@qelos/integrator-next/middleware';
83
+ Register a catch-all App Router handler (see above) that exports the handlers
84
+ from `createQelosApiProxyHandlers`. Every request your app does not handle
85
+ itself is forwarded to the configured Qelos origin; the response body streams
86
+ back and upstream `Set-Cookie` headers are rewritten so `Domain=` matches the
87
+ inbound `Host` (port stripped).
69
88
 
70
- export default createQelosMiddleware({
71
- config: {
72
- appUrl: process.env.QELOS_APP_URL!,
73
- skipPaths: ['/_next', '/favicon.ico'],
74
- requireAuth: false,
75
- },
76
- resolveWorkspace: ({ req, workspaces }) => {
77
- const slug = req.nextUrl.searchParams.get('workspace');
78
- return workspaces.find((w) => (w as any).slug === slug) ?? workspaces[0] ?? null;
79
- },
80
- });
89
+ User-defined routes under `app/api/...` still take precedence over the catch-all
90
+ segment — the proxy only runs for paths nothing else matched.
81
91
 
82
- export const config = {
83
- matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
84
- };
85
- ```
92
+ ### Opting out (`disableProxy`)
86
93
 
87
- The middleware:
94
+ Set `disableProxy: true` on `QelosNextConfig` when you do not use the catch-all
95
+ proxy. Middleware will then **not** auto-prepend `/api/` to `skipPaths`, so you
96
+ can run your own `/api/*` handlers without the integrator skipping them for the
97
+ proxy.
88
98
 
89
- - Reads tokens from cookies (`q_access_token`, `q_refresh_token`) or the
90
- `Authorization` header.
91
- - Calls the Qelos SDK to resolve the user and the active workspace.
92
- - Forwards the resolved ids to downstream handlers via the
93
- `x-qelos-user-id` and `x-qelos-workspace-id` request headers.
94
- - Refreshes the access/refresh token pair when needed and writes the new
95
- cookies onto the outbound response.
96
- - Returns `401` early when `config.requireAuth: true` and the user cannot be
97
- resolved.
99
+ WebSocket upgrades are not proxied.
98
100
 
99
- ### 2. Server components (RSC)
101
+ ## Edge middleware
100
102
 
101
- `getQelosContext()` is safe to call inside React Server Components on both
102
- Next.js 14 (sync `cookies()` / `headers()`) and Next.js 15 (async). Wrap it
103
- with React's `cache()` so re-renders within the same request reuse the result:
103
+ On each matched request, middleware:
104
104
 
105
- ```tsx
106
- // lib/qelos.ts
107
- import { cache } from 'react';
108
- import { getQelosContext } from '@qelos/integrator-next/context';
105
+ 1. Resolves the upstream origin (`NEXT_QELOS_PROXY_TARGET` → `QELOS_IP` →
106
+ `QELOS_API_IP` → `appUrl`). If neither that nor `apiToken` is configured and
107
+ `requireAuth` is false, identity headers are cleared and the request
108
+ continues anonymously.
109
+ 2. When an upstream origin exists, issues `fetch('${origin}/api/me', { redirect:
110
+ 'manual' })` with the inbound `Cookie` and `Authorization` headers forwarded.
111
+ 3. Appends every upstream `Set-Cookie` to the outgoing response after rewriting
112
+ `Domain=` to the inbound `Host`.
113
+ 4. On `200` JSON, uses that body as `IUser`, loads workspaces via the SDK, and
114
+ sets the active workspace from `user.workspace` (or your `resolveWorkspace`
115
+ callback) — **not** `workspaces[0]`.
116
+ 5. Forwards `x-qelos-user-id` and `x-qelos-workspace-id` on the rewritten request
117
+ headers for downstream App Router code.
109
118
 
110
- export const loadQelos = cache(() => getQelosContext());
111
- ```
119
+ When the proxy is enabled (`disableProxy !== true`), `/api/` is prepended to
120
+ `skipPaths` so middleware does not run the `/api/me` probe on proxied API
121
+ traffic (avoids double upstream calls).
112
122
 
113
- ```tsx
114
- // app/page.tsx
115
- import { loadQelos } from '../lib/qelos';
123
+ > Edge middleware runs in the Edge runtime. The `/api/me` round-trip uses the
124
+ > standard `fetch` API with `redirect: 'manual'`. In local dev over plain HTTP,
125
+ > browsers may drop upstream `Secure` cookies — use HTTPS locally or configure
126
+ > Qelos for non-`Secure` cookies in development.
116
127
 
117
- export default async function Page() {
118
- const { user, workspace } = await loadQelos();
119
- return <p>Hello {user?.fullName ?? 'guest'} — {workspace?.name}</p>;
120
- }
121
- ```
128
+ ## App Router server code
129
+
130
+ Wrap `getQelosContext()` with React `cache()` if you want one resolution per
131
+ request. It performs the same `/api/me` identification as middleware (with live
132
+ headers) and attempts to apply upstream `Set-Cookie` values through
133
+ `next/headers` `cookies().set` when the runtime allows it.
122
134
 
123
- ### 3. Route handlers (`app/api/**/route.ts`)
135
+ ### Route handlers
124
136
 
125
137
  ```ts
126
138
  // app/api/me/route.ts
@@ -133,26 +145,8 @@ export const GET = withQelosRoute((_req, _ctx, qelos) => {
133
145
  });
134
146
  ```
135
147
 
136
- Anywhere downstream — including modules outside the React tree — can read the
137
- active context from AsyncLocalStorage via `getStoredQelosContext()`, provided
138
- execution went through `withQelosRoute`, `withQelosContext`, or one of the
139
- Pages Router wrappers.
140
-
141
- ```ts
142
- // services/products.ts
143
- import { getStoredQelosContext } from '@qelos/integrator-next/context';
144
-
145
- export async function listProducts() {
146
- const qelos = getStoredQelosContext();
147
- if (!qelos?.sdk) throw new Error('no qelos context');
148
- return qelos.sdk.entities('products').getList();
149
- }
150
- ```
151
-
152
148
  ## Pages Router
153
149
 
154
- ### API routes
155
-
156
150
  ```ts
157
151
  // pages/api/me.ts
158
152
  import { withQelosApi } from '@qelos/integrator-next/pages';
@@ -165,92 +159,43 @@ export default withQelosApi(
165
159
  );
166
160
  ```
167
161
 
168
- ### `getServerSideProps`
169
-
170
162
  ```ts
171
163
  // pages/dashboard.tsx
172
164
  import { withQelosSSR } from '@qelos/integrator-next/pages';
173
165
 
174
166
  export const getServerSideProps = withQelosSSR(
175
- async (_ctx, qelos) => ({ props: { user: qelos.user, workspace: qelos.workspace } }),
167
+ async (_ctx, qelos) => ({
168
+ props: { user: qelos.user, workspace: qelos.workspace },
169
+ }),
176
170
  { config: { appUrl: process.env.QELOS_APP_URL!, requireAuth: true } },
177
171
  );
178
172
  ```
179
173
 
180
- ## Token refresh
181
-
182
- When a request arrives with an expired access token, the SDK's failed-auth
183
- path triggers a refresh, in order:
184
-
185
- 1. If a refresh token is present, calls
186
- `sdk.authentication.refreshToken()` (`POST /api/token/refresh`) — issues a
187
- new access + refresh pair.
188
- 2. Otherwise, calls `sdk.authentication.refreshCookieToken()`
189
- (`POST /api/cookie/refresh`) — used for cookie-only sessions that do not
190
- carry a separate refresh token (e.g. social-auth flows).
191
-
192
- The new pair is then written back to cookies using the configured
193
- `accessTokenCookie` / `refreshTokenCookie` names — automatically in App
194
- Router middleware (`response.cookies.set`), Pages Router API routes
195
- (`Set-Cookie` header), and `getServerSideProps` responses.
196
-
197
- App Router server components and route handlers cannot mutate cookies after
198
- rendering starts, so the default refresh hook there is a no-op — the new
199
- tokens are still applied to the in-memory pair so subsequent SDK calls in the
200
- same request use the fresh access token. To persist the refreshed pair, hand
201
- the request off to a route handler that calls `cookies().set(...)`.
202
-
203
- Override the behaviour by passing `onTokenRefresh` to any of the wrappers.
204
- The hook receives:
205
-
206
- ```ts
207
- interface TokenRefreshContext<T> {
208
- target: T; // NextResponse | NextApiResponse | ServerResponse | null
209
- oldTokens: { accessToken?: string; refreshToken?: string };
210
- newTokens: { accessToken: string; refreshToken?: string };
211
- sdk: QelosSDK;
212
- }
213
- ```
214
-
215
- ### Manual cookie refresh
216
-
217
- Long-lived integrator-hosted sessions can also call the SDK directly to
218
- proactively refresh the cookie token. From a route handler that owns the
219
- response (so it can mutate cookies):
174
+ ## Configuration (`QelosNextConfig`)
220
175
 
221
- ```ts
222
- // app/api/session/refresh/route.ts
223
- import { NextResponse } from 'next/server';
224
- import { withQelosRoute } from '@qelos/integrator-next/route';
225
-
226
- export const POST = withQelosRoute(async (_req, _ctx, qelos) => {
227
- const result = await qelos.sdk.authentication.refreshCookieToken();
228
- // result.headers['set-cookie'] — fresh cookie value to forward
229
- return NextResponse.json({ user: result.payload.user });
230
- });
231
- ```
232
-
233
- ## Configuration
234
-
235
- ```ts
236
- interface QelosNextConfig {
237
- appUrl: string; // Qelos backend base URL
238
- apiToken?: string; // service-to-service token (skips refresh logic)
239
- accessTokenCookie?: string; // default 'q_access_token'
240
- refreshTokenCookie?: string; // default 'q_refresh_token'
241
- requireAuth?: boolean; // 401/redirect on anonymous (default false)
242
- skipPaths?: string[]; // path prefixes to bypass entirely
243
- sdkOptions?: Partial<QelosSDKOptions>;
244
- }
245
- ```
176
+ | Field | Description |
177
+ |-------|-------------|
178
+ | `appUrl` | Qelos managed-app base URL |
179
+ | `apiToken` | Static token — no `/api/me` cookie identity |
180
+ | `requireAuth` | Reject anonymous requests (`401` / redirect) |
181
+ | `skipPaths` | Path prefixes to bypass middleware (and `/api/` is auto-prepended when the proxy is enabled) |
182
+ | `disableProxy` | Opt out of auto `/api/` skip for middleware |
183
+ | `sdkOptions` | Extra `QelosSDK` constructor options |
246
184
 
247
185
  ## Subpath exports
248
186
 
249
187
  | Import | Purpose |
250
- |---|---|
251
- | `@qelos/integrator-next` | Everything (re-exports of all subpaths) |
252
- | `@qelos/integrator-next/middleware` | Edge middleware (`qelosMiddleware`, `createQelosMiddleware`) |
253
- | `@qelos/integrator-next/context` | Server-component / route-handler context (`getQelosContext`, `getStoredQelosContext`) |
254
- | `@qelos/integrator-next/route` | App Router route wrapper (`withQelosRoute`) |
255
- | `@qelos/integrator-next/pages` | Pages Router wrappers (`withQelosApi`, `withQelosSSR`) |
256
- | `@qelos/integrator-next/types` | Shared types |
188
+ |--------|---------|
189
+ | `@qelos/integrator-next` | Barrel |
190
+ | `@qelos/integrator-next/middleware` | Edge middleware |
191
+ | `@qelos/integrator-next/context` | `getQelosContext`, AsyncLocalStorage helpers |
192
+ | `@qelos/integrator-next/route` | `withQelosRoute` |
193
+ | `@qelos/integrator-next/pages` | Pages Router wrappers |
194
+ | `@qelos/integrator-next/runtime/api-proxy` | Catch-all proxy handlers (`runtime = 'nodejs'`) |
195
+ | `@qelos/integrator-next/types` | Types and header name constants |
196
+
197
+ ## Social auth
198
+
199
+ `completeSocialAuthCallback` and the re-exported SDK helpers forward Qelos
200
+ session cookies from `socialCallback` onto your Node response — use them from
201
+ a route handler that owns the response object.
package/dist/context.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { IUser } from '@qelos/sdk/dist/authentication';
2
2
  import type { IWorkspace } from '@qelos/sdk/workspaces';
3
- import type { QelosNextConfig, QelosRequestContext, TokenRefreshHook } from './types';
3
+ import type { QelosNextConfig, QelosRequestContext } from './types';
4
4
  /**
5
5
  * Run `fn` with `ctx` as the active Qelos request context. Code anywhere in
6
6
  * the resulting async stack can call `getStoredQelosContext()` to retrieve it
@@ -15,15 +15,9 @@ export declare function getStoredQelosContext(): QelosRequestContext | null;
15
15
  export interface GetQelosContextOptions {
16
16
  config: QelosNextConfig;
17
17
  /**
18
- * Hook invoked after a successful token refresh. App Router server
19
- * components and route handlers cannot mutate cookies after rendering
20
- * starts, so the default is a no-op. Callers handling refresh through a
21
- * route handler can override this to call `cookies().set(...)`.
22
- */
23
- onTokenRefresh?: TokenRefreshHook<null>;
24
- /**
25
- * Resolve the active workspace for a request. Defaults to picking the first
26
- * workspace returned from `sdk.workspaces.getList()`.
18
+ * Resolve the active workspace for a request. Defaults to whatever
19
+ * `/api/me` reports on `user.workspace` (the user's currently activated
20
+ * workspace, or `null` when none is active).
27
21
  */
28
22
  resolveWorkspace?: (params: {
29
23
  user: IUser;
@@ -33,7 +27,7 @@ export interface GetQelosContextOptions {
33
27
  /**
34
28
  * Identify the user / workspace for the current App Router request and
35
29
  * return the Qelos context. Safe to call multiple times within the same
36
- * request — each call performs its own SDK round-trip, so wrap it with
30
+ * request — each call performs its own `/api/me` round-trip, so wrap it with
37
31
  * React's `cache()` if you want a single resolution per render.
38
32
  *
39
33
  * Calling without arguments uses the env-derived config (see
package/dist/context.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { rewriteSetCookieDomain } from './cookies';
2
3
  import { getDefaultQelosConfig } from './env-config';
4
+ import { fetchMeIdentity } from './me-client';
5
+ import { resolveQelosProxyTarget } from './proxy-target';
3
6
  import { createRequestSdk } from './sdk-factory';
4
- const DEFAULT_ACCESS_COOKIE = 'q_access_token';
5
- const DEFAULT_REFRESH_COOKIE = 'q_refresh_token';
6
7
  const storage = new AsyncLocalStorage();
7
8
  /**
8
9
  * Run `fn` with `ctx` as the active Qelos request context. Code anywhere in
@@ -29,27 +30,46 @@ function loadNextHeaders() {
29
30
  }
30
31
  return nextHeadersModulePromise;
31
32
  }
32
- async function readTokensFromHeaders(config) {
33
- const { cookies, headers } = await loadNextHeaders();
34
- const accessCookie = config.accessTokenCookie || DEFAULT_ACCESS_COOKIE;
35
- const refreshCookie = config.refreshTokenCookie || DEFAULT_REFRESH_COOKIE;
36
- const jar = await cookies();
37
- const hdr = await headers();
38
- const cookieAccess = jar.get(accessCookie)?.value;
39
- const cookieRefresh = jar.get(refreshCookie)?.value;
40
- const authHeader = hdr.get('authorization');
41
- const headerAccess = authHeader && authHeader.toLowerCase().startsWith('bearer ')
42
- ? authHeader.slice(7).trim()
43
- : undefined;
33
+ async function getInboundAuthHeaders() {
34
+ const { headers } = await loadNextHeaders();
35
+ const hdr = await Promise.resolve(headers());
44
36
  return {
45
- accessToken: headerAccess || cookieAccess || undefined,
46
- refreshToken: cookieRefresh || undefined,
37
+ cookie: hdr.get('cookie') ?? undefined,
38
+ authorization: hdr.get('authorization') ?? undefined,
39
+ host: hdr.get('host'),
47
40
  };
48
41
  }
42
+ async function forwardSetCookieThroughNextCookies(rawLines, originalHost) {
43
+ const rewritten = rawLines.map((v) => rewriteSetCookieDomain(v, originalHost ?? undefined));
44
+ try {
45
+ const { cookies } = await import('next/headers');
46
+ const jar = await Promise.resolve(cookies());
47
+ for (const line of rewritten) {
48
+ const semi = line.indexOf(';');
49
+ const nv = (semi === -1 ? line : line.slice(0, semi)).trim();
50
+ const eq = nv.indexOf('=');
51
+ if (eq <= 0)
52
+ continue;
53
+ const name = nv.slice(0, eq).trim();
54
+ const value = nv.slice(eq + 1).trim();
55
+ if (!name)
56
+ continue;
57
+ try {
58
+ jar.set(name, value, { path: '/' });
59
+ }
60
+ catch {
61
+ // not writable in this context
62
+ }
63
+ }
64
+ }
65
+ catch {
66
+ //
67
+ }
68
+ }
49
69
  /**
50
70
  * Identify the user / workspace for the current App Router request and
51
71
  * return the Qelos context. Safe to call multiple times within the same
52
- * request — each call performs its own SDK round-trip, so wrap it with
72
+ * request — each call performs its own `/api/me` round-trip, so wrap it with
53
73
  * React's `cache()` if you want a single resolution per render.
54
74
  *
55
75
  * Calling without arguments uses the env-derived config (see
@@ -59,49 +79,49 @@ async function readTokensFromHeaders(config) {
59
79
  export async function getQelosContext(options) {
60
80
  const resolved = options ?? { config: getDefaultQelosConfig() };
61
81
  const { config, resolveWorkspace } = resolved;
62
- const tokens = await readTokensFromHeaders(config);
63
- const sdk = createRequestSdk({
64
- config,
65
- tokens,
66
- refreshTarget: null,
67
- onTokenRefresh: resolved.onTokenRefresh,
68
- });
82
+ const getHeaders = () => getInboundAuthHeaders();
83
+ const sdk = createRequestSdk({ config, getHeaders });
69
84
  const ctx = {
70
85
  user: null,
71
86
  workspace: null,
72
87
  workspaces: [],
73
88
  sdk,
74
- tokens,
75
89
  };
76
- const hasAuthMaterial = Boolean(config.apiToken || tokens.accessToken || tokens.refreshToken);
77
- if (!hasAuthMaterial) {
90
+ const base = resolveQelosProxyTarget(config);
91
+ if (!base && !config.apiToken) {
78
92
  return ctx;
79
93
  }
80
- try {
81
- ctx.user = await sdk.authentication.getLoggedInUser();
94
+ if (base) {
95
+ const h = await getInboundAuthHeaders();
96
+ const { response, user } = await fetchMeIdentity({
97
+ base,
98
+ cookie: h.cookie,
99
+ authorization: h.authorization,
100
+ });
101
+ const setCookieValues = response.headers.getSetCookie?.() ?? [];
102
+ await forwardSetCookieThroughNextCookies(setCookieValues, h.host);
103
+ ctx.user = user;
82
104
  }
83
- catch {
105
+ if (!ctx.user) {
84
106
  return ctx;
85
107
  }
86
- if (!ctx.user)
87
- return ctx;
88
108
  try {
89
109
  ctx.workspaces = await sdk.workspaces.getList();
90
110
  }
91
111
  catch {
92
112
  ctx.workspaces = [];
93
113
  }
94
- if (ctx.workspaces.length) {
95
- if (resolveWorkspace) {
96
- ctx.workspace =
97
- (await resolveWorkspace({
98
- user: ctx.user,
99
- workspaces: ctx.workspaces,
100
- })) || null;
101
- }
102
- else {
103
- ctx.workspace = ctx.workspaces[0] || null;
104
- }
114
+ if (resolveWorkspace) {
115
+ ctx.workspace =
116
+ (await resolveWorkspace({
117
+ user: ctx.user,
118
+ workspaces: ctx.workspaces,
119
+ })) || null;
120
+ }
121
+ else {
122
+ ctx.workspace =
123
+ ctx.user.workspace ||
124
+ null;
105
125
  }
106
126
  return ctx;
107
127
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Rewrite the `Domain=` attribute of a single `Set-Cookie` header value.
3
+ *
4
+ * - If the cookie contains a `Domain=<value>` attribute (case-insensitive), its
5
+ * value is replaced with `newDomain`, with any trailing `:port` suffix
6
+ * stripped first (cookie `Domain` attributes do not include a port).
7
+ * - If `newDomain` is `undefined` (or empty), the entire `; Domain=<value>`
8
+ * segment is removed so the browser scopes the cookie to the current host.
9
+ * - If no `Domain=` attribute is present, the input is returned unchanged.
10
+ *
11
+ * All other attributes, their casing/order and the original cookie name/value
12
+ * bytes are preserved.
13
+ */
14
+ export declare function rewriteSetCookieDomain(setCookie: string, newDomain: string | undefined): string;
15
+ /**
16
+ * Apply {@link rewriteSetCookieDomain} to each entry of a `Set-Cookie` array
17
+ * (e.g. the result of `Headers.getSetCookie()`).
18
+ */
19
+ export declare function rewriteSetCookieDomains(values: string[], newDomain: string | undefined): string[];
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Rewrite the `Domain=` attribute of a single `Set-Cookie` header value.
3
+ *
4
+ * - If the cookie contains a `Domain=<value>` attribute (case-insensitive), its
5
+ * value is replaced with `newDomain`, with any trailing `:port` suffix
6
+ * stripped first (cookie `Domain` attributes do not include a port).
7
+ * - If `newDomain` is `undefined` (or empty), the entire `; Domain=<value>`
8
+ * segment is removed so the browser scopes the cookie to the current host.
9
+ * - If no `Domain=` attribute is present, the input is returned unchanged.
10
+ *
11
+ * All other attributes, their casing/order and the original cookie name/value
12
+ * bytes are preserved.
13
+ */
14
+ export function rewriteSetCookieDomain(setCookie, newDomain) {
15
+ const domainSegment = /;\s*Domain\s*=\s*[^;]+/i;
16
+ if (!domainSegment.test(setCookie))
17
+ return setCookie;
18
+ const stripped = newDomain ? stripPort(newDomain) : '';
19
+ if (!stripped) {
20
+ return setCookie.replace(domainSegment, '');
21
+ }
22
+ return setCookie.replace(/(;\s*Domain\s*=\s*)[^;]+/i, `$1${stripped}`);
23
+ }
24
+ /**
25
+ * Apply {@link rewriteSetCookieDomain} to each entry of a `Set-Cookie` array
26
+ * (e.g. the result of `Headers.getSetCookie()`).
27
+ */
28
+ export function rewriteSetCookieDomains(values, newDomain) {
29
+ return values.map((value) => rewriteSetCookieDomain(value, newDomain));
30
+ }
31
+ function stripPort(host) {
32
+ if (host.startsWith('[')) {
33
+ const end = host.indexOf(']');
34
+ return end === -1 ? host : host.slice(1, end);
35
+ }
36
+ const colon = host.indexOf(':');
37
+ return colon === -1 ? host : host.slice(0, colon);
38
+ }
39
+ //# sourceMappingURL=cookies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../src/cookies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACpC,SAAiB,EACjB,SAA6B;IAE7B,MAAM,aAAa,GAAG,yBAAyB,CAAC;IAChD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAErD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,CACtB,2BAA2B,EAC3B,KAAK,QAAQ,EAAE,CAChB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAgB,EAChB,SAA6B;IAE7B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACpD,CAAC"}
@@ -8,11 +8,11 @@ import type { QelosNextConfig } from './types';
8
8
  * Recognized variables:
9
9
  *
10
10
  * - `QELOS_APP_URL` (required) — Qelos backend base URL.
11
- * - `QELOS_API_TOKEN` — service-to-service token (skips refresh logic).
12
- * - `QELOS_ACCESS_TOKEN_COOKIE` — defaults to `q_access_token`.
13
- * - `QELOS_REFRESH_TOKEN_COOKIE` — defaults to `q_refresh_token`.
11
+ * - `QELOS_API_TOKEN` — service-to-service token (skips cookie identity).
14
12
  * - `QELOS_REQUIRE_AUTH` — `"true"` to reject anonymous requests.
15
13
  * - `QELOS_SKIP_PATHS` — comma-separated path prefixes to bypass.
14
+ * - `QELOS_DISABLE_PROXY` — `"true"` to disable auto `/api/` skip in middleware
15
+ * (when you are not using the BFF catch-all proxy).
16
16
  */
17
17
  export declare function loadQelosConfigFromEnv(env?: NodeJS.ProcessEnv): QelosNextConfig;
18
18
  /**