diff --git a/.changeset/rich-planes-drive.md b/.changeset/rich-planes-drive.md new file mode 100644 index 00000000000..07bf509c097 --- /dev/null +++ b/.changeset/rich-planes-drive.md @@ -0,0 +1,5 @@ +--- +"@thirdweb-dev/service-utils": patch +--- + +[service-utils] Provide CF req to forward origin header diff --git a/packages/service-utils/src/cf-worker/usageV2.ts b/packages/service-utils/src/cf-worker/usageV2.ts index aaee2a3ecc2..84c525bafbe 100644 --- a/packages/service-utils/src/cf-worker/usageV2.ts +++ b/packages/service-utils/src/cf-worker/usageV2.ts @@ -1,28 +1,22 @@ +import type { Request } from "@cloudflare/workers-types"; +import type { CoreAuthInput } from "src/core/types.js"; import type { ClientUsageV2Event, UsageV2Event, UsageV2Source, } from "../core/usageV2.js"; +import { extractAuthorizationData } from "./index.js"; type UsageV2Options = { usageBaseUrl: string; source: UsageV2Source; -} & ( - | { serviceKey: string; thirdwebClientId?: never; thirdwebSecretKey?: never } - | { serviceKey?: never; thirdwebClientId: string; thirdwebSecretKey?: never } - | { serviceKey?: never; thirdwebClientId?: never; thirdwebSecretKey: string } -); + authInput: CoreAuthInput & { req: Request }; + serviceKey?: string; +}; /** * Send usageV2 events from either internal services or public clients. * - * Exactly one authentication method must be provided: - * - serviceKey: for internal services - * - thirdwebClientId: for public clients (MUST be the user's project) - * - thirdwebSecretKey: for public clients (MUST be the user's project) - * - * NOTE: `team_id` is required if `serviceKey` is provided. - * * This method may throw. To call this non-blocking: * ```ts * void sendUsageV2Events(...).catch((e) => console.error(e)) @@ -34,19 +28,26 @@ export async function sendUsageV2Events( : ClientUsageV2Event[], options: T, ): Promise { + const { usageBaseUrl, source, authInput, serviceKey } = options; + const { clientId, secretKey } = await extractAuthorizationData(authInput); + // Determine endpoint and auth header based on provided credentials. let url: string; const headers: HeadersInit = { "Content-Type": "application/json" }; + const origin = authInput.req.headers.get("Origin"); + if (origin) { + headers["Origin"] = origin; + } - if (options.serviceKey) { - url = `${options.usageBaseUrl}/usage-v2/${options.source}`; - headers["x-service-api-key"] = options.serviceKey; - } else if (options.thirdwebSecretKey) { - url = `${options.usageBaseUrl}/usage-v2/${options.source}/client`; - headers["x-secret-key"] = options.thirdwebSecretKey; - } else if (options.thirdwebClientId) { - url = `${options.usageBaseUrl}/usage-v2/${options.source}/client`; - headers["x-client-id"] = options.thirdwebClientId; + if (serviceKey) { + url = `${usageBaseUrl}/usage-v2/${source}`; + headers["x-service-api-key"] = serviceKey; + } else if (secretKey) { + url = `${usageBaseUrl}/usage-v2/${source}/client`; + headers["x-secret-key"] = secretKey; + } else if (clientId) { + url = `${usageBaseUrl}/usage-v2/${source}/client`; + headers["x-client-id"] = clientId; } else { throw new Error("[UsageV2] No authentication method provided."); } @@ -56,7 +57,6 @@ export async function sendUsageV2Events( headers, body: JSON.stringify({ events }), }); - if (!resp.ok) { throw new Error( `[UsageV2] Unexpected response ${resp.status}: ${await resp.text()}`,