-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiddleware.ts
101 lines (85 loc) · 3.04 KB
/
middleware.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { redirect } from "@solidjs/router";
import { createMiddleware } from "@solidjs/start/middleware";
import { type FetchEvent } from "@solidjs/start/server";
import { type Toucan } from "toucan-js";
import { sendWebResponse } from "vinxi/http";
import { type PlatformProxy } from "wrangler";
import { type Database, createDb } from "~/db/client";
import { tryGetUser } from "~/lib/jwt";
import { type Log, createLog } from "~/lib/log";
import { createSentry } from "~/lib/sentry";
type Proxy = PlatformProxy<Env, IncomingRequestCfProperties>;
interface CacheStorage {
open(cacheName: string): Promise<Cache>;
readonly default: Cache;
}
declare global {
// eslint-disable-next-line no-var
var cfPlatformProxy: Proxy;
}
declare module "@solidjs/start/server" {
interface RequestEventLocals {
cf: IncomingRequestCfProperties;
env: Env;
caches: CacheStorage;
waitUntil: (promise: Promise<unknown>) => void;
passThroughOnException: () => void;
sentry: Toucan;
log: Log;
user?: string;
db: Database;
}
}
const ensurePlatformProxy = async (): Promise<Proxy> => {
if (globalThis.cfPlatformProxy) return globalThis.cfPlatformProxy;
const wrangler = await import("wrangler");
const proxy = await wrangler.getPlatformProxy<Env>({ persist: true });
globalThis.cfPlatformProxy = proxy;
return proxy;
};
const cloudflare = async (event: FetchEvent): Promise<void> => {
if (import.meta.env.DEV) {
const platformProxy = await ensurePlatformProxy();
event.locals.cf = platformProxy.cf;
event.locals.env = platformProxy.env;
event.locals.caches = platformProxy.caches as unknown as CacheStorage;
event.locals.waitUntil = platformProxy.ctx.waitUntil;
event.locals.passThroughOnException = platformProxy.ctx.passThroughOnException;
} else {
const context = event.nativeEvent.context;
event.locals.cf = context.cf;
event.locals.env = context.cloudflare.env;
event.locals.caches = caches as unknown as CacheStorage;
event.locals.waitUntil = context.waitUntil;
event.locals.passThroughOnException = context.passThroughOnException;
}
};
const redirectToDomain = (event: FetchEvent): Response | undefined => {
if (import.meta.env.DEV) return;
const domain = event.locals.env.DOMAIN;
const url = new URL(event.request.url);
if (url.hostname !== "localhost" && url.host !== domain) {
url.host = domain;
url.protocol = "https:";
return redirect(url.href);
}
};
const sentry = (event: FetchEvent): void => {
event.locals.sentry = createSentry(event);
event.locals.log = createLog(event.locals.sentry);
};
const user = async (event: FetchEvent): Promise<Response | undefined> => {
if (!event.locals.env.JWT_ISSUER) return;
const user = await tryGetUser(event);
if (!user) {
await sendWebResponse(new Response("Unauthorized", { status: 401 }));
return;
}
event.locals.user = user;
};
const db = (event: FetchEvent): void => {
event.locals.db = createDb(event);
};
export default createMiddleware({
onRequest: [cloudflare, redirectToDomain, sentry, user, db]
});