(request: Request)
| 242 | |
| 243 | /** (a) The mcp() OAuth opaque bearer, with self-enforced expiry. */ |
| 244 | const authenticateOAuthBearer = (request: Request): Effect.Effect<Principal | null> => |
| 245 | Effect.gen(function* () { |
| 246 | const session = yield* Effect.promise(() => |
| 247 | auth.api.getMcpSession({ headers: request.headers }), |
| 248 | ); |
| 249 | if (!session) return null; |
| 250 | // GOTCHA: getMcpSession does NOT validate accessTokenExpiresAt — an |
| 251 | // expired token still resolves. Reject it here. |
| 252 | if (new Date(session.accessTokenExpiresAt).getTime() < Date.now()) return null; |
| 253 | return yield* principalFromUserId(session.userId); |
| 254 | }).pipe(Effect.orElseSucceed(() => null)); |
| 255 | |
| 256 | /** (b) The existing cookie / bearer-session / x-api-key path. The fallback's |
| 257 | * api `Principal` shape is byte-identical to host-mcp's `Principal`. The |
no test coverage detected