diff --git a/src/app/browser-session-machine.ts b/src/app/browser-session-machine.ts index 235c9601..aa55c62a 100644 --- a/src/app/browser-session-machine.ts +++ b/src/app/browser-session-machine.ts @@ -185,8 +185,13 @@ export const browserSessionMachine = setup({ Connections: { on: { CONNECT: { + guard: ({ event }) => { + console.log("RI", event.requestInfo); + return !!event.requestInfo; + }, actions: assign(({ context, event }) => { return produce(context, (draft) => { + console.log(event); if (event.requestInfo?.continent) { draft.continent = event.requestInfo?.continent; } @@ -258,6 +263,7 @@ export const browserSessionMachine = setup({ invoke: { src: "generateIngredientSuggestions", input: ({ context }) => { + console.log("RUNNING!"); assert(context.timezone, "expected timezone"); const personalizationContext = getPersonalizationContext(context); diff --git a/src/lib/actor-kit/index.ts b/src/lib/actor-kit/index.ts index 0e7ba86c..77d41cc9 100644 --- a/src/lib/actor-kit/index.ts +++ b/src/lib/actor-kit/index.ts @@ -148,6 +148,7 @@ export const createMachineServer = < } async onRequest(request: Party.Request) { + console.log(request.cf); const connectionId = randomUUID(); const authHeader = request.headers.get("Authorization"); const callerIdToken = authHeader?.split(" ")[1]; @@ -317,9 +318,15 @@ export const createMachineServer = < if (context.request.cf) { const result = RequestInfoSchema.safeParse(context.request.cf); if (result.success) { + // console.log({ requestInfo }); requestInfo = result.data; + } else { + // Error parsing cloudflare + // Shouldnt happen frequently + console.error(result.error); } } + // console.log(context.request.cf, requestInfo); // @ts-expect-error actor.send({ type: "CONNECT", diff --git a/src/middleware.ts b/src/middleware.ts index 4d297bec..c12aa2a2 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,4 +1,5 @@ import { NextRequest, NextResponse } from "next/server"; +import { z } from "zod"; import { createBrowserSessionToken, createCallerToken, @@ -13,6 +14,11 @@ import { CallerSchema } from "./schema"; export async function middleware(request: NextRequest) { const appInstallToken = request.nextUrl.searchParams.get("token"); + const result = extractAndValidateHeaders(request.headers); + console.log(result); + + // const headers = extractAndValidateHeaders(request.headers); + // console.log(headers); let newGuestToken: string | undefined; let newBrowserSessionToken: string | undefined; @@ -95,3 +101,60 @@ function uuidv4() { return v.toString(16); }); } +// Define a schema for IP location data +const IPLocationSchema = z.object({ + latitude: z.number().optional(), + longitude: z.number().optional(), +}); + +// Define a schema for the headers we want to extract and validate +const HeadersSchema = z.object({ + continent: z.enum(["AF", "AN", "AS", "EU", "NA", "OC", "SA"]).optional(), + country: z.string().length(2).optional(), + region: z.string().max(3).optional(), + city: z.string().optional(), + timezone: z.string().optional(), + signature: z.string().optional(), + gps: IPLocationSchema.optional(), +}); + +// Type definition for the headers context +type HeadersContext = { + continent?: string; + country?: string; + region?: string; + city?: string; + timezone?: string; + signature?: string; + gps?: { + latitude: number; + longitude: number; + }; +}; + +// Function to extract and validate headers from a request with a .get() method +function extractAndValidateHeaders(headers: NextRequest["headers"]) { + // Extract headers and convert them into a structured object + const headersToValidate: HeadersContext = { + continent: headers.get("x-vercel-ip-continent") || undefined, + country: headers.get("x-vercel-ip-country") || undefined, + region: headers.get("x-vercel-ip-country-region") || undefined, + city: headers.get("x-vercel-ip-city") || undefined, + timezone: headers.get("x-vercel-ip-timezone") || undefined, + signature: headers.get("x-vercel-signature") || undefined, + gps: { + latitude: parseFloat(headers.get("x-vercel-ip-latitude") || "0"), + longitude: parseFloat(headers.get("x-vercel-ip-longitude") || "0"), + }, + }; + + // Validate the structured object using the Zod schema + const result = HeadersSchema.safeParse(headersToValidate); + + if (result.success) { + return result.data; + } else { + console.error("Validation failed:", result.error); + return undefined; + } +}