| 1 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 2 | import { assert, it } from "@effect/vitest"; |
| 3 | import { AuthProvidersManageScope, AuthOrchestrationReadScope } from "@t3tools/contracts"; |
| 4 | import * as Effect from "effect/Effect"; |
| 5 | import * as Context from "effect/Context"; |
| 6 | import * as Layer from "effect/Layer"; |
| 7 | import * as Schema from "effect/Schema"; |
| 8 | import { HttpRouter } from "effect/http"; |
| 9 | import * as ServerConfig from "../config.ts"; |
| 10 | import * as EnvironmentAuth from "../auth/EnvironmentAuth.ts"; |
| 11 | import { layerSharedAccountRoute } from "../http.ts"; |
| 12 | import * as SharedAccounts from "./SharedAccounts.ts"; |
| 13 | |
| 14 | const encode = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown)); |
| 15 | const layer = SharedAccounts.layer.pipe( |
| 16 | Layer.provideMerge(EnvironmentAuth.layerRuntime), |
| 17 | Layer.provide(ServerConfig.layerTest(process.cwd(), { prefix: "t3-shared-http-" })), |
| 18 | Layer.provide(NodeServices.layer), |
| 19 | ); |
| 20 | |
| 21 | it.live( |
| 22 | "requires provider management authority and never returns credential causes in HTTP errors", |
| 23 | () => |
| 24 | Effect.gen(function* () { |
| 25 | const auth = yield* EnvironmentAuth.EnvironmentAuth; |
| 26 | const accounts = yield* SharedAccounts.SharedAccounts; |
| 27 | const manager = yield* auth.issueSession({ scopes: [AuthProvidersManageScope] }); |
| 28 | const reader = yield* auth.issueSession({ scopes: [AuthOrchestrationReadScope] }); |
| 29 | const requestContext = Context.make(EnvironmentAuth.EnvironmentAuth, auth).pipe( |
| 30 | Context.add(SharedAccounts.SharedAccounts, accounts), |
| 31 | ); |
| 32 | const app = yield* Effect.acquireRelease( |
| 33 | Effect.sync(() => |
| 34 | HttpRouter.toWebHandler(layerSharedAccountRoute, { disableLogger: true }), |
| 35 | ), |
| 36 | (app) => Effect.promise(() => app.dispose()), |
| 37 | ); |
| 38 | const post = (body: unknown, token?: string) => |
| 39 | Effect.promise(() => |
| 40 | app.handler( |
| 41 | new Request("http://127.0.0.1/api/shared/accounts", { |
| 42 | method: "POST", |
| 43 | headers: { |
| 44 | "content-type": "application/json", |
| 45 | ...(token ? { authorization: `Bearer ${token}` } : {}), |
| 46 | }, |
| 47 | body: encode(body), |
| 48 | }), |
| 49 | requestContext, |
| 50 | ), |
| 51 | ); |
| 52 | assert.strictEqual((yield* post({ type: "list" })).status, 401); |
| 53 | assert.strictEqual((yield* post({ type: "list" }, reader.token)).status, 403); |
| 54 | const response = yield* post({ type: "list" }, manager.token); |
| 55 | assert.strictEqual(response.status, 200); |
| 56 | assert.strictEqual(response.headers.get("cache-control"), "no-store"); |
| 57 | const invalid = yield* post( |
| 58 | { |
| 59 | type: "import", |
| 60 | label: "Personal", |
| 61 | credentials: { driver: "codex", accessToken: "private-value-in-malformed-input" }, |
| 62 | }, |
| 63 | manager.token, |
| 64 | ); |
| 65 | assert.strictEqual(invalid.status, 503); |
| 66 | const error = yield* Effect.promise(() => invalid.text()); |
| 67 | assert.isFalse(error.includes("private-value")); |
| 68 | assert.isFalse(error.includes("cause")); |
| 69 | }).pipe(Effect.provide(layer)), |
| 70 | ); |