@lupinum/better-convex-nuxt 0.8.0-beta.40
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/LICENSE +21 -0
- package/LICENSES/Apache-2.0.txt +201 -0
- package/README.md +151 -0
- package/THIRD_PARTY_NOTICES.md +38 -0
- package/dist/module.d.mts +55 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +309 -0
- package/dist/runtime/auth/auth-identity.d.ts +31 -0
- package/dist/runtime/auth/auth-identity.js +21 -0
- package/dist/runtime/auth/better-auth-browser-adapter.d.ts +33 -0
- package/dist/runtime/auth/better-auth-browser-adapter.js +215 -0
- package/dist/runtime/auth/client-engine-types.d.ts +4 -0
- package/dist/runtime/auth/client-engine-types.js +0 -0
- package/dist/runtime/auth/integrated-client.d.ts +25 -0
- package/dist/runtime/auth/integrated-client.js +132 -0
- package/dist/runtime/auth/operation-tracker.d.ts +7 -0
- package/dist/runtime/auth/operation-tracker.js +14 -0
- package/dist/runtime/auth/session-synchronization.d.ts +23 -0
- package/dist/runtime/auth/session-synchronization.js +156 -0
- package/dist/runtime/auth/token-fetcher.d.ts +66 -0
- package/dist/runtime/auth/token-fetcher.js +131 -0
- package/dist/runtime/auth/validate-auth-client-definition.d.ts +12 -0
- package/dist/runtime/auth/validate-auth-client-definition.js +47 -0
- package/dist/runtime/auth-client/convex-client-plugin.d.ts +31 -0
- package/dist/runtime/auth-client/convex-client-plugin.js +14 -0
- package/dist/runtime/auth-client/definition-types.d.ts +6 -0
- package/dist/runtime/auth-client/definition-types.js +0 -0
- package/dist/runtime/auth-client/empty-definition.d.ts +2 -0
- package/dist/runtime/auth-client/empty-definition.js +2 -0
- package/dist/runtime/auth-client/index.d.ts +71 -0
- package/dist/runtime/auth-client/index.js +3 -0
- package/dist/runtime/cli/auth-schema.d.ts +2 -0
- package/dist/runtime/cli/auth-schema.js +169 -0
- package/dist/runtime/cli/convex.d.ts +11 -0
- package/dist/runtime/cli/convex.js +274 -0
- package/dist/runtime/composables/useConvex.d.ts +4 -0
- package/dist/runtime/composables/useConvex.js +9 -0
- package/dist/runtime/composables/useConvexAction.d.ts +4 -0
- package/dist/runtime/composables/useConvexAction.js +18 -0
- package/dist/runtime/composables/useConvexAttachment.d.ts +9 -0
- package/dist/runtime/composables/useConvexAttachment.js +14 -0
- package/dist/runtime/composables/useConvexAuth.d.ts +10 -0
- package/dist/runtime/composables/useConvexAuth.js +37 -0
- package/dist/runtime/composables/useConvexConfig.d.ts +12 -0
- package/dist/runtime/composables/useConvexConfig.js +7 -0
- package/dist/runtime/composables/useConvexConnectionState.d.ts +33 -0
- package/dist/runtime/composables/useConvexConnectionState.js +24 -0
- package/dist/runtime/composables/useConvexFileUpload.d.ts +169 -0
- package/dist/runtime/composables/useConvexFileUpload.js +198 -0
- package/dist/runtime/composables/useConvexMutation.d.ts +13 -0
- package/dist/runtime/composables/useConvexMutation.js +24 -0
- package/dist/runtime/composables/useConvexPaginatedQuery.d.ts +13 -0
- package/dist/runtime/composables/useConvexPaginatedQuery.js +256 -0
- package/dist/runtime/composables/useConvexQuery.d.ts +19 -0
- package/dist/runtime/composables/useConvexQuery.js +308 -0
- package/dist/runtime/convex-auth/adapter/create-adapter.d.ts +33 -0
- package/dist/runtime/convex-auth/adapter/create-adapter.js +308 -0
- package/dist/runtime/convex-auth/adapter/define-functions.d.ts +160 -0
- package/dist/runtime/convex-auth/adapter/define-functions.js +497 -0
- package/dist/runtime/convex-auth/adapter/generate-schema.d.ts +16 -0
- package/dist/runtime/convex-auth/adapter/generate-schema.js +332 -0
- package/dist/runtime/convex-auth/adapter/metadata.d.ts +44 -0
- package/dist/runtime/convex-auth/adapter/metadata.js +91 -0
- package/dist/runtime/convex-auth/adapter/query.d.ts +32 -0
- package/dist/runtime/convex-auth/adapter/query.js +275 -0
- package/dist/runtime/convex-auth/adapter/relationships.d.ts +20 -0
- package/dist/runtime/convex-auth/adapter/relationships.js +128 -0
- package/dist/runtime/convex-auth/component/_generated/api.js +5 -0
- package/dist/runtime/convex-auth/component/_generated/component.d.ts +116 -0
- package/dist/runtime/convex-auth/component/_generated/component.js +0 -0
- package/dist/runtime/convex-auth/component/_generated/dataModel.js +0 -0
- package/dist/runtime/convex-auth/component/_generated/server.js +16 -0
- package/dist/runtime/convex-auth/component/adapter.d.ts +142 -0
- package/dist/runtime/convex-auth/component/adapter.js +16 -0
- package/dist/runtime/convex-auth/component/convex.config.d.ts +2 -0
- package/dist/runtime/convex-auth/component/convex.config.js +3 -0
- package/dist/runtime/convex-auth/component/schema.d.ts +799 -0
- package/dist/runtime/convex-auth/component/schema.js +180 -0
- package/dist/runtime/convex-auth/component/schemaMetadata.d.ts +2094 -0
- package/dist/runtime/convex-auth/component/schemaMetadata.js +2161 -0
- package/dist/runtime/convex-auth/context.d.ts +5 -0
- package/dist/runtime/convex-auth/context.js +8 -0
- package/dist/runtime/convex-auth/create-auth-component.d.ts +41 -0
- package/dist/runtime/convex-auth/create-auth-component.js +157 -0
- package/dist/runtime/convex-auth/index.d.ts +11 -0
- package/dist/runtime/convex-auth/index.js +7 -0
- package/dist/runtime/convex-auth/internal-session.d.ts +2 -0
- package/dist/runtime/convex-auth/internal-session.js +1 -0
- package/dist/runtime/convex-auth/jwks-rotation.d.ts +58 -0
- package/dist/runtime/convex-auth/jwks-rotation.js +163 -0
- package/dist/runtime/convex-auth/oauth-live-access.d.ts +17 -0
- package/dist/runtime/convex-auth/oauth-live-access.js +78 -0
- package/dist/runtime/convex-auth/oauth-provider-compat.d.ts +10 -0
- package/dist/runtime/convex-auth/oauth-provider-compat.js +170 -0
- package/dist/runtime/convex-auth/oauth-resource.d.ts +39 -0
- package/dist/runtime/convex-auth/oauth-resource.js +118 -0
- package/dist/runtime/convex-auth/oauth-security.d.ts +82 -0
- package/dist/runtime/convex-auth/oauth-security.js +454 -0
- package/dist/runtime/convex-auth/origin.d.ts +4 -0
- package/dist/runtime/convex-auth/origin.js +9 -0
- package/dist/runtime/convex-auth/plugin.d.ts +18 -0
- package/dist/runtime/convex-auth/plugin.js +605 -0
- package/dist/runtime/convex-auth/provider.d.ts +2 -0
- package/dist/runtime/convex-auth/provider.js +11 -0
- package/dist/runtime/convex-auth/test.d.ts +410 -0
- package/dist/runtime/convex-auth/test.js +9 -0
- package/dist/runtime/convex-auth/types.d.ts +18 -0
- package/dist/runtime/convex-auth/types.js +0 -0
- package/dist/runtime/convex-auth/user-projection.d.ts +106 -0
- package/dist/runtime/convex-auth/user-projection.js +128 -0
- package/dist/runtime/devtools/auth-proxy-registry.d.ts +4 -0
- package/dist/runtime/devtools/auth-proxy-registry.js +47 -0
- package/dist/runtime/devtools/bridge-setup.d.ts +21 -0
- package/dist/runtime/devtools/bridge-setup.js +165 -0
- package/dist/runtime/devtools/path-utils.d.ts +2 -0
- package/dist/runtime/devtools/path-utils.js +12 -0
- package/dist/runtime/devtools/server.d.ts +2 -0
- package/dist/runtime/devtools/server.js +108 -0
- package/dist/runtime/devtools/setup-client.d.ts +16 -0
- package/dist/runtime/devtools/setup-client.js +43 -0
- package/dist/runtime/devtools/sink.d.ts +18 -0
- package/dist/runtime/devtools/sink.js +110 -0
- package/dist/runtime/devtools/transport.d.ts +16 -0
- package/dist/runtime/devtools/transport.js +149 -0
- package/dist/runtime/devtools/types.d.ts +167 -0
- package/dist/runtime/devtools/types.js +1 -0
- package/dist/runtime/devtools/ui/dist/200.html +1 -0
- package/dist/runtime/devtools/ui/dist/404.html +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/C4MASuCh.js +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/DJHkqtZq.js +3 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/DWwrCltl.js +2 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/DZ_UiYoH.js +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/_m9ujb-i.js +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/latest.json +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/better-convex-nuxt-devtools.json +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/entry.DpFDKYZ5.css +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/error-404.DYUJo5xt.css +1 -0
- package/dist/runtime/devtools/ui/dist/_nuxt/error-500.DQdoJJXg.css +1 -0
- package/dist/runtime/devtools/ui/dist/convex-logo.svg +5 -0
- package/dist/runtime/devtools/ui/dist/index.html +1 -0
- package/dist/runtime/errors/index.d.ts +7 -0
- package/dist/runtime/errors/index.js +5 -0
- package/dist/runtime/middleware/convex-auth.global.d.ts +2 -0
- package/dist/runtime/middleware/convex-auth.global.js +31 -0
- package/dist/runtime/plugin.auth.client.d.ts +3 -0
- package/dist/runtime/plugin.auth.client.js +217 -0
- package/dist/runtime/plugin.client.d.ts +3 -0
- package/dist/runtime/plugin.client.js +43 -0
- package/dist/runtime/plugin.server.d.ts +12 -0
- package/dist/runtime/plugin.server.js +98 -0
- package/dist/runtime/plugins/convex-call-error-payload.d.ts +14 -0
- package/dist/runtime/plugins/convex-call-error-payload.js +12 -0
- package/dist/runtime/runtime-context.d.ts +26 -0
- package/dist/runtime/runtime-context.js +48 -0
- package/dist/runtime/server/api/auth/[...].d.ts +10 -0
- package/dist/runtime/server/api/auth/[...].js +509 -0
- package/dist/runtime/server/api/auth/authorization-server-metadata.d.ts +2 -0
- package/dist/runtime/server/api/auth/authorization-server-metadata.js +6 -0
- package/dist/runtime/server/api/auth/body-size.d.ts +15 -0
- package/dist/runtime/server/api/auth/body-size.js +179 -0
- package/dist/runtime/server/api/auth/headers.d.ts +6 -0
- package/dist/runtime/server/api/auth/headers.js +98 -0
- package/dist/runtime/server/api/auth/jwks.d.ts +2 -0
- package/dist/runtime/server/api/auth/jwks.js +6 -0
- package/dist/runtime/server/api/auth/security.d.ts +14 -0
- package/dist/runtime/server/api/auth/security.js +85 -0
- package/dist/runtime/server/api/release-fingerprint.d.ts +2 -0
- package/dist/runtime/server/api/release-fingerprint.js +36 -0
- package/dist/runtime/server/index.d.ts +1 -0
- package/dist/runtime/server/index.js +3 -0
- package/dist/runtime/server/plugins/runtime-config.d.ts +7 -0
- package/dist/runtime/server/plugins/runtime-config.js +7 -0
- package/dist/runtime/server/utils/auth-snapshot.d.ts +26 -0
- package/dist/runtime/server/utils/auth-snapshot.js +165 -0
- package/dist/runtime/server/utils/http.d.ts +16 -0
- package/dist/runtime/server/utils/http.js +133 -0
- package/dist/runtime/server/utils/server-convex-caller.d.ts +31 -0
- package/dist/runtime/server/utils/server-convex-caller.js +151 -0
- package/dist/runtime/server/utils/server-convex-options.d.ts +83 -0
- package/dist/runtime/server/utils/server-convex-options.js +69 -0
- package/dist/runtime/server/utils/signed-client-ip.d.ts +6 -0
- package/dist/runtime/server/utils/signed-client-ip.js +29 -0
- package/dist/runtime/server/utils/ssr-auth-headers.d.ts +26 -0
- package/dist/runtime/server/utils/ssr-auth-headers.js +49 -0
- package/dist/runtime/server/utils/token-exchange.d.ts +27 -0
- package/dist/runtime/server/utils/token-exchange.js +96 -0
- package/dist/runtime/shared/auth-cookie.d.ts +4 -0
- package/dist/runtime/shared/auth-cookie.js +25 -0
- package/dist/runtime/shared/auth-origin.d.ts +15 -0
- package/dist/runtime/shared/auth-origin.js +42 -0
- package/dist/runtime/shared/bounded-stream.d.ts +2 -0
- package/dist/runtime/shared/bounded-stream.js +50 -0
- package/dist/runtime/shared/client-ip.d.ts +21 -0
- package/dist/runtime/shared/client-ip.js +123 -0
- package/dist/runtime/shared/release-fingerprint.d.ts +5 -0
- package/dist/runtime/shared/release-fingerprint.js +17 -0
- package/dist/runtime/types.d.ts +19 -0
- package/dist/runtime/utils/auth-config.d.ts +24 -0
- package/dist/runtime/utils/auth-config.js +45 -0
- package/dist/runtime/utils/auth-contract.d.ts +22 -0
- package/dist/runtime/utils/auth-contract.js +0 -0
- package/dist/runtime/utils/auth-errors.d.ts +5 -0
- package/dist/runtime/utils/auth-errors.js +22 -0
- package/dist/runtime/utils/auth-identity-state.d.ts +4 -0
- package/dist/runtime/utils/auth-identity-state.js +8 -0
- package/dist/runtime/utils/auth-pending-state.d.ts +13 -0
- package/dist/runtime/utils/auth-pending-state.js +4 -0
- package/dist/runtime/utils/auth-pending.d.ts +10 -0
- package/dist/runtime/utils/auth-pending.js +30 -0
- package/dist/runtime/utils/auth-route-protection.d.ts +16 -0
- package/dist/runtime/utils/auth-route-protection.js +58 -0
- package/dist/runtime/utils/auth-status.d.ts +47 -0
- package/dist/runtime/utils/auth-status.js +8 -0
- package/dist/runtime/utils/bounded-convex-fetch.d.ts +18 -0
- package/dist/runtime/utils/bounded-convex-fetch.js +152 -0
- package/dist/runtime/utils/callable-devtools.d.ts +17 -0
- package/dist/runtime/utils/callable-devtools.js +49 -0
- package/dist/runtime/utils/callable-observer.d.ts +2 -0
- package/dist/runtime/utils/callable-observer.js +1 -0
- package/dist/runtime/utils/composable-scope.d.ts +2 -0
- package/dist/runtime/utils/composable-scope.js +8 -0
- package/dist/runtime/utils/config-defaults.d.ts +8 -0
- package/dist/runtime/utils/config-defaults.js +8 -0
- package/dist/runtime/utils/convex-cache.d.ts +68 -0
- package/dist/runtime/utils/convex-cache.js +47 -0
- package/dist/runtime/utils/convex-config.d.ts +16 -0
- package/dist/runtime/utils/convex-config.js +50 -0
- package/dist/runtime/utils/convex-shared.d.ts +67 -0
- package/dist/runtime/utils/convex-shared.js +134 -0
- package/dist/runtime/utils/identity-changed-error.d.ts +4 -0
- package/dist/runtime/utils/identity-changed-error.js +12 -0
- package/dist/runtime/utils/identity-key.d.ts +19 -0
- package/dist/runtime/utils/identity-key.js +10 -0
- package/dist/runtime/utils/integrated-auth-client.d.ts +5 -0
- package/dist/runtime/utils/integrated-auth-client.js +0 -0
- package/dist/runtime/utils/logger.d.ts +42 -0
- package/dist/runtime/utils/logger.js +190 -0
- package/dist/runtime/utils/mime-type.d.ts +33 -0
- package/dist/runtime/utils/mime-type.js +10 -0
- package/dist/runtime/utils/query-execution-gate.d.ts +47 -0
- package/dist/runtime/utils/query-execution-gate.js +63 -0
- package/dist/runtime/utils/query-execution.d.ts +8 -0
- package/dist/runtime/utils/query-execution.js +19 -0
- package/dist/runtime/utils/query-foundation.d.ts +20 -0
- package/dist/runtime/utils/query-foundation.js +39 -0
- package/dist/runtime/utils/query-state.d.ts +12 -0
- package/dist/runtime/utils/query-state.js +12 -0
- package/dist/runtime/utils/reactive-args.d.ts +5 -0
- package/dist/runtime/utils/reactive-args.js +42 -0
- package/dist/runtime/utils/runtime-config-normalize.d.ts +22 -0
- package/dist/runtime/utils/runtime-config-normalize.js +28 -0
- package/dist/runtime/utils/runtime-config.d.ts +4 -0
- package/dist/runtime/utils/runtime-config.js +8 -0
- package/dist/runtime/utils/sanitize-diagnostic.d.ts +6 -0
- package/dist/runtime/utils/sanitize-diagnostic.js +81 -0
- package/dist/runtime/utils/shared-helpers.d.ts +46 -0
- package/dist/runtime/utils/shared-helpers.js +139 -0
- package/dist/runtime/utils/site-url.d.ts +4 -0
- package/dist/runtime/utils/site-url.js +15 -0
- package/dist/runtime/utils/ssr-pagination-state.d.ts +3 -0
- package/dist/runtime/utils/ssr-pagination-state.js +3 -0
- package/dist/runtime/utils/types.d.ts +29 -0
- package/dist/runtime/utils/types.js +0 -0
- package/dist/runtime/utils/upload-core.d.ts +16 -0
- package/dist/runtime/utils/upload-core.js +116 -0
- package/dist/types.d.mts +21 -0
- package/package.json +253 -0
- package/security/upstream-convex-better-auth.json +477 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { CONVEX_MODULE_DEFAULTS } from "../../utils/config-defaults.js";
|
|
2
|
+
export const DEFAULT_SERVER_FETCH_TIMEOUT_MS = 8e3;
|
|
3
|
+
export const MAX_SERVER_AUTH_RESPONSE_BODY_BYTES = CONVEX_MODULE_DEFAULTS.authProxy.maxResponseBodyBytes;
|
|
4
|
+
function createTimeoutSignal(timeoutMs, parentSignal) {
|
|
5
|
+
const controller = new AbortController();
|
|
6
|
+
const timeout = setTimeout(() => {
|
|
7
|
+
controller.abort(new Error(`Request timed out after ${timeoutMs}ms`));
|
|
8
|
+
}, timeoutMs);
|
|
9
|
+
const abortFromParent = () => controller.abort(parentSignal?.reason);
|
|
10
|
+
if (parentSignal) {
|
|
11
|
+
if (parentSignal.aborted) {
|
|
12
|
+
abortFromParent();
|
|
13
|
+
} else {
|
|
14
|
+
parentSignal.addEventListener("abort", abortFromParent, { once: true });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
signal: controller.signal,
|
|
19
|
+
cleanup: () => {
|
|
20
|
+
clearTimeout(timeout);
|
|
21
|
+
if (parentSignal) {
|
|
22
|
+
parentSignal.removeEventListener("abort", abortFromParent);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export async function fetchWithTimeout(input, options = {}) {
|
|
28
|
+
const {
|
|
29
|
+
timeoutMs = DEFAULT_SERVER_FETCH_TIMEOUT_MS,
|
|
30
|
+
fetchImpl = fetch,
|
|
31
|
+
signal: parentSignal,
|
|
32
|
+
...init
|
|
33
|
+
} = options;
|
|
34
|
+
const { signal, cleanup } = createTimeoutSignal(timeoutMs, parentSignal ?? void 0);
|
|
35
|
+
try {
|
|
36
|
+
const response = await fetchImpl(input, {
|
|
37
|
+
...init,
|
|
38
|
+
signal
|
|
39
|
+
});
|
|
40
|
+
if (!response.body) {
|
|
41
|
+
cleanup();
|
|
42
|
+
return response;
|
|
43
|
+
}
|
|
44
|
+
const reader = response.body.getReader();
|
|
45
|
+
let bodyController;
|
|
46
|
+
let settled = false;
|
|
47
|
+
const finish = () => {
|
|
48
|
+
if (settled) return false;
|
|
49
|
+
settled = true;
|
|
50
|
+
signal.removeEventListener("abort", abortBody);
|
|
51
|
+
cleanup();
|
|
52
|
+
reader.releaseLock();
|
|
53
|
+
return true;
|
|
54
|
+
};
|
|
55
|
+
const cancelBody = (reason) => {
|
|
56
|
+
if (settled) return;
|
|
57
|
+
try {
|
|
58
|
+
void reader.cancel(reason).catch(() => {
|
|
59
|
+
});
|
|
60
|
+
} finally {
|
|
61
|
+
finish();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const abortBody = () => {
|
|
65
|
+
if (settled) return;
|
|
66
|
+
const reason = signal.reason ?? new Error("Request was aborted");
|
|
67
|
+
cancelBody(reason);
|
|
68
|
+
bodyController?.error(reason);
|
|
69
|
+
};
|
|
70
|
+
const body = new ReadableStream({
|
|
71
|
+
start(controller) {
|
|
72
|
+
bodyController = controller;
|
|
73
|
+
signal.addEventListener("abort", abortBody, { once: true });
|
|
74
|
+
if (signal.aborted) abortBody();
|
|
75
|
+
},
|
|
76
|
+
async pull(controller) {
|
|
77
|
+
if (settled) return;
|
|
78
|
+
try {
|
|
79
|
+
const next = await reader.read();
|
|
80
|
+
if (settled) return;
|
|
81
|
+
if (next.done) {
|
|
82
|
+
finish();
|
|
83
|
+
controller.close();
|
|
84
|
+
} else {
|
|
85
|
+
controller.enqueue(next.value);
|
|
86
|
+
}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (finish()) controller.error(error);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
cancel(reason) {
|
|
92
|
+
cancelBody(reason);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return new Response(body, {
|
|
96
|
+
status: response.status,
|
|
97
|
+
statusText: response.statusText,
|
|
98
|
+
headers: response.headers
|
|
99
|
+
});
|
|
100
|
+
} catch (error) {
|
|
101
|
+
cleanup();
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export async function readBoundedJson(response, maxBytes) {
|
|
106
|
+
const body = response.body;
|
|
107
|
+
if (!body) throw new SyntaxError("Response body is empty");
|
|
108
|
+
const reader = body.getReader();
|
|
109
|
+
const chunks = [];
|
|
110
|
+
let total = 0;
|
|
111
|
+
try {
|
|
112
|
+
for (; ; ) {
|
|
113
|
+
const { done, value } = await reader.read();
|
|
114
|
+
if (done) break;
|
|
115
|
+
if (!value) continue;
|
|
116
|
+
total += value.byteLength;
|
|
117
|
+
if (total > maxBytes) {
|
|
118
|
+
await reader.cancel("Response body exceeded the size limit");
|
|
119
|
+
throw new Error("Response body exceeded the size limit");
|
|
120
|
+
}
|
|
121
|
+
chunks.push(value);
|
|
122
|
+
}
|
|
123
|
+
} finally {
|
|
124
|
+
reader.releaseLock();
|
|
125
|
+
}
|
|
126
|
+
const merged = new Uint8Array(total);
|
|
127
|
+
let offset = 0;
|
|
128
|
+
for (const chunk of chunks) {
|
|
129
|
+
merged.set(chunk, offset);
|
|
130
|
+
offset += chunk.byteLength;
|
|
131
|
+
}
|
|
132
|
+
return JSON.parse(new TextDecoder().decode(merged));
|
|
133
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { FunctionReference, FunctionReturnType, OptionalRestArgs } from 'convex/server';
|
|
2
|
+
import type { H3Event } from 'h3';
|
|
3
|
+
import { type ServerConvexOptions } from './server-convex-options.js';
|
|
4
|
+
export type { ServerConvexOptions };
|
|
5
|
+
/**
|
|
6
|
+
* One request-scoped server caller ("Caller-owned token promise").
|
|
7
|
+
*
|
|
8
|
+
* A caller owns exactly one lazy authentication token promise and one lazy
|
|
9
|
+
* `ConvexHttpClient`; `setAuth` runs at most once, when a token exists. The
|
|
10
|
+
* operation methods use Convex's native optional-rest-args contract, so exact
|
|
11
|
+
* no-argument references omit the artificial `{}` argument while references
|
|
12
|
+
* with declared arguments remain required and inferred.
|
|
13
|
+
*/
|
|
14
|
+
export interface ServerConvexCaller {
|
|
15
|
+
getToken(): Promise<string | null>;
|
|
16
|
+
query<Query extends FunctionReference<'query'>>(query: Query, ...args: OptionalRestArgs<Query>): Promise<FunctionReturnType<Query>>;
|
|
17
|
+
mutation<Mutation extends FunctionReference<'mutation'>>(mutation: Mutation, ...args: OptionalRestArgs<Mutation>): Promise<FunctionReturnType<Mutation>>;
|
|
18
|
+
action<Action extends FunctionReference<'action'>>(action: Action, ...args: OptionalRestArgs<Action>): Promise<FunctionReturnType<Action>>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Construct a request-scoped Convex server caller .
|
|
22
|
+
*
|
|
23
|
+
* The caller lazily resolves one authentication token and one
|
|
24
|
+
* `ConvexHttpClient` (built with `logger: false` so arbitrary Convex function
|
|
25
|
+
* log lines are not re-emitted, and the shared bounded fetch so abort, deadline,
|
|
26
|
+
* response-size, and transport classification remain request-scoped). A
|
|
27
|
+
* rejected token or client promise stays rejected for this caller; retrying
|
|
28
|
+
* requires a new caller. Neither promise is stored on the event nor keyed by
|
|
29
|
+
* option hash.
|
|
30
|
+
*/
|
|
31
|
+
export declare function serverConvex(event: H3Event, options?: ServerConvexOptions): ServerConvexCaller;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { ConvexHttpClient } from "convex/browser";
|
|
2
|
+
import { ConvexCallError, normalizeConvexError } from "../../errors/index.js";
|
|
3
|
+
import { createBoundedConvexFetch } from "../../utils/bounded-convex-fetch.js";
|
|
4
|
+
import { normalizeConvexRuntimeConfig } from "../../utils/runtime-config-normalize.js";
|
|
5
|
+
import { filterBetterAuthCookies, getBetterAuthSessionToken } from "../../utils/shared-helpers.js";
|
|
6
|
+
import {
|
|
7
|
+
validateServerConvexOptions
|
|
8
|
+
} from "./server-convex-options.js";
|
|
9
|
+
import { exchangeConvexToken } from "./token-exchange.js";
|
|
10
|
+
function readCallerConfig(event) {
|
|
11
|
+
const context = event.context;
|
|
12
|
+
const runtimeConfig = context.nitro?.runtimeConfig;
|
|
13
|
+
return normalizeConvexRuntimeConfig(runtimeConfig?.public?.convex);
|
|
14
|
+
}
|
|
15
|
+
function readRequiredConvexUrl(event) {
|
|
16
|
+
const url = readCallerConfig(event).url;
|
|
17
|
+
if (!url) {
|
|
18
|
+
throw new ConvexCallError({
|
|
19
|
+
kind: "unknown",
|
|
20
|
+
message: "Convex URL is not configured for serverConvex"
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return url;
|
|
24
|
+
}
|
|
25
|
+
function readCookieHeader(event) {
|
|
26
|
+
const directHeader = event.headers;
|
|
27
|
+
if (directHeader?.get) {
|
|
28
|
+
return directHeader.get("cookie");
|
|
29
|
+
}
|
|
30
|
+
const nodeHeaders = event.node?.req?.headers;
|
|
31
|
+
const raw = nodeHeaders?.cookie;
|
|
32
|
+
if (Array.isArray(raw)) return raw.join("; ");
|
|
33
|
+
return typeof raw === "string" ? raw : null;
|
|
34
|
+
}
|
|
35
|
+
function authenticationRequiredError(status = 401) {
|
|
36
|
+
return new ConvexCallError({
|
|
37
|
+
kind: "authentication",
|
|
38
|
+
message: "Convex authentication is required for this server call",
|
|
39
|
+
status
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function throwExchangeFailure(result) {
|
|
43
|
+
throw result.error ?? new ConvexCallError({
|
|
44
|
+
kind: "transport",
|
|
45
|
+
message: "Convex token exchange could not complete"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function resolveServerToken(event, normalized) {
|
|
49
|
+
if (normalized.authToken) {
|
|
50
|
+
return normalized.authToken;
|
|
51
|
+
}
|
|
52
|
+
const config = readCallerConfig(event);
|
|
53
|
+
const required = normalized.auth === "required";
|
|
54
|
+
if (config.auth === false) {
|
|
55
|
+
if (normalized.credential || required) throw authenticationRequiredError();
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
if (normalized.credential) {
|
|
59
|
+
if (!config.siteUrl) throw authenticationRequiredError();
|
|
60
|
+
const result2 = await exchangeConvexToken({
|
|
61
|
+
event,
|
|
62
|
+
siteUrl: config.siteUrl,
|
|
63
|
+
credential: normalized.credential,
|
|
64
|
+
trustedClientIpHeader: config.auth.trustedClientIpHeader
|
|
65
|
+
});
|
|
66
|
+
if (result2.token) return result2.token;
|
|
67
|
+
throwExchangeFailure(result2);
|
|
68
|
+
}
|
|
69
|
+
if (normalized.auth === "none") return null;
|
|
70
|
+
const cookieHeader = readCookieHeader(event);
|
|
71
|
+
const sessionToken = getBetterAuthSessionToken(cookieHeader);
|
|
72
|
+
const authCookieHeader = filterBetterAuthCookies(cookieHeader);
|
|
73
|
+
if (!authCookieHeader || !sessionToken) {
|
|
74
|
+
if (required) throw authenticationRequiredError();
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
if (!config.siteUrl) {
|
|
78
|
+
if (required) throw authenticationRequiredError();
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const result = await exchangeConvexToken({
|
|
82
|
+
event,
|
|
83
|
+
siteUrl: config.siteUrl,
|
|
84
|
+
credential: { type: "cookie", value: authCookieHeader },
|
|
85
|
+
trustedClientIpHeader: config.auth.trustedClientIpHeader
|
|
86
|
+
});
|
|
87
|
+
if (result.token) return result.token;
|
|
88
|
+
if (result.status === 401 || result.status === 403) {
|
|
89
|
+
if (required) throw authenticationRequiredError(result.status);
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
throwExchangeFailure(result);
|
|
93
|
+
}
|
|
94
|
+
export function serverConvex(event, options = {}) {
|
|
95
|
+
const normalized = validateServerConvexOptions(options);
|
|
96
|
+
const boundedFetch = createBoundedConvexFetch({
|
|
97
|
+
signal: event.web?.request?.signal
|
|
98
|
+
});
|
|
99
|
+
let tokenPromise = null;
|
|
100
|
+
let clientPromise = null;
|
|
101
|
+
const getToken = () => {
|
|
102
|
+
tokenPromise ??= resolveServerToken(event, normalized);
|
|
103
|
+
return tokenPromise;
|
|
104
|
+
};
|
|
105
|
+
const getClient = () => {
|
|
106
|
+
clientPromise ??= (async () => {
|
|
107
|
+
const client = new ConvexHttpClient(readRequiredConvexUrl(event), {
|
|
108
|
+
fetch: boundedFetch,
|
|
109
|
+
logger: false
|
|
110
|
+
});
|
|
111
|
+
const token = await getToken();
|
|
112
|
+
if (token) client.setAuth(token);
|
|
113
|
+
return client;
|
|
114
|
+
})();
|
|
115
|
+
return clientPromise;
|
|
116
|
+
};
|
|
117
|
+
const prepareClient = async () => {
|
|
118
|
+
const token = await getToken();
|
|
119
|
+
if (normalized.auth === "required" && !token) {
|
|
120
|
+
throw authenticationRequiredError();
|
|
121
|
+
}
|
|
122
|
+
return getClient();
|
|
123
|
+
};
|
|
124
|
+
return {
|
|
125
|
+
getToken,
|
|
126
|
+
async query(query, ...args) {
|
|
127
|
+
const client = await prepareClient();
|
|
128
|
+
try {
|
|
129
|
+
return await client.query(query, ...args);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
throw normalizeConvexError(error);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
async mutation(mutation, ...args) {
|
|
135
|
+
const client = await prepareClient();
|
|
136
|
+
try {
|
|
137
|
+
return await client.mutation(mutation, ...args);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
throw normalizeConvexError(error);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
async action(action, ...args) {
|
|
143
|
+
const client = await prepareClient();
|
|
144
|
+
try {
|
|
145
|
+
return await client.action(action, ...args);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
throw normalizeConvexError(error);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { ConvexAuthMode } from '../../utils/auth-status.js';
|
|
2
|
+
/**
|
|
3
|
+
* A low-level Better Auth cookie credential handed to `serverConvex` for an
|
|
4
|
+
* explicit principal. The value is a raw `Cookie` header string.
|
|
5
|
+
*/
|
|
6
|
+
export type ConvexCredential = {
|
|
7
|
+
type: 'cookie';
|
|
8
|
+
value: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Public per-caller options for `serverConvex`.
|
|
12
|
+
*
|
|
13
|
+
* Cookie policy, an explicit Convex token, and an explicit Better Auth cookie
|
|
14
|
+
* credential are three mutually exclusive call modes. An explicit principal
|
|
15
|
+
* always requires authentication, so those branches deliberately do not accept
|
|
16
|
+
* a redundant `auth: 'required'` field.
|
|
17
|
+
*/
|
|
18
|
+
export type ServerConvexOptions = {
|
|
19
|
+
auth?: ConvexAuthMode;
|
|
20
|
+
authToken?: never;
|
|
21
|
+
credential?: never;
|
|
22
|
+
} | {
|
|
23
|
+
auth?: never;
|
|
24
|
+
authToken: string;
|
|
25
|
+
credential?: never;
|
|
26
|
+
} | {
|
|
27
|
+
auth?: never;
|
|
28
|
+
authToken?: never;
|
|
29
|
+
credential: ConvexCredential;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* The validated, resolved options a caller operates on. `auth` is always a
|
|
33
|
+
* concrete mode: cookie-based callers default to a fixed `optional`, while an
|
|
34
|
+
* explicit principal resolves to `required`.
|
|
35
|
+
*/
|
|
36
|
+
export type NormalizedServerConvexOptions = {
|
|
37
|
+
auth: ConvexAuthMode;
|
|
38
|
+
authToken?: never;
|
|
39
|
+
credential?: never;
|
|
40
|
+
} | {
|
|
41
|
+
auth: 'required';
|
|
42
|
+
authToken: string;
|
|
43
|
+
credential?: never;
|
|
44
|
+
} | {
|
|
45
|
+
auth: 'required';
|
|
46
|
+
authToken?: never;
|
|
47
|
+
credential: ConvexCredential;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Synchronous validation failure for server-call options and credential values
|
|
51
|
+
* . This is deliberately NOT a {@link ConvexCallError}: the public
|
|
52
|
+
* error contract has no `validation` kind, and an option/credential
|
|
53
|
+
* contract violation is a caller programming error surfaced before any network
|
|
54
|
+
* access — not a classifiable Convex call outcome. Callers that construct a
|
|
55
|
+
* `serverConvex` caller receive this synchronously, before a request is ever
|
|
56
|
+
* made.
|
|
57
|
+
*/
|
|
58
|
+
export declare class ServerConvexValidationError extends Error {
|
|
59
|
+
constructor(message: string);
|
|
60
|
+
}
|
|
61
|
+
export declare function credentialHasControlChars(value: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Reject an empty or control-character-bearing credential value synchronously,
|
|
64
|
+
* before any network access . Shared by option validation and by the
|
|
65
|
+
* exchange primitive so both refuse a smuggling-capable credential at the door.
|
|
66
|
+
*/
|
|
67
|
+
export declare function assertCredentialValueSafe(value: unknown, label: string): asserts value is string;
|
|
68
|
+
export declare function assertConvexCredentialShape(credential: unknown): asserts credential is ConvexCredential;
|
|
69
|
+
/**
|
|
70
|
+
* Validate and normalize {@link ServerConvexOptions} synchronously (public
|
|
71
|
+
* "Validation rules"). Throws {@link ServerConvexValidationError} — before any
|
|
72
|
+
* network access — for every invalid combination rather than silently
|
|
73
|
+
* downgrading a rejected explicit principal.
|
|
74
|
+
*
|
|
75
|
+
* Rules:
|
|
76
|
+
* - `authToken` and `credential` are mutually exclusive.
|
|
77
|
+
* - Providing either implies `required`; every explicit `auth` field is
|
|
78
|
+
* rejected as redundant or contradictory.
|
|
79
|
+
* - An empty or control-character token/credential value is rejected.
|
|
80
|
+
* - With no explicit principal, cookie-based resolution defaults to a fixed
|
|
81
|
+
* `optional`.
|
|
82
|
+
*/
|
|
83
|
+
export declare function validateServerConvexOptions(options?: ServerConvexOptions): NormalizedServerConvexOptions;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export class ServerConvexValidationError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "ServerConvexValidationError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
const ASCII_CONTROL_MAX = 31;
|
|
8
|
+
const ASCII_DEL = 127;
|
|
9
|
+
export function credentialHasControlChars(value) {
|
|
10
|
+
for (let index = 0; index < value.length; index++) {
|
|
11
|
+
const code = value.charCodeAt(index);
|
|
12
|
+
if (code <= ASCII_CONTROL_MAX || code === ASCII_DEL) return true;
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
export function assertCredentialValueSafe(value, label) {
|
|
17
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
18
|
+
throw new ServerConvexValidationError(`${label} must be a non-empty string`);
|
|
19
|
+
}
|
|
20
|
+
if (credentialHasControlChars(value)) {
|
|
21
|
+
throw new ServerConvexValidationError(`${label} must not contain control characters`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function assertConvexCredentialShape(credential) {
|
|
25
|
+
if (!credential || typeof credential !== "object") {
|
|
26
|
+
throw new ServerConvexValidationError("credential must be a cookie credential");
|
|
27
|
+
}
|
|
28
|
+
const type = credential.type;
|
|
29
|
+
if (type !== "cookie") {
|
|
30
|
+
throw new ServerConvexValidationError("credential must be a cookie credential");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function assertConvexAuthMode(auth) {
|
|
34
|
+
if (auth !== void 0 && auth !== "required" && auth !== "optional" && auth !== "none") {
|
|
35
|
+
throw new ServerConvexValidationError("auth must be one of 'required', 'optional', or 'none'");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function validateServerConvexOptions(options = {}) {
|
|
39
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
40
|
+
throw new ServerConvexValidationError("serverConvex options must be an object");
|
|
41
|
+
}
|
|
42
|
+
const { auth, authToken, credential } = options;
|
|
43
|
+
const hasToken = authToken !== void 0;
|
|
44
|
+
const hasCredential = credential !== void 0;
|
|
45
|
+
assertConvexAuthMode(auth);
|
|
46
|
+
if (hasToken && hasCredential) {
|
|
47
|
+
throw new ServerConvexValidationError(
|
|
48
|
+
"authToken and credential are mutually exclusive; provide at most one"
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (hasToken) {
|
|
52
|
+
assertCredentialValueSafe(authToken, "authToken");
|
|
53
|
+
}
|
|
54
|
+
if (hasCredential) {
|
|
55
|
+
assertConvexCredentialShape(credential);
|
|
56
|
+
assertCredentialValueSafe(credential.value, "credential value");
|
|
57
|
+
}
|
|
58
|
+
const hasExplicitPrincipal = hasToken || hasCredential;
|
|
59
|
+
if (hasExplicitPrincipal) {
|
|
60
|
+
if (auth !== void 0) {
|
|
61
|
+
throw new ServerConvexValidationError(
|
|
62
|
+
"auth must be omitted when authToken or credential is provided; an explicit principal already requires authentication"
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (hasToken) return { auth: "required", authToken };
|
|
66
|
+
if (hasCredential) return { auth: "required", credential };
|
|
67
|
+
}
|
|
68
|
+
return { auth: auth ?? "optional" };
|
|
69
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { H3Event } from 'h3';
|
|
2
|
+
export interface SignedClientIpHeadersOptions {
|
|
3
|
+
trustedClientIpHeader?: string | null;
|
|
4
|
+
}
|
|
5
|
+
/** Build the complete authenticated client-IP pair for one Nuxt-to-Convex hop. */
|
|
6
|
+
export declare function buildSignedClientIpHeaders(event: H3Event, options: SignedClientIpHeadersOptions): Promise<Record<string, string>>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLIENT_IP_HEADER,
|
|
3
|
+
CLIENT_IP_SIGNATURE_HEADER,
|
|
4
|
+
normalizeClientIp,
|
|
5
|
+
requireProxyIpSecret,
|
|
6
|
+
signClientIp
|
|
7
|
+
} from "../../shared/client-ip.js";
|
|
8
|
+
function readRequestHeader(event, name) {
|
|
9
|
+
const directHeaders = event.headers;
|
|
10
|
+
const direct = directHeaders?.get?.(name);
|
|
11
|
+
if (direct !== null && direct !== void 0) return direct;
|
|
12
|
+
const nodeHeaders = event.node?.req?.headers;
|
|
13
|
+
const value = nodeHeaders?.[name.toLowerCase()];
|
|
14
|
+
if (Array.isArray(value)) return value.join(",");
|
|
15
|
+
return typeof value === "string" ? value : null;
|
|
16
|
+
}
|
|
17
|
+
export async function buildSignedClientIpHeaders(event, options) {
|
|
18
|
+
const trustedHeader = options.trustedClientIpHeader;
|
|
19
|
+
if (!trustedHeader) return {};
|
|
20
|
+
const clientIp = normalizeClientIp(readRequestHeader(event, trustedHeader));
|
|
21
|
+
if (!clientIp) {
|
|
22
|
+
throw new TypeError("Trusted client IP header must contain exactly one valid IP address");
|
|
23
|
+
}
|
|
24
|
+
const secret = requireProxyIpSecret(process.env.BCN_AUTH_PROXY_IP_SECRET);
|
|
25
|
+
return {
|
|
26
|
+
[CLIENT_IP_HEADER]: clientIp,
|
|
27
|
+
[CLIENT_IP_SIGNATURE_HEADER]: await signClientIp(clientIp, secret)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type H3Event } from 'h3';
|
|
2
|
+
/**
|
|
3
|
+
* Merge `Cookie` into an existing `Vary` header value without dropping any
|
|
4
|
+
* caller-set field ("Vary/Cache-Control"). Existing tokens are
|
|
5
|
+
* preserved, whitespace is normalized, and `Cookie` is added exactly once
|
|
6
|
+
* (case-insensitively) so an auth-enabled SSR response always varies by cookie
|
|
7
|
+
* while a pre-existing `Vary: Accept-Encoding` survives. `Vary: *` already
|
|
8
|
+
* varies on every request property and must remain the sole field value.
|
|
9
|
+
*/
|
|
10
|
+
export declare function mergeVaryCookie(existing: string | number | string[] | undefined | null): string;
|
|
11
|
+
/**
|
|
12
|
+
* Apply the SSR auth cache policy to the current response :
|
|
13
|
+
*
|
|
14
|
+
* - Every auth-enabled SSR response appends `Vary: Cookie`, preserving existing
|
|
15
|
+
* `Vary` values so a shared cache keys per cookie.
|
|
16
|
+
* - A request carrying a recognized Better Auth cookie, or any response that
|
|
17
|
+
* serializes a token, additionally gets `Cache-Control: private, no-store`.
|
|
18
|
+
* Invalid/revoked sessions remain request-specific even when no token is
|
|
19
|
+
* produced, and a per-user JWT is never cacheable without a cookie signal.
|
|
20
|
+
* Shared-cache override headers already present on the response are removed;
|
|
21
|
+
* an operator/CDN rule that rewrites headers after this point remains external.
|
|
22
|
+
*/
|
|
23
|
+
export declare function applyConvexAuthSsrHeaders(event: H3Event, options: {
|
|
24
|
+
hasBetterAuthCookie: boolean;
|
|
25
|
+
serializesToken: boolean;
|
|
26
|
+
}): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getResponseHeader,
|
|
3
|
+
getResponseHeaders,
|
|
4
|
+
removeResponseHeader,
|
|
5
|
+
setResponseHeader
|
|
6
|
+
} from "h3";
|
|
7
|
+
const SHARED_CACHE_CONTROL_HEADERS = /* @__PURE__ */ new Set([
|
|
8
|
+
"cdn-cache-control",
|
|
9
|
+
"edge-control",
|
|
10
|
+
"surrogate-control",
|
|
11
|
+
"x-accel-expires"
|
|
12
|
+
]);
|
|
13
|
+
function removeSharedCacheOverrides(event) {
|
|
14
|
+
for (const name of Object.keys(getResponseHeaders(event))) {
|
|
15
|
+
const lower = name.toLowerCase();
|
|
16
|
+
if (SHARED_CACHE_CONTROL_HEADERS.has(lower) || lower.endsWith("-cdn-cache-control")) {
|
|
17
|
+
removeResponseHeader(event, name);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function mergeVaryCookie(existing) {
|
|
22
|
+
const values = [];
|
|
23
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24
|
+
const push = (raw) => {
|
|
25
|
+
for (const part of raw.split(",")) {
|
|
26
|
+
const token = part.trim();
|
|
27
|
+
if (!token) continue;
|
|
28
|
+
const key = token.toLowerCase();
|
|
29
|
+
if (seen.has(key)) continue;
|
|
30
|
+
seen.add(key);
|
|
31
|
+
values.push(token);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
if (Array.isArray(existing)) {
|
|
35
|
+
for (const entry of existing) push(String(entry));
|
|
36
|
+
} else if (existing !== void 0 && existing !== null) {
|
|
37
|
+
push(String(existing));
|
|
38
|
+
}
|
|
39
|
+
if (seen.has("*")) return "*";
|
|
40
|
+
if (!seen.has("cookie")) values.push("Cookie");
|
|
41
|
+
return values.join(", ");
|
|
42
|
+
}
|
|
43
|
+
export function applyConvexAuthSsrHeaders(event, options) {
|
|
44
|
+
setResponseHeader(event, "Vary", mergeVaryCookie(getResponseHeader(event, "Vary")));
|
|
45
|
+
if (options.hasBetterAuthCookie || options.serializesToken) {
|
|
46
|
+
removeSharedCacheOverrides(event);
|
|
47
|
+
setResponseHeader(event, "Cache-Control", "private, no-store");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { H3Event } from 'h3';
|
|
2
|
+
import { ConvexCallError } from '../../errors/index.js';
|
|
3
|
+
import type { ConvexCredential } from './server-convex-options.js';
|
|
4
|
+
/**
|
|
5
|
+
* The never-throwing result of a cookie -> Convex JWT exchange
|
|
6
|
+
* (architecture invariant).
|
|
7
|
+
*
|
|
8
|
+
* Success returns a non-null `token`, a 2xx `status`, and `error: null`.
|
|
9
|
+
* A network/HTTP failure returns `token: null`, exactly one `error`, and the
|
|
10
|
+
* upstream `status` when one exists. This is intentionally NOT an
|
|
11
|
+
* `ok`-discriminated union; the invariants above are pinned by tests.
|
|
12
|
+
*/
|
|
13
|
+
export interface ConvexTokenExchangeResult {
|
|
14
|
+
token: string | null;
|
|
15
|
+
status: number | undefined;
|
|
16
|
+
error: ConvexCallError | null;
|
|
17
|
+
}
|
|
18
|
+
interface RequestBoundTokenExchangeInput {
|
|
19
|
+
event: H3Event;
|
|
20
|
+
siteUrl: string;
|
|
21
|
+
credential: ConvexCredential;
|
|
22
|
+
trustedClientIpHeader: string;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
}
|
|
25
|
+
/** Request-aware exchange used by every shipped Nitro auth path. */
|
|
26
|
+
export declare function exchangeConvexToken(input: RequestBoundTokenExchangeInput): Promise<ConvexTokenExchangeResult>;
|
|
27
|
+
export {};
|