1import { DateTime, Effect, Layer, Redacted } from "effect"
2import { Authorization, CurrentUser, Unauthorized } from "../api/Authorization.ts"
3import { User, UserId } from "../domain/User.ts"
4
5const fixedTimestamp = DateTime.makeUnsafe("2026-01-01T00:00:00Z")
6const devUser = new User({
7 id: UserId.make("bf3dbe33-0ad2-4c9c-9c9e-733e57bdcbee"),
8 name: "Dev User",
9 email: "dev@acme.com",
10 createdAt: fixedTimestamp,
11 updatedAt: fixedTimestamp
12})
13
14// The implementation of the Authorization middleware. It is seperate from the
15// service definition to avoid leaking it into a client.
16export const AuthorizationLayer = Layer.effect(
17 Authorization,
18 Effect.gen(function*() {
19 // Here you could access services required by the middleware, like a
20 // database or an external auth provider.
21 yield* Effect.logInfo("Starting Authorization middleware")
22
23 return Authorization.of({
24 bearer: Effect.fn(function*(httpEffect, { credential }) {
25 // Validate the token and return an Unauthorized error if it's invalid.
26 const token = Redacted.value(credential)
27 if (token !== "dev-token") {
28 return yield* new Unauthorized({ message: "Missing or invalid bearer token" })
29 }
30
31 // Provide the current user to the rest of the stack. This will be
32 // available in any endpoint or middleware that runs after this one.
33 return yield* Effect.provideService(httpEffect, CurrentUser, devUser)
34 })
35 })
36 })
37)