// ---------------------------------------------------------------------------// The membership mirror's FEEDERS, end to end through the code that runs in// production, against the real PGlite Postgres every cloud unit test runs on// (scripts/test-globalsetup.ts). WorkOS is a fake `WorkOSClient` (the// emulator has no list-users / events routes); the mirror, the user store,// and the directory read are the live layers over `DbService.Live`.//// What this pins:// - the login callback records the signed-in user and EVERY membership// WorkOS lists (active and pending), with the org row minted so the FK// holds — from the one membership list it already fetches// - the callback picks the landing org from that same list: a returnTo// slug or last-org cookie lands only in an ACTIVE membership, an unknown// or pending one falls through// - `inviteMember` mirrors the PENDING membership WorkOS created for the// invitee (found by email among the org's pending memberships), so the// member list shows the invite and can revoke it// - `removeMember` tombstones the mirror row after the WorkOS delete,// stamped with the membership's last WorkOS state (never a local clock),// so a replay of the membership as it was before the delete cannot// restore it while a replacement WorkOS created meanwhile is accepted// - `updateMemberRole` writes the role WorkOS returned// - deleting an org marks it deleted locally FIRST, so every member's// session is refused at once even when the billing cancel, the WorkOS// delete, or the local purge fails afterwards; billing is cancelled// BEFORE the WorkOS delete, so a failed cancel leaves the WorkOS org// intact and the retry finishes the deletion; a retry after WorkOS// already deleted the org still runs the purge — even while the mirror// is not ready, when WorkOS can no longer vouch for the admin; a marked// org leaves the switcher// - authorization scans an organization the backfill never covered (its// `backfilled_at` is missing) from WorkOS before reading its mirror,// once, so a member the mirror never recorded is admitted; an// organization the mirror does not hold at all is resolved from WorkOS// for a caller WorkOS confirms as its member, and minted for nobody else// - the seat gate trusts the mirror's count only for an organization whose// membership list was scanned from WorkOS in full: an unmarked one is// scanned first (once), so a partial mirror never admits an invite past// the plan limit// - the seat reporter scans an unmarked organization before counting and// never re-scans a marked one// - the backfill mirrors every org's members and counts what it wrote,// writes nothing on a dry run, converges on a re-run, tombstones a// membership WorkOS no longer lists — but never one written after its// listing was taken — marks each org backfilled as of its listing, and// records the events replay boundary BEFORE its first listing and only// ONCE: a run that fails part-way keeps the marks of the orgs it// finished and the boundary it recorded, and its retry (like any later// run) keeps that first boundary — so a user deleted between the failed// attempt and the retry is still inside the events replay, and the// reconciler clears their profile// - two scans of one org that overlap cannot resurrect a membership: a scan// that listed it, stalled, and resumed after a later listing (which no// longer had it) was applied is refused whole// - a login whose membership list was fetched BEFORE the org was purged and// written after cannot re-mint the org or its membership, one fetched// before a rename cannot revert the rename, and one fetched before a// revocation the backfill has since scanned cannot reinstate the// membership// --------------------------------------------------------------------------- import { describe, expect, it } from "@effect/vitest";import { sql } from "drizzle-orm";import { Effect, Exit, Fiber, Latch, Layer, Option } from "effect";import { HttpRouter, HttpServer } from "effect/unstable/http";import { HttpApiBuilder } from "effect/unstable/httpapi"; import { AccountForbidden } from "@executor-js/api";import { AccountProvider, MemberDirectory, RouterConfigLive, requestScopedMiddleware,} from "@executor-js/api/server"; import { AccountCaller, workosAccountProvider } from "../account/workos-account-service";import { RequestScopedServicesLive } from "../api/layers";import { DbService } from "../db/db";import { forkReportMemberSeats } from "../extensions/billing/member-seats";import { AutumnError, AutumnService, type AutumnFailure } from "../extensions/billing/service";import { ApiKeyService } from "./api-keys";import { UserStoreService } from "./context";import { UserStoreError, WorkOSError } from "./errors";import { CloudAuthPublicHandlers, CloudSessionAuthHandlers, NonProtectedApi } from "./handlers";import { LAST_ORG_COOKIE } from "./last-org-cookie";import { encodeLoginState } from "./login-state";import { cloudMemberDirectoryLayer } from "./member-directory";import { SessionAuthLive } from "./middleware-live";import { mirrorSignIn } from "./mirror-feeders";import { ORG_SELECTOR_HEADER, authorizeOrganization, markOrganizationDeleted,} from "./organization";import { WorkOSClient, type WorkOSClientService } from "./workos";import { WorkOsMirror, type WorkOsMirrorShape } from "./workos-mirror";import { backfillOrganization, backfillWorkOsMirror } from "./workos-mirror-backfill";import type { WorkOsMembershipPayload, WorkOsUserPayload } from "./workos-mirror-store"; const T1 = "2026-01-01T00:00:00.000Z";const T2 = "2026-01-02T00:00:00.000Z"; // Synthetic identities only. Every test mints its own org ids so the shared// test database never couples two tests.const freshId = (prefix: string) => `${prefix}_${crypto.randomUUID().replaceAll("-", "")}`; const workosUser = (id: string, overrides: Partial<WorkOsUserPayload> = {}) => ({ object: "user" as const, id, email: `${id}@placeholder.test`, emailVerified: true, firstName: "Ada", lastName: "Placeholder", profilePictureUrl: null, lastSignInAt: T1, locale: null, createdAt: T1, updatedAt: T1, externalId: null, metadata: {}, ...overrides,}); interface FakeMembership extends WorkOsMembershipPayload { readonly organizationName: string;} const workosMembership = ( userId: string, organizationId: string, overrides: Partial<FakeMembership> = {},): FakeMembership => ({ id: `om_${userId}_${organizationId}`, userId, organizationId, organizationName: `Org ${organizationId}`, role: { slug: "member" }, status: "active", updatedAt: T1, ...overrides,}); /** Mirrored rows for one org, read through the live cloud `MemberDirectory`. */const readMembers = (organizationId: string) => Effect.runPromise( Effect.flatMap(MemberDirectory.asEffect(), (directory) => directory.members(organizationId, { statuses: ["active", "pending", "inactive"], }), ).pipe( Effect.provide(cloudMemberDirectoryLayer.pipe(Layer.provide(DbService.Live))), Effect.scoped, ), ); /** Mirror an org row (named as of T1) and return the URL slug the store minted for it. */const seedOrganization = (id: string) => Effect.runPromise( Effect.flatMap(UserStoreService.asEffect(), (users) => users.use("upsertOrganization", (s) => s.upsertOrganization({ id, name: `Org ${id}`, updatedAt: new Date(T1), }), ), ).pipe( Effect.map((org) => org.slug), Effect.provide(UserStoreService.Live.pipe(Layer.provide(DbService.Live))), Effect.scoped, ), ); const stubAutumn = Layer.succeed(AutumnService)({ use: () => Effect.die("feeders do not read billing"), ensureCustomer: () => Effect.void, checkExecutionBalance: () => Effect.die("feeders do not check balances"), trackExecution: () => Effect.void, setMemberSeats: () => Effect.void,}); /** * A `WorkOSClient` whose every method is one of `methods`; anything else is * an unexpected call and dies, so a feeder that silently adds a WorkOS read * fails the test instead of passing on a fake. */const stubWorkOS = (methods: Partial<WorkOSClientService>) => Layer.succeed( WorkOSClient, new Proxy({} as WorkOSClientService, { get: (_target, prop) => (methods as Record<PropertyKey, unknown>)[prop] ?? (() => Effect.die(`unexpected WorkOSClient.${String(prop)} call`)), }), ); describe("login callback", () => { const callbackHandler = (workos: Layer.Layer<WorkOSClient>) => HttpRouter.toWebHandler( HttpApiBuilder.layer(NonProtectedApi).pipe( Layer.provide(Layer.mergeAll(CloudAuthPublicHandlers, CloudSessionAuthHandlers)), Layer.provide(requestScopedMiddleware(RequestScopedServicesLive).layer), Layer.provideMerge(SessionAuthLive), Layer.provideMerge(stubAutumn), Layer.provideMerge(workos), Layer.provideMerge(HttpServer.layerServices), Layer.provideMerge(RouterConfigLive), ), { disableLogger: true }, ).handler; const STATE_COOKIE = "wos-login-state"; /** * A callback handler over a fake WorkOS that authenticates `user` with the * memberships `listed`, recording every WorkOS read (`calls`) and every * session refresh (`refreshedInto`, the org ids) so the landing-org choice * is assertable from the outside. */ const signIn = (user: ReturnType<typeof workosUser>, listed: readonly FakeMembership[]) => { const calls: string[] = []; const refreshedInto: (string | undefined)[] = []; const handler = callbackHandler( stubWorkOS({ authenticateWithCode: () => Effect.succeed({ user, organizationId: undefined, accessToken: "access", refreshToken: "refresh", sealedSession: "sealed", }), listUserMemberships: (id) => { calls.push(`listUserMemberships:${id}`); return Effect.succeed({ object: "list" as const, data: listed as never[], listMetadata: { before: null, after: null }, }); }, // The landing org's seat recount scans the org from WorkOS the first // time it is counted (its per-org backfill mark is missing); the // scan lists the org's members and fetches each user. listOrgMembers: (organizationId) => { calls.push(`listOrgMembers:${organizationId}`); return Effect.succeed({ object: "list" as const, data: listed.filter((m) => m.organizationId === organizationId) as never[], listMetadata: { before: null, after: null }, }); }, getUser: (id) => { calls.push(`getUser:${id}`); return Effect.succeed(workosUser(id) as never); }, refreshSession: (_sealed, organizationId) => { refreshedInto.push(organizationId); return Effect.succeed("sealed-refreshed"); }, }), ); return { handler, calls, refreshedInto }; }; /** * `GET /auth/callback` with the CSRF-matched login `state` (the callback * refuses any request without one) and any extra cookies; `returnTo` * rides inside the state as /login mints it. */ const callbackRequest = (options: { returnTo?: string; cookies?: Record<string, string> }) => { const url = new URL("http://test.local/auth/callback"); url.searchParams.set("code", "code_1"); const state = encodeLoginState({ nonce: "nonce", ...(options.returnTo === undefined ? {} : { returnTo: options.returnTo }), }); url.searchParams.set("state", state); const cookies = { ...options.cookies, [STATE_COOKIE]: state }; const cookie = Object.entries(cookies) .map(([name, value]) => `${name}=${value}`) .join("; "); return new Request(url, { headers: cookie ? { cookie } : {} }); }; it("records the user and every listed membership from the one list it already fetches", async () => { const userId = freshId("user"); const activeOrg = freshId("org"); const pendingOrg = freshId("org"); const { handler, calls } = signIn( workosUser(userId, { firstName: "Grace", lastName: "Hopper", updatedAt: T2, }), [ workosMembership(userId, activeOrg, { role: { slug: "admin" }, updatedAt: T2, }), workosMembership(userId, pendingOrg, { status: "pending" }), ], ); const response = await handler(callbackRequest({})); expect(response.status).toBe(302); expect( calls, "one membership list for the callback itself; the landing org, never scanned, is scanned once for its seat count", ).toEqual([ `listUserMemberships:${userId}`, `listOrgMembers:${activeOrg}`, `getUser:${userId}`, ]); calls.length = 0; expect((await handler(callbackRequest({}))).status).toBe(302); expect(calls, "a second sign-in lists memberships only: the org is now marked").toEqual([ `listUserMemberships:${userId}`, ]); const active = await readMembers(activeOrg); expect(active).toHaveLength(1); expect(active[0]).toMatchObject({ accountId: userId, membershipId: `om_${userId}_${activeOrg}`, email: `${userId}@placeholder.test`, name: "Grace Hopper", role: "admin", status: "active", lastActiveAt: new Date(T1).getTime(), }); const pending = await readMembers(pendingOrg); expect( pending.map((m) => m.status), "pending memberships are mirrored too", ).toEqual(["pending"]); }); describe("lands in the org the returnTo slug names", () => { it("when the user holds an active membership there", async () => { const userId = freshId("user"); const requested = freshId("org"); const other = freshId("org"); const slug = await seedOrganization(requested); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, other), workosMembership(userId, requested), ]); const response = await handler(callbackRequest({ returnTo: `/${slug}/settings` })); expect(response.status).toBe(302); expect(response.headers.get("location")).toBe(`/${slug}/settings`); expect(refreshedInto, "the session is switched into the requested org").toEqual([requested]); }); it("never when the membership there is only pending", async () => { const userId = freshId("user"); const requested = freshId("org"); const other = freshId("org"); const slug = await seedOrganization(requested); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, other), workosMembership(userId, requested, { status: "pending" }), ]); const response = await handler(callbackRequest({ returnTo: `/${slug}` })); expect(response.status).toBe(302); expect(response.headers.get("location")).toBe(`/${slug}`); expect( refreshedInto, "a pending membership is not a landing candidate, and an explicit slug does not fall back to another org", ).toEqual([]); }); }); describe("without a returnTo org", () => { it("lands in the last-org cookie's org when the user is active there", async () => { const userId = freshId("user"); const last = freshId("org"); const other = freshId("org"); const slug = await seedOrganization(last); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, other), workosMembership(userId, last), ]); const response = await handler(callbackRequest({ cookies: { [LAST_ORG_COOKIE]: slug } })); expect(response.status).toBe(302); expect(response.headers.get("location")).toBe("/"); expect(refreshedInto).toEqual([last]); }); it("falls through an unknown last-org slug to the first active membership", async () => { const userId = freshId("user"); const pendingOrg = freshId("org"); const activeOrg = freshId("org"); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, pendingOrg, { status: "pending" }), workosMembership(userId, activeOrg), ]); const response = await handler( // Valid slug grammar, never minted: the store finds no org for it. callbackRequest({ cookies: { [LAST_ORG_COOKIE]: "no-such-org-slug" } }), ); expect(response.status).toBe(302); expect(refreshedInto).toEqual([activeOrg]); }); });}); describe("a delayed sign-in feeder", () => { /** The live mirror, user store, and directory over one test-db socket. */ const Services = Layer.mergeAll( UserStoreService.Live, WorkOsMirror.Live, cloudMemberDirectoryLayer, ).pipe(Layer.provideMerge(DbService.Live)); const run = <A, E>( body: Effect.Effect<A, E, UserStoreService | WorkOsMirror | MemberDirectory | DbService>, ) => Effect.runPromise(body.pipe(Effect.provide(Services), Effect.scoped)); const readOrganization = (org: string) => Effect.flatMap(UserStoreService.asEffect(), (users) => users.use("getOrganization", (s) => s.getOrganization(org)), ); const readMembership = (userId: string, org: string) => Effect.flatMap(MemberDirectory.asEffect(), (directory) => directory.membership(userId, org, ["active", "pending", "inactive"]), ); it("cannot re-mint a purged organization or its membership from a list fetched before the purge", async () => { const userId = freshId("user"); const org = freshId("org"); await seedOrganization(org); const result = await run( Effect.gen(function* () { const users = yield* UserStoreService; // The login fetched its membership list at T1, while the org lived... const fetchedAt = new Date(T1); const listed = [workosMembership(userId, org)]; // ...then stalled while cloud's deletion flow purged the org at T2. yield* users.use("deleteOrganizationCascade", (s) => s.deleteOrganizationCascade(org, new Date(T2)), ); // The stalled login resumes and writes what it holds. yield* mirrorSignIn(workosUser(userId), listed, fetchedAt); return { organization: yield* readOrganization(org), membership: yield* readMembership(userId, org), }; }), ); expect(result.organization?.deletedAt, "the org stays a deleted tombstone").toEqual( new Date(T2), ); expect(result.membership, "and holds no membership: nothing to authorize").toBeNull(); }); it("cannot reinstate a membership from a list fetched before a revocation the backfill has since scanned", async () => { const userId = freshId("user"); const org = freshId("org"); await seedOrganization(org); const result = await run( Effect.gen(function* () { const mirror = yield* WorkOsMirror; // The login fetched its membership list at T1, while the user was // a member, then stalled... const fetchedAt = new Date(T1); const listed = [workosMembership(userId, org)]; // ...WorkOS revoked the membership before the mirror was ever // backfilled, and the backfill then scanned the org at T2 without // it: no tombstone, the row was never there — and the revocation // predates the events replay boundary, so no event will land it. yield* mirror.applyOrganizationScan({ organizationId: org, listedAt: new Date(T2), members: [], }); // The stalled login resumes and writes what it holds. yield* mirrorSignIn(workosUser(userId), listed, fetchedAt); const membership = yield* readMembership(userId, org); // A login after the scan, carrying a membership WorkOS created // since (stamped past the scan), is recorded. const rejoinedAt = "2026-01-03T00:00:00.000Z"; yield* mirrorSignIn( workosUser(userId), [ workosMembership(userId, org, { id: `om_${userId}_${org}_2`, updatedAt: rejoinedAt, }), ], new Date(rejoinedAt),Lines 1–500 of 2021. Load more
// --------------------------------------------------------------------------- // The membership mirror's FEEDERS, end to end through the code that runs in // production, against the real PGlite Postgres every cloud unit test runs on // (scripts/test-globalsetup.ts). WorkOS is a fake `WorkOSClient` (the // emulator has no list-users / events routes); the mirror, the user store, // and the directory read are the live layers over `DbService.Live`. // // What this pins: // - the login callback records the signed-in user and EVERY membership // WorkOS lists (active and pending), with the org row minted so the FK // holds — from the one membership list it already fetches // - the callback picks the landing org from that same list: a returnTo // slug or last-org cookie lands only in an ACTIVE membership, an unknown // or pending one falls through // - `inviteMember` mirrors the PENDING membership WorkOS created for the // invitee (found by email among the org's pending memberships), so the // member list shows the invite and can revoke it // - `removeMember` tombstones the mirror row after the WorkOS delete, // stamped with the membership's last WorkOS state (never a local clock), // so a replay of the membership as it was before the delete cannot // restore it while a replacement WorkOS created meanwhile is accepted // - `updateMemberRole` writes the role WorkOS returned // - deleting an org marks it deleted locally FIRST, so every member's // session is refused at once even when the billing cancel, the WorkOS // delete, or the local purge fails afterwards; billing is cancelled // BEFORE the WorkOS delete, so a failed cancel leaves the WorkOS org // intact and the retry finishes the deletion; a retry after WorkOS // already deleted the org still runs the purge — even while the mirror // is not ready, when WorkOS can no longer vouch for the admin; a marked // org leaves the switcher // - authorization scans an organization the backfill never covered (its // `backfilled_at` is missing) from WorkOS before reading its mirror, // once, so a member the mirror never recorded is admitted; an // organization the mirror does not hold at all is resolved from WorkOS // for a caller WorkOS confirms as its member, and minted for nobody else // - the seat gate trusts the mirror's count only for an organization whose // membership list was scanned from WorkOS in full: an unmarked one is // scanned first (once), so a partial mirror never admits an invite past // the plan limit // - the seat reporter scans an unmarked organization before counting and // never re-scans a marked one // - the backfill mirrors every org's members and counts what it wrote, // writes nothing on a dry run, converges on a re-run, tombstones a // membership WorkOS no longer lists — but never one written after its // listing was taken — marks each org backfilled as of its listing, and // records the events replay boundary BEFORE its first listing and only // ONCE: a run that fails part-way keeps the marks of the orgs it // finished and the boundary it recorded, and its retry (like any later // run) keeps that first boundary — so a user deleted between the failed // attempt and the retry is still inside the events replay, and the // reconciler clears their profile // - two scans of one org that overlap cannot resurrect a membership: a scan // that listed it, stalled, and resumed after a later listing (which no // longer had it) was applied is refused whole // - a login whose membership list was fetched BEFORE the org was purged and // written after cannot re-mint the org or its membership, one fetched // before a rename cannot revert the rename, and one fetched before a // revocation the backfill has since scanned cannot reinstate the // membership // --------------------------------------------------------------------------- import { describe, expect, it } from "@effect/vitest"; import { sql } from "drizzle-orm"; import { Effect, Exit, Fiber, Latch, Layer, Option } from "effect"; import { HttpRouter, HttpServer } from "effect/unstable/http"; import { HttpApiBuilder } from "effect/unstable/httpapi"; import { AccountForbidden } from "@executor-js/api"; import { AccountProvider, MemberDirectory, RouterConfigLive, requestScopedMiddleware, } from "@executor-js/api/server"; import { AccountCaller, workosAccountProvider } from "../account/workos-account-service"; import { RequestScopedServicesLive } from "../api/layers"; import { DbService } from "../db/db"; import { forkReportMemberSeats } from "../extensions/billing/member-seats"; import { AutumnError, AutumnService, type AutumnFailure } from "../extensions/billing/service"; import { ApiKeyService } from "./api-keys"; import { UserStoreService } from "./context"; import { UserStoreError, WorkOSError } from "./errors"; import { CloudAuthPublicHandlers, CloudSessionAuthHandlers, NonProtectedApi } from "./handlers"; import { LAST_ORG_COOKIE } from "./last-org-cookie"; import { encodeLoginState } from "./login-state"; import { cloudMemberDirectoryLayer } from "./member-directory"; import { SessionAuthLive } from "./middleware-live"; import { mirrorSignIn } from "./mirror-feeders"; import { ORG_SELECTOR_HEADER, authorizeOrganization, markOrganizationDeleted, } from "./organization"; import { WorkOSClient, type WorkOSClientService } from "./workos"; import { WorkOsMirror, type WorkOsMirrorShape } from "./workos-mirror"; import { backfillOrganization, backfillWorkOsMirror } from "./workos-mirror-backfill"; import type { WorkOsMembershipPayload, WorkOsUserPayload } from "./workos-mirror-store"; const T1 = "2026-01-01T00:00:00.000Z"; const T2 = "2026-01-02T00:00:00.000Z"; // Synthetic identities only. Every test mints its own org ids so the shared // test database never couples two tests. const freshId = (prefix: string) => `${prefix}_${crypto.randomUUID().replaceAll("-", "")}`; const workosUser = (id: string, overrides: Partial<WorkOsUserPayload> = {}) => ({ object: "user" as const, id, email: `${id}@placeholder.test`, emailVerified: true, firstName: "Ada", lastName: "Placeholder", profilePictureUrl: null, lastSignInAt: T1, locale: null, createdAt: T1, updatedAt: T1, externalId: null, metadata: {}, ...overrides, }); interface FakeMembership extends WorkOsMembershipPayload { readonly organizationName: string; } const workosMembership = ( userId: string, organizationId: string, overrides: Partial<FakeMembership> = {}, ): FakeMembership => ({ id: `om_${userId}_${organizationId}`, userId, organizationId, organizationName: `Org ${organizationId}`, role: { slug: "member" }, status: "active", updatedAt: T1, ...overrides, }); /** Mirrored rows for one org, read through the live cloud `MemberDirectory`. */ const readMembers = (organizationId: string) => Effect.runPromise( Effect.flatMap(MemberDirectory.asEffect(), (directory) => directory.members(organizationId, { statuses: ["active", "pending", "inactive"], }), ).pipe( Effect.provide(cloudMemberDirectoryLayer.pipe(Layer.provide(DbService.Live))), Effect.scoped, ), ); /** Mirror an org row (named as of T1) and return the URL slug the store minted for it. */ const seedOrganization = (id: string) => Effect.runPromise( Effect.flatMap(UserStoreService.asEffect(), (users) => users.use("upsertOrganization", (s) => s.upsertOrganization({ id, name: `Org ${id}`, updatedAt: new Date(T1), }), ), ).pipe( Effect.map((org) => org.slug), Effect.provide(UserStoreService.Live.pipe(Layer.provide(DbService.Live))), Effect.scoped, ), ); const stubAutumn = Layer.succeed(AutumnService)({ use: () => Effect.die("feeders do not read billing"), ensureCustomer: () => Effect.void, checkExecutionBalance: () => Effect.die("feeders do not check balances"), trackExecution: () => Effect.void, setMemberSeats: () => Effect.void, }); /** * A `WorkOSClient` whose every method is one of `methods`; anything else is * an unexpected call and dies, so a feeder that silently adds a WorkOS read * fails the test instead of passing on a fake. */ const stubWorkOS = (methods: Partial<WorkOSClientService>) => Layer.succeed( WorkOSClient, new Proxy({} as WorkOSClientService, { get: (_target, prop) => (methods as Record<PropertyKey, unknown>)[prop] ?? (() => Effect.die(`unexpected WorkOSClient.${String(prop)} call`)), }), ); describe("login callback", () => { const callbackHandler = (workos: Layer.Layer<WorkOSClient>) => HttpRouter.toWebHandler( HttpApiBuilder.layer(NonProtectedApi).pipe( Layer.provide(Layer.mergeAll(CloudAuthPublicHandlers, CloudSessionAuthHandlers)), Layer.provide(requestScopedMiddleware(RequestScopedServicesLive).layer), Layer.provideMerge(SessionAuthLive), Layer.provideMerge(stubAutumn), Layer.provideMerge(workos), Layer.provideMerge(HttpServer.layerServices), Layer.provideMerge(RouterConfigLive), ), { disableLogger: true }, ).handler; const STATE_COOKIE = "wos-login-state"; /** * A callback handler over a fake WorkOS that authenticates `user` with the * memberships `listed`, recording every WorkOS read (`calls`) and every * session refresh (`refreshedInto`, the org ids) so the landing-org choice * is assertable from the outside. */ const signIn = (user: ReturnType<typeof workosUser>, listed: readonly FakeMembership[]) => { const calls: string[] = []; const refreshedInto: (string | undefined)[] = []; const handler = callbackHandler( stubWorkOS({ authenticateWithCode: () => Effect.succeed({ user, organizationId: undefined, accessToken: "access", refreshToken: "refresh", sealedSession: "sealed", }), listUserMemberships: (id) => { calls.push(`listUserMemberships:${id}`); return Effect.succeed({ object: "list" as const, data: listed as never[], listMetadata: { before: null, after: null }, }); }, // The landing org's seat recount scans the org from WorkOS the first // time it is counted (its per-org backfill mark is missing); the // scan lists the org's members and fetches each user. listOrgMembers: (organizationId) => { calls.push(`listOrgMembers:${organizationId}`); return Effect.succeed({ object: "list" as const, data: listed.filter((m) => m.organizationId === organizationId) as never[], listMetadata: { before: null, after: null }, }); }, getUser: (id) => { calls.push(`getUser:${id}`); return Effect.succeed(workosUser(id) as never); }, refreshSession: (_sealed, organizationId) => { refreshedInto.push(organizationId); return Effect.succeed("sealed-refreshed"); }, }), ); return { handler, calls, refreshedInto }; }; /** * `GET /auth/callback` with the CSRF-matched login `state` (the callback * refuses any request without one) and any extra cookies; `returnTo` * rides inside the state as /login mints it. */ const callbackRequest = (options: { returnTo?: string; cookies?: Record<string, string> }) => { const url = new URL("http://test.local/auth/callback"); url.searchParams.set("code", "code_1"); const state = encodeLoginState({ nonce: "nonce", ...(options.returnTo === undefined ? {} : { returnTo: options.returnTo }), }); url.searchParams.set("state", state); const cookies = { ...options.cookies, [STATE_COOKIE]: state }; const cookie = Object.entries(cookies) .map(([name, value]) => `${name}=${value}`) .join("; "); return new Request(url, { headers: cookie ? { cookie } : {} }); }; it("records the user and every listed membership from the one list it already fetches", async () => { const userId = freshId("user"); const activeOrg = freshId("org"); const pendingOrg = freshId("org"); const { handler, calls } = signIn( workosUser(userId, { firstName: "Grace", lastName: "Hopper", updatedAt: T2, }), [ workosMembership(userId, activeOrg, { role: { slug: "admin" }, updatedAt: T2, }), workosMembership(userId, pendingOrg, { status: "pending" }), ], ); const response = await handler(callbackRequest({})); expect(response.status).toBe(302); expect( calls, "one membership list for the callback itself; the landing org, never scanned, is scanned once for its seat count", ).toEqual([ `listUserMemberships:${userId}`, `listOrgMembers:${activeOrg}`, `getUser:${userId}`, ]); calls.length = 0; expect((await handler(callbackRequest({}))).status).toBe(302); expect(calls, "a second sign-in lists memberships only: the org is now marked").toEqual([ `listUserMemberships:${userId}`, ]); const active = await readMembers(activeOrg); expect(active).toHaveLength(1); expect(active[0]).toMatchObject({ accountId: userId, membershipId: `om_${userId}_${activeOrg}`, email: `${userId}@placeholder.test`, name: "Grace Hopper", role: "admin", status: "active", lastActiveAt: new Date(T1).getTime(), }); const pending = await readMembers(pendingOrg); expect( pending.map((m) => m.status), "pending memberships are mirrored too", ).toEqual(["pending"]); }); describe("lands in the org the returnTo slug names", () => { it("when the user holds an active membership there", async () => { const userId = freshId("user"); const requested = freshId("org"); const other = freshId("org"); const slug = await seedOrganization(requested); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, other), workosMembership(userId, requested), ]); const response = await handler(callbackRequest({ returnTo: `/${slug}/settings` })); expect(response.status).toBe(302); expect(response.headers.get("location")).toBe(`/${slug}/settings`); expect(refreshedInto, "the session is switched into the requested org").toEqual([requested]); }); it("never when the membership there is only pending", async () => { const userId = freshId("user"); const requested = freshId("org"); const other = freshId("org"); const slug = await seedOrganization(requested); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, other), workosMembership(userId, requested, { status: "pending" }), ]); const response = await handler(callbackRequest({ returnTo: `/${slug}` })); expect(response.status).toBe(302); expect(response.headers.get("location")).toBe(`/${slug}`); expect( refreshedInto, "a pending membership is not a landing candidate, and an explicit slug does not fall back to another org", ).toEqual([]); }); }); describe("without a returnTo org", () => { it("lands in the last-org cookie's org when the user is active there", async () => { const userId = freshId("user"); const last = freshId("org"); const other = freshId("org"); const slug = await seedOrganization(last); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, other), workosMembership(userId, last), ]); const response = await handler(callbackRequest({ cookies: { [LAST_ORG_COOKIE]: slug } })); expect(response.status).toBe(302); expect(response.headers.get("location")).toBe("/"); expect(refreshedInto).toEqual([last]); }); it("falls through an unknown last-org slug to the first active membership", async () => { const userId = freshId("user"); const pendingOrg = freshId("org"); const activeOrg = freshId("org"); const { handler, refreshedInto } = signIn(workosUser(userId), [ workosMembership(userId, pendingOrg, { status: "pending" }), workosMembership(userId, activeOrg), ]); const response = await handler( // Valid slug grammar, never minted: the store finds no org for it. callbackRequest({ cookies: { [LAST_ORG_COOKIE]: "no-such-org-slug" } }), ); expect(response.status).toBe(302); expect(refreshedInto).toEqual([activeOrg]); }); }); }); describe("a delayed sign-in feeder", () => { /** The live mirror, user store, and directory over one test-db socket. */ const Services = Layer.mergeAll( UserStoreService.Live, WorkOsMirror.Live, cloudMemberDirectoryLayer, ).pipe(Layer.provideMerge(DbService.Live)); const run = <A, E>( body: Effect.Effect<A, E, UserStoreService | WorkOsMirror | MemberDirectory | DbService>, ) => Effect.runPromise(body.pipe(Effect.provide(Services), Effect.scoped)); const readOrganization = (org: string) => Effect.flatMap(UserStoreService.asEffect(), (users) => users.use("getOrganization", (s) => s.getOrganization(org)), ); const readMembership = (userId: string, org: string) => Effect.flatMap(MemberDirectory.asEffect(), (directory) => directory.membership(userId, org, ["active", "pending", "inactive"]), ); it("cannot re-mint a purged organization or its membership from a list fetched before the purge", async () => { const userId = freshId("user"); const org = freshId("org"); await seedOrganization(org); const result = await run( Effect.gen(function* () { const users = yield* UserStoreService; // The login fetched its membership list at T1, while the org lived... const fetchedAt = new Date(T1); const listed = [workosMembership(userId, org)]; // ...then stalled while cloud's deletion flow purged the org at T2. yield* users.use("deleteOrganizationCascade", (s) => s.deleteOrganizationCascade(org, new Date(T2)), ); // The stalled login resumes and writes what it holds. yield* mirrorSignIn(workosUser(userId), listed, fetchedAt); return { organization: yield* readOrganization(org), membership: yield* readMembership(userId, org), }; }), ); expect(result.organization?.deletedAt, "the org stays a deleted tombstone").toEqual( new Date(T2), ); expect(result.membership, "and holds no membership: nothing to authorize").toBeNull(); }); it("cannot reinstate a membership from a list fetched before a revocation the backfill has since scanned", async () => { const userId = freshId("user"); const org = freshId("org"); await seedOrganization(org); const result = await run( Effect.gen(function* () { const mirror = yield* WorkOsMirror; // The login fetched its membership list at T1, while the user was // a member, then stalled... const fetchedAt = new Date(T1); const listed = [workosMembership(userId, org)]; // ...WorkOS revoked the membership before the mirror was ever // backfilled, and the backfill then scanned the org at T2 without // it: no tombstone, the row was never there — and the revocation // predates the events replay boundary, so no event will land it. yield* mirror.applyOrganizationScan({ organizationId: org, listedAt: new Date(T2), members: [], }); // The stalled login resumes and writes what it holds. yield* mirrorSignIn(workosUser(userId), listed, fetchedAt); const membership = yield* readMembership(userId, org); // A login after the scan, carrying a membership WorkOS created // since (stamped past the scan), is recorded. const rejoinedAt = "2026-01-03T00:00:00.000Z"; yield* mirrorSignIn( workosUser(userId), [ workosMembership(userId, org, { id: `om_${userId}_${org}_2`, updatedAt: rejoinedAt, }), ], new Date(rejoinedAt),