1import * as Cloudflare from "@/Cloudflare/index.ts";
2import * as Effect from "effect/Effect";
3import * as HttpServerResponse from "effect/http/HttpServerResponse";
4
5/**
6 * The Access application this Worker enrolls into — policies authored
7 * inline (application-owned), no separate Policy resource.
8 */
9export const App = Cloudflare.Access.Application("WorkerAccessApp", {
10 type: "self_hosted",
11 name: "Access for alchemy worker-enrollment test",
12 policies: [
13 {
14 decision: "allow",
15 include: [{ emailDomain: "example.com" }],
16 },
17 ],
18});
19
20/**
21 * Worker protected by Access via the `access` prop: the provider enrolls it
22 * into {@link App} (worker + preview destinations). The fetch handler
23 * serves a marker body plus its `ctx.access` view, so the test can
24 * distinguish "worker answered directly" from "Access intercepted".
25 */
26export default class AccessProtectedWorker extends Cloudflare.Worker<AccessProtectedWorker>()(
27 "AccessProtectedWorker",
28 {
29 main: import.meta.url,
30 access: App,
31 },
32 Effect.gen(function* () {
33 return {
34 fetch: Effect.gen(function* () {
35 const access = yield* Cloudflare.Access.Context;
36 const identity =
37 access === undefined
38 ? undefined
39 : yield* access.getIdentity().pipe(Effect.orDie);
40 return yield* HttpServerResponse.json({
41 marker: "alchemy-access-worker-open",
42 authenticated: access !== undefined,
43 aud: access?.aud,
44 email: identity?.email,
45 });
46 }),
47 };
48 }),
49) {}