@fragno-dev/auth 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +196 -9
  2. package/dist/browser/client/react.d.ts +1194 -64
  3. package/dist/browser/client/react.d.ts.map +1 -1
  4. package/dist/browser/client/react.js +1 -1
  5. package/dist/browser/client/react.js.map +1 -1
  6. package/dist/browser/client/solid.d.ts +1446 -64
  7. package/dist/browser/client/solid.d.ts.map +1 -1
  8. package/dist/browser/client/solid.js +1 -1
  9. package/dist/browser/client/solid.js.map +1 -1
  10. package/dist/browser/client/svelte.d.ts +1194 -64
  11. package/dist/browser/client/svelte.d.ts.map +1 -1
  12. package/dist/browser/client/svelte.js +1 -1
  13. package/dist/browser/client/svelte.js.map +1 -1
  14. package/dist/browser/client/vanilla.d.ts +1194 -64
  15. package/dist/browser/client/vanilla.d.ts.map +1 -1
  16. package/dist/browser/client/vanilla.js +1 -1
  17. package/dist/browser/client/vanilla.js.map +1 -1
  18. package/dist/browser/client/vue.d.ts +1150 -20
  19. package/dist/browser/client/vue.d.ts.map +1 -1
  20. package/dist/browser/client/vue.js +1 -1
  21. package/dist/browser/client/vue.js.map +1 -1
  22. package/dist/browser/index-m_5zsra2.d.ts +7141 -0
  23. package/dist/browser/index-m_5zsra2.d.ts.map +1 -0
  24. package/dist/browser/index.d.ts +2 -600
  25. package/dist/browser/index.js +2 -2
  26. package/dist/browser/src-Ck4bl2NH.js +1892 -0
  27. package/dist/browser/src-Ck4bl2NH.js.map +1 -0
  28. package/dist/node/index.d.ts +6806 -265
  29. package/dist/node/index.d.ts.map +1 -1
  30. package/dist/node/index.js +5532 -266
  31. package/dist/node/index.js.map +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +20 -39
  34. package/dist/browser/index.d.ts.map +0 -1
  35. package/dist/browser/src-DNrh9CQq.js +0 -184
  36. package/dist/browser/src-DNrh9CQq.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["password: string","storedHash: string","value: string","cookieHeader: string | null","cookies: Record<string, string>","value: string","options: CookieOptions","headers: Headers","queryParam?: string | null","bodySessionId?: string","email: string","passwordHash: string","role: \"user\" | \"admin\"","userId: string","sessionId: string","b","cookieOptions?: CookieOptions","sessionId: string","userId: string","b","headers: Headers","user: {\n id: unknown;\n email: string;\n role: string;\n createdAt: Date;\n }","params: GetUsersParams","effectiveSortBy: SortField","query","cursorParam: string | null","sortBy: SortField","config: AuthConfig","fragnoConfig: FragnoPublicConfigWithDatabase","fragnoConfig?: FragnoPublicClientConfig","params?: { sessionId?: string }"],"sources":["../../src/schema.ts","../../src/user/password.ts","../../src/utils/cookie.ts","../../src/user/user-actions.ts","../../src/session/session.ts","../../src/user/user-overview.ts","../../src/index.ts"],"sourcesContent":["import { column, idColumn, referenceColumn, schema } from \"@fragno-dev/db/schema\";\n\nexport const authSchema = schema(\"auth\", (s) => {\n return s\n .addTable(\"user\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"email\", column(\"string\"))\n .addColumn(\"passwordHash\", column(\"string\"))\n .addColumn(\"role\", column(\"string\").defaultTo(\"user\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_user_email\", [\"email\"])\n .createIndex(\"idx_user_id\", [\"id\"], { unique: true });\n })\n .addTable(\"session\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"userId\", referenceColumn())\n .addColumn(\"expiresAt\", column(\"timestamp\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_session_user\", [\"userId\"]);\n })\n .addReference(\"sessionOwner\", {\n from: {\n table: \"session\",\n column: \"userId\",\n },\n to: {\n table: \"user\",\n column: \"id\",\n },\n type: \"one\",\n })\n .alterTable(\"user\", (t) => {\n return t.createIndex(\"idx_user_createdAt\", [\"createdAt\"]);\n });\n});\n","// Password hashing utilities using WebCrypto\nexport async function hashPassword(password: string): Promise<string> {\n const encoder = new TextEncoder();\n const salt = crypto.getRandomValues(new Uint8Array(16));\n const iterations = 100000;\n\n const keyMaterial = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(password),\n \"PBKDF2\",\n false,\n [\"deriveBits\"],\n );\n\n const hashBuffer = await crypto.subtle.deriveBits(\n {\n name: \"PBKDF2\",\n salt: salt,\n iterations: iterations,\n hash: \"SHA-256\",\n },\n keyMaterial,\n 256,\n );\n\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const saltArray = Array.from(salt);\n\n return `${saltArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\")}:${iterations}:${hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\nexport async function verifyPassword(password: string, storedHash: string): Promise<boolean> {\n const parts = storedHash.split(\":\");\n if (parts.length !== 3) {\n return false;\n }\n\n const [saltHex, iterationsStr, hashHex] = parts;\n const iterations = Number.parseInt(iterationsStr, 10);\n const isHex = (value: string) => /^[0-9a-f]+$/i.test(value) && value.length % 2 === 0;\n\n if (!saltHex || !hashHex || !isHex(saltHex) || !isHex(hashHex)) {\n return false;\n }\n\n if (!Number.isFinite(iterations) || iterations <= 0) {\n return false;\n }\n\n const saltPairs = saltHex.match(/.{1,2}/g);\n const hashPairs = hashHex.match(/.{1,2}/g);\n\n if (!saltPairs || !hashPairs) {\n return false;\n }\n\n const salt = new Uint8Array(saltPairs.map((byte) => Number.parseInt(byte, 16)));\n const storedHashBytes = new Uint8Array(hashPairs.map((byte) => Number.parseInt(byte, 16)));\n\n const encoder = new TextEncoder();\n const keyMaterial = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(password),\n \"PBKDF2\",\n false,\n [\"deriveBits\"],\n );\n\n const hashBuffer = await crypto.subtle.deriveBits(\n {\n name: \"PBKDF2\",\n salt: salt,\n iterations: iterations,\n hash: \"SHA-256\",\n },\n keyMaterial,\n 256,\n );\n\n const hashArray = new Uint8Array(hashBuffer);\n\n if (hashArray.length !== storedHashBytes.length) {\n return false;\n }\n\n let isEqual = true;\n for (let i = 0; i < hashArray.length; i++) {\n if (hashArray[i] !== storedHashBytes[i]) {\n isEqual = false;\n }\n }\n return isEqual;\n}\n","/**\n * Cookie utilities for session management\n */\n\nexport const COOKIE_NAME = \"sessionid\";\nconst MAX_AGE = 2592000; // 30 days in seconds\n\nexport interface CookieOptions {\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n maxAge?: number;\n path?: string;\n}\n\n/**\n * Parse cookies from a Cookie header string\n */\nexport function parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) {\n return {};\n }\n\n const cookies: Record<string, string> = {};\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const [key, ...valueParts] = pair.split(\"=\");\n const trimmedKey = key?.trim();\n const value = valueParts.join(\"=\").trim();\n\n if (trimmedKey) {\n cookies[trimmedKey] = decodeURIComponent(value);\n }\n }\n\n return cookies;\n}\n\n/**\n * Build a Set-Cookie header string with security attributes\n */\nexport function buildSetCookieHeader(value: string, options: CookieOptions = {}): string {\n const {\n httpOnly = true,\n secure = true,\n sameSite = \"Strict\",\n maxAge = MAX_AGE,\n path = \"/\",\n } = options;\n const effectiveSecure = sameSite === \"None\" ? true : secure;\n\n const parts = [\n `${COOKIE_NAME}=${encodeURIComponent(value)}`,\n `Max-Age=${maxAge}`,\n `Path=${path}`,\n ];\n\n if (httpOnly) {\n parts.push(\"HttpOnly\");\n }\n\n if (effectiveSecure) {\n parts.push(\"Secure\");\n }\n\n if (sameSite) {\n parts.push(`SameSite=${sameSite}`);\n }\n\n return parts.join(\"; \");\n}\n\n/**\n * Build a Set-Cookie header to clear the session cookie\n */\nexport function buildClearCookieHeader(options: CookieOptions = {}): string {\n return buildSetCookieHeader(\"\", { ...options, maxAge: 0 });\n}\n\n/**\n * Extract session ID from headers, checking cookies first, then query/body\n */\nexport function extractSessionId(\n headers: Headers,\n queryParam?: string | null,\n bodySessionId?: string,\n): string | null {\n // First, try to get from cookies\n const cookieHeader = headers.get(\"Cookie\");\n const cookies = parseCookies(cookieHeader);\n const sessionIdFromCookie = cookies[COOKIE_NAME];\n\n if (sessionIdFromCookie) {\n return sessionIdFromCookie;\n }\n\n // Fall back to query parameter\n if (queryParam) {\n return queryParam;\n }\n\n // Fall back to body\n if (bodySessionId) {\n return bodySessionId;\n }\n\n return null;\n}\n","import { defineRoute, defineRoutes } from \"@fragno-dev/core\";\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\nimport { authSchema } from \"../schema\";\nimport { z } from \"zod\";\nimport { hashPassword, verifyPassword } from \"./password\";\nimport { buildSetCookieHeader, extractSessionId } from \"../utils/cookie\";\nimport type { authFragmentDefinition } from \"..\";\n\ntype AuthServiceContext = DatabaseServiceContext<{}>;\n\nexport function createUserServices() {\n return {\n createUser: function (\n this: AuthServiceContext,\n email: string,\n passwordHash: string,\n role: \"user\" | \"admin\" = \"user\",\n ) {\n return this.serviceTx(authSchema)\n .mutate(({ uow }) => {\n const id = uow.create(\"user\", {\n email,\n passwordHash,\n role,\n });\n return {\n id: id.valueOf(),\n email,\n role,\n };\n })\n .build();\n },\n getUserByEmail: function (this: AuthServiceContext, email: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"user\", (b) =>\n b.whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"=\", email)),\n ),\n )\n .transformRetrieve(([user]) =>\n user\n ? {\n id: user.id.valueOf(),\n email: user.email,\n passwordHash: user.passwordHash,\n role: user.role as \"user\" | \"admin\",\n }\n : null,\n )\n .build();\n },\n updateUserRole: function (this: AuthServiceContext, userId: string, role: \"user\" | \"admin\") {\n return this.serviceTx(authSchema)\n .mutate(({ uow }) => {\n uow.update(\"user\", userId, (b) => b.set({ role }));\n return { success: true };\n })\n .build();\n },\n updateUserPassword: function (this: AuthServiceContext, userId: string, passwordHash: string) {\n return this.serviceTx(authSchema)\n .mutate(({ uow }) => {\n uow.update(\"user\", userId, (b) => b.set({ passwordHash }));\n return { success: true };\n })\n .build();\n },\n signUpWithSession: function (this: AuthServiceContext, email: string, passwordHash: string) {\n const expiresAt = new Date();\n expiresAt.setDate(expiresAt.getDate() + 30); // 30 days from now\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"user\", (b) =>\n b.whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"=\", email)),\n ),\n )\n .mutate(({ uow, retrieveResult: [existingUser] }) => {\n if (existingUser) {\n return { ok: false as const, code: \"email_already_exists\" as const };\n }\n\n const userId = uow.create(\"user\", {\n email,\n passwordHash,\n role: \"user\",\n });\n\n const sessionId = uow.create(\"session\", {\n userId,\n expiresAt,\n });\n\n return {\n ok: true as const,\n sessionId: sessionId.valueOf(),\n userId: userId.valueOf(),\n email,\n role: \"user\" as const,\n };\n })\n .build();\n },\n updateUserRoleWithSession: function (\n this: AuthServiceContext,\n sessionId: string,\n userId: string,\n role: \"user\" | \"admin\",\n ) {\n const now = new Date();\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId))\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\"]))),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }) => {\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (session.expiresAt < now) {\n uow.delete(\"session\", session.id, (b) => b.check());\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (session.sessionOwner.role !== \"admin\") {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n uow.update(\"user\", userId, (b) => b.set({ role }));\n return { ok: true as const };\n })\n .build();\n },\n changePasswordWithSession: function (\n this: AuthServiceContext,\n sessionId: string,\n passwordHash: string,\n ) {\n const now = new Date();\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId))\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\"]))),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }) => {\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (session.expiresAt < now) {\n uow.delete(\"session\", session.id, (b) => b.check());\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n uow.update(\"user\", session.sessionOwner.id, (b) => b.set({ passwordHash }).check());\n return { ok: true as const };\n })\n .build();\n },\n };\n}\n\nexport const userActionsRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ services, config }) => {\n return [\n defineRoute({\n method: \"PATCH\",\n path: \"/users/:userId/role\",\n inputSchema: z.object({\n role: z.enum([\"user\", \"admin\"]),\n }),\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"invalid_input\", \"session_invalid\", \"permission_denied\"],\n handler: async function ({ input, pathParams, headers, query }, { json, error }) {\n const { role } = await input.valid();\n const { userId } = pathParams;\n\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.updateUserRoleWithSession(sessionId, userId, role)])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"permission_denied\") {\n return error({ message: \"Unauthorized\", code: \"permission_denied\" }, 401);\n }\n\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({ success: true });\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/sign-up\",\n inputSchema: z.object({\n email: z.email(),\n password: z.string().min(8).max(100),\n }),\n outputSchema: z.object({\n sessionId: z.string(),\n userId: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n }),\n errorCodes: [\"email_already_exists\", \"invalid_input\"],\n handler: async function ({ input }, { json, error }) {\n const { email, password } = await input.valid();\n\n const passwordHash = await hashPassword(password);\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.signUpWithSession(email, passwordHash)])\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Email already exists\", code: \"email_already_exists\" }, 400);\n }\n\n // Build response with Set-Cookie header\n const setCookieHeader = buildSetCookieHeader(result.sessionId, config.cookieOptions);\n\n return json(\n {\n sessionId: result.sessionId,\n userId: result.userId,\n email: result.email,\n role: result.role,\n },\n {\n headers: {\n \"Set-Cookie\": setCookieHeader,\n },\n },\n );\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/sign-in\",\n inputSchema: z.object({\n email: z.email(),\n password: z.string().min(8).max(100),\n }),\n outputSchema: z.object({\n sessionId: z.string(),\n userId: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n }),\n errorCodes: [\"invalid_credentials\"],\n handler: async function ({ input }, { json, error }) {\n const { email, password } = await input.valid();\n\n // Get user by email\n const [user] = await this.handlerTx()\n .withServiceCalls(() => [services.getUserByEmail(email)])\n .execute();\n if (!user) {\n return error({ message: \"Invalid credentials\", code: \"invalid_credentials\" }, 401);\n }\n\n // Verify password\n const isValid = await verifyPassword(password, user.passwordHash);\n if (!isValid) {\n return error({ message: \"Invalid credentials\", code: \"invalid_credentials\" }, 401);\n }\n\n // Create session\n const [session] = await this.handlerTx()\n .withServiceCalls(() => [services.createSession(user.id)])\n .execute();\n\n // Build response with Set-Cookie header\n const setCookieHeader = buildSetCookieHeader(session.id, config.cookieOptions);\n\n return json(\n {\n sessionId: session.id,\n userId: user.id,\n email: user.email,\n role: user.role,\n },\n {\n headers: {\n \"Set-Cookie\": setCookieHeader,\n },\n },\n );\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/change-password\",\n inputSchema: z.object({\n newPassword: z.string().min(8).max(100),\n }),\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"session_invalid\"],\n handler: async function ({ input, headers, query }, { json, error }) {\n const { newPassword } = await input.valid();\n\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const passwordHash = await hashPassword(newPassword);\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.changePasswordWithSession(sessionId, passwordHash)])\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({ success: true });\n },\n }),\n ];\n },\n);\n","import { defineRoute, defineRoutes } from \"@fragno-dev/core\";\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\nimport { authSchema } from \"../schema\";\nimport { z } from \"zod\";\nimport {\n buildClearCookieHeader,\n buildSetCookieHeader,\n extractSessionId,\n type CookieOptions,\n} from \"../utils/cookie\";\nimport type { Role, authFragmentDefinition } from \"..\";\n\ntype AuthServiceContext = DatabaseServiceContext<{}>;\n\nexport function createSessionServices(cookieOptions?: CookieOptions) {\n const services = {\n buildSessionCookie: function (sessionId: string): string {\n return buildSetCookieHeader(sessionId, cookieOptions);\n },\n createSession: function (this: AuthServiceContext, userId: string) {\n const expiresAt = new Date();\n expiresAt.setDate(expiresAt.getDate() + 30); // 30 days from now\n\n return this.serviceTx(authSchema)\n .mutate(({ uow }) => {\n const id = uow.create(\"session\", {\n userId,\n expiresAt,\n });\n\n return {\n id: id.valueOf(),\n userId,\n expiresAt,\n };\n })\n .build();\n },\n validateSession: function (this: AuthServiceContext, sessionId: string) {\n const now = new Date();\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId))\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\"]))),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }) => {\n if (!session) {\n return null;\n }\n\n // Check if session has expired\n if (session.expiresAt < now) {\n uow.delete(\"session\", session.id, (b) => b.check());\n return null;\n }\n\n if (!session.sessionOwner) {\n return null;\n }\n\n return {\n id: session.id.valueOf(),\n userId: session.userId as unknown as string,\n user: {\n id: session.sessionOwner.id.valueOf(),\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n },\n };\n })\n .build();\n },\n invalidateSession: function (this: AuthServiceContext, sessionId: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId)),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }) => {\n if (!session) {\n return false;\n }\n\n uow.delete(\"session\", session.id, (b) => b.check());\n return true;\n })\n .build();\n },\n getSession: function (this: AuthServiceContext, headers: Headers) {\n const sessionId = extractSessionId(headers);\n const now = new Date();\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId ?? \"\"))\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\"]))),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }) => {\n if (!session || !sessionId) {\n return undefined;\n }\n\n if (session.expiresAt < now) {\n uow.delete(\"session\", session.id, (b) => b.check());\n return undefined;\n }\n\n if (!session.sessionOwner) {\n return undefined;\n }\n\n return {\n userId: session.sessionOwner.id.valueOf(),\n email: session.sessionOwner.email,\n };\n })\n .build();\n },\n };\n return services;\n}\n\nexport const sessionRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ services, config }) => {\n return [\n defineRoute({\n method: \"POST\",\n path: \"/sign-out\",\n inputSchema: z\n .object({\n sessionId: z.string().optional(),\n })\n .optional(),\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"session_not_found\"],\n handler: async function ({ input, headers }, { json, error }) {\n const body = await input.valid();\n\n // Extract session ID from cookies first, then body\n const sessionId = extractSessionId(headers, null, body?.sessionId);\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_not_found\" }, 400);\n }\n\n const [success] = await this.handlerTx()\n .withServiceCalls(() => [services.invalidateSession(sessionId)])\n .execute();\n\n // Build response with clear cookie header\n const clearCookieHeader = buildClearCookieHeader(config.cookieOptions ?? {});\n\n if (!success) {\n // Still clear the cookie even if session not found in DB\n return json(\n { success: false },\n {\n headers: {\n \"Set-Cookie\": clearCookieHeader,\n },\n },\n );\n }\n\n return json(\n { success: true },\n {\n headers: {\n \"Set-Cookie\": clearCookieHeader,\n },\n },\n );\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/me\",\n queryParameters: [\"sessionId\"],\n outputSchema: z.object({\n userId: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n }),\n errorCodes: [\"session_invalid\"],\n handler: async function ({ query, headers }, { json, error }) {\n // Extract session ID from cookies first, then query params\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [session] = await this.handlerTx()\n .withServiceCalls(() => [services.validateSession(sessionId)])\n .execute();\n\n if (!session) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({\n userId: session.user.id,\n email: session.user.email,\n role: session.user.role as Role,\n });\n },\n }),\n ];\n },\n);\n","import { defineRoute, defineRoutes } from \"@fragno-dev/core\";\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\nimport { type Cursor, decodeCursor } from \"@fragno-dev/db/cursor\";\nimport { authSchema } from \"../schema\";\nimport { z } from \"zod\";\nimport type { authFragmentDefinition } from \"..\";\n\nexport type SortField = \"email\" | \"createdAt\";\nexport type SortOrder = \"asc\" | \"desc\";\n\nexport interface GetUsersParams {\n search?: string;\n sortBy: SortField;\n sortOrder: SortOrder;\n pageSize: number;\n cursor?: Cursor;\n}\n\nexport interface UserResult {\n id: string;\n email: string;\n role: \"user\" | \"admin\";\n createdAt: Date;\n}\n\ntype AuthServiceContext = DatabaseServiceContext<{}>;\n\nexport function createUserOverviewServices() {\n const mapUser = (user: {\n id: unknown;\n email: string;\n role: string;\n createdAt: Date;\n }): UserResult => ({\n id: String(user.id),\n email: user.email,\n role: user.role as \"user\" | \"admin\",\n createdAt: user.createdAt,\n });\n\n return {\n getUsersWithCursor: function (this: AuthServiceContext, params: GetUsersParams) {\n const { search, sortBy, sortOrder, pageSize, cursor } = params;\n\n // Determine which index to use based on search and sortBy\n // When searching, only email sorting is allowed (search uses email index)\n const effectiveSortBy: SortField = search ? \"email\" : sortBy;\n const indexName = effectiveSortBy === \"email\" ? \"idx_user_email\" : \"idx_user_createdAt\";\n\n // If cursor is provided, extract its metadata to ensure consistency\n const effectiveSortOrder = cursor ? cursor.orderDirection : sortOrder;\n const effectivePageSize = cursor ? cursor.pageSize : pageSize;\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findWithCursor(\"user\", (b) => {\n // When searching, we must filter by email and can only use the email index\n if (search) {\n const query = b\n .whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"contains\", search))\n .orderByIndex(\"idx_user_email\", effectiveSortOrder)\n .pageSize(effectivePageSize);\n\n // Add cursor for pagination continuation\n return cursor ? query.after(cursor) : query;\n }\n\n // When not searching, use the appropriate index for sorting\n const query = b\n .whereIndex(indexName)\n .orderByIndex(indexName, effectiveSortOrder)\n .pageSize(effectivePageSize);\n\n // Add cursor for pagination continuation\n return cursor ? query.after(cursor) : query;\n }),\n )\n .transformRetrieve(([result]) => ({\n users: result.items.map(mapUser),\n cursor: result.cursor,\n hasNextPage: result.hasNextPage,\n }))\n .build();\n },\n };\n}\n\nconst sortBySchema = z.enum([\"email\", \"createdAt\"]);\nconst sortOrderSchema = z.enum([\"asc\", \"desc\"]);\n\nexport const userOverviewRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ services }) => {\n const querySchema = z.object({\n search: z.string().optional(),\n sortBy: sortBySchema.default(\"createdAt\"),\n sortOrder: sortOrderSchema.default(\"desc\"),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n });\n\n const parseCursor = (cursorParam: string | null): Cursor | undefined => {\n if (!cursorParam) {\n return undefined;\n }\n try {\n return decodeCursor(cursorParam);\n } catch {\n return undefined;\n }\n };\n\n return [\n defineRoute({\n method: \"GET\",\n path: \"/users\",\n queryParameters: [\"search\", \"sortBy\", \"sortOrder\", \"pageSize\", \"cursor\"],\n outputSchema: z.object({\n users: z.array(\n z.object({\n id: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n createdAt: z.string(),\n }),\n ),\n cursor: z.string().optional(),\n hasNextPage: z.boolean(),\n sortBy: sortBySchema,\n }),\n errorCodes: [\"invalid_input\"],\n handler: async function ({ query }, { json, error }) {\n const parsed = querySchema.safeParse(Object.fromEntries(query.entries()));\n if (!parsed.success) {\n return error({ message: \"Invalid query parameters\", code: \"invalid_input\" }, 400);\n }\n\n const rawSearch = parsed.data.search?.trim();\n const search = rawSearch ? rawSearch : undefined;\n const sortBy: SortField = search ? \"email\" : parsed.data.sortBy;\n const params = {\n search,\n sortBy,\n sortOrder: parsed.data.sortOrder as SortOrder,\n pageSize: parsed.data.pageSize,\n };\n const cursor = parseCursor(query.get(\"cursor\"));\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.getUsersWithCursor({ ...params, cursor })])\n .execute();\n\n return json({\n users: result.users.map((user) => ({\n id: user.id,\n email: user.email,\n role: user.role,\n createdAt: user.createdAt.toISOString(),\n })),\n cursor: result.cursor?.encode(),\n hasNextPage: result.hasNextPage,\n sortBy: params.sortBy, // Return the actual sortBy used (may differ from requested)\n });\n },\n }),\n ];\n },\n);\n","import { defineFragment, instantiate } from \"@fragno-dev/core\";\nimport { createClientBuilder, type FragnoPublicClientConfig } from \"@fragno-dev/core/client\";\nimport { withDatabase, type FragnoPublicConfigWithDatabase } from \"@fragno-dev/db\";\nimport { authSchema } from \"./schema\";\nimport { createUserServices, userActionsRoutesFactory } from \"./user/user-actions\";\nimport { createSessionServices, sessionRoutesFactory } from \"./session/session\";\nimport {\n createUserOverviewServices,\n userOverviewRoutesFactory,\n type GetUsersParams,\n type UserResult,\n type SortField,\n type SortOrder,\n} from \"./user/user-overview\";\nimport type { CookieOptions } from \"./utils/cookie\";\n\nexport interface AuthConfig {\n sendEmail?: (params: { to: string; subject: string; body: string }) => Promise<void>;\n cookieOptions?: CookieOptions;\n}\n\nexport const authFragmentDefinition = defineFragment<AuthConfig>(\"auth\")\n .extend(withDatabase(authSchema))\n .providesBaseService(({ defineService, config }) => {\n return defineService({\n ...createUserServices(),\n ...createSessionServices(config.cookieOptions),\n ...createUserOverviewServices(),\n });\n })\n .build();\n\nexport type AuthFragment = typeof authFragmentDefinition;\n\nexport function createAuthFragment(\n config: AuthConfig = {},\n fragnoConfig: FragnoPublicConfigWithDatabase,\n) {\n const options = {\n ...fragnoConfig,\n // Preserve legacy namespace to avoid changing physical table names.\n databaseNamespace:\n fragnoConfig.databaseNamespace !== undefined\n ? fragnoConfig.databaseNamespace\n : \"simple-auth-db\",\n };\n\n return instantiate(authFragmentDefinition)\n .withConfig(config)\n .withOptions(options)\n .withRoutes([userActionsRoutesFactory, sessionRoutesFactory, userOverviewRoutesFactory])\n .build();\n}\n\nexport function createAuthFragmentClients(fragnoConfig?: FragnoPublicClientConfig) {\n // Note: Cookies are automatically sent for same-origin requests by the browser.\n // For cross-origin requests, you may need to configure CORS headers on the server.\n const config = { ...fragnoConfig };\n\n const b = createClientBuilder(\n authFragmentDefinition,\n config,\n [userActionsRoutesFactory, sessionRoutesFactory, userOverviewRoutesFactory],\n {\n type: \"options\",\n options: {\n credentials: \"include\",\n },\n },\n );\n\n const useMe = b.createHook(\"/me\");\n const useSignUp = b.createMutator(\"POST\", \"/sign-up\");\n const useSignIn = b.createMutator(\"POST\", \"/sign-in\");\n const useSignOut = b.createMutator(\"POST\", \"/sign-out\", (invalidate) => {\n invalidate(\"GET\", \"/me\", {});\n invalidate(\"GET\", \"/users\", {});\n });\n const useUsers = b.createHook(\"/users\");\n const useUpdateUserRole = b.createMutator(\"PATCH\", \"/users/:userId/role\", (invalidate) => {\n invalidate(\"GET\", \"/users\", {});\n invalidate(\"GET\", \"/me\", {});\n });\n const useChangePassword = b.createMutator(\"POST\", \"/change-password\");\n\n return {\n // Reactive hooks - Auth\n useSignUp,\n useSignIn,\n useSignOut,\n useMe,\n useUsers,\n useUpdateUserRole,\n useChangePassword,\n\n // Non-reactive methods\n signIn: {\n email: async ({\n email,\n password,\n rememberMe: _rememberMe,\n }: {\n email: string;\n password: string;\n rememberMe?: boolean;\n }) => {\n // Note: rememberMe is accepted but not yet implemented on the backend\n return useSignIn.mutateQuery({\n body: {\n email,\n password,\n },\n });\n },\n },\n\n signUp: {\n email: async ({ email, password }: { email: string; password: string }) => {\n return useSignUp.mutateQuery({\n body: {\n email,\n password,\n },\n });\n },\n },\n\n signOut: (params?: { sessionId?: string }) => {\n return useSignOut.mutateQuery({\n body: params?.sessionId ? { sessionId: params.sessionId } : {},\n });\n },\n\n me: async (params?: { sessionId?: string }) => {\n if (params?.sessionId) {\n return useMe.query({ query: { sessionId: params.sessionId } });\n }\n\n return useMe.query();\n },\n };\n}\n\nexport type { FragnoRouteConfig } from \"@fragno-dev/core/api\";\nexport type { GetUsersParams, UserResult, SortField, SortOrder };\n\nexport type Role = \"user\" | \"admin\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["storage?: StorageLike | null","win?: WindowLike | null","value: string | null | undefined","_accountId?: string","_accountId?: string | null","_accountId: string | null | undefined","organizationId: string","onChange: () => void","options?: { windowObject?: WindowLike | null }","e: Event","me: TMe","organizationId: string | null | undefined","entry: DefaultOrganizationEntry<TMe>","status: DefaultOrganizationResolutionStatus","storedId: string | null","storedOrganizationId: string | null","options: {\n meStore: DefaultOrganizationMeStore<TMe>;\n readMe: (params?: { sessionId?: string }) => Promise<TMe>;\n getAccountId?: (me: TMe) => string | null | undefined;\n storage?: StorageLike | null;\n windowObject?: WindowLike | null;\n}","id: string","resolution","value: string","roles: readonly TRole[] | undefined | null","fallback: readonly TRole[]","email: string","config: AutoCreateOrganizationConfig | undefined","ctx: { userId: string; email: string }","value: unknown","session?: SessionSeedInput | null","value: unknown","members: TMember[]","value: string | null","name: string","userId: string","uow: AuthUow","input: {\n userId: string;\n email: string;\n now: Date;\n options?: AutoCreateOrganizationOptions;\n }","user: UserSummaryInput","length: number","bytes: Uint8Array","params: {\n authorizationEndpoint: string;\n clientId: string;\n redirectURI: string;\n state: string;\n scopes?: string[];\n prompt?: string;\n loginHint?: string;\n codeChallenge?: string;\n codeChallengeMethod?: \"S256\" | \"plain\";\n extraParams?: Record<string, string | undefined>;\n}","parseScopes","scopeValue: unknown","value: unknown","response: Record<string, unknown>","response: Response","data: unknown","provider: AnyOAuthProvider","config?: AuthOAuthConfig","normalizedProviders: Record<string, AnyOAuthProvider>","normalizeMany","value: T | T[] | null | undefined","value: SessionSeedMemberRow | SessionSeedMemberRow[] | null | undefined","collectSessionSeedMembers","rows: Array<TUser | null | undefined>","value: string | number","value?: string | null","tokens: OAuth2Tokens","mode: AuthOAuthConfig[\"tokenStorage\"]","options: {\n oauth?: AuthOAuthConfig;\n autoCreateOptions?: AutoCreateOrganizationOptions;\n beforeCreateUser?: BeforeCreateUserHook;\n}","input: {\n providerId: string;\n redirectUri: string;\n returnTo?: string | null;\n sessionId?: string | null;\n link?: boolean;\n session?: SessionSeedInput | null;\n }","input: {\n providerId: string;\n state: string;\n tokens: OAuth2Tokens;\n userInfo: OAuth2UserInfo;\n rawProfile: Record<string, unknown> | null;\n provider?: AnyOAuthProvider;\n requestSignUp?: boolean;\n }","b","j","resolvedUser: {\n id: string;\n email: string;\n role: \"user\" | \"admin\";\n bannedAt?: Date | null;\n members: ReturnType<typeof mapSessionSeedMembers>;\n } | null","cookieHeader: string | null","cookies: Record<string, string>","value: string","options: CookieOptions","headers: Headers","queryParam?: string | null","bodySessionId?: string","value: string | null","provider: AnyOAuthProvider | undefined","fallback?: string","sessionId: string","organizationId: string","value: unknown","role: Role","roles: readonly string[]","role: string","mapOrganization","organization: OrganizationRow","invitation: InvitationRow","mapInvitationRow","organizationIdOverride?: unknown","resolveInternalId","value: unknown","normalizeMany","value: T | T[] | null | undefined","extractRoles","matchesOrganizationId","left: unknown","right: unknown","input: CreateInvitationInput","value: string","filterRolesForMemberId","roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }[]","member: { id?: unknown; _internalId?: unknown } | null","options: OrganizationInvitationServiceOptions","invitationId: string","invitation","params: { organizationId: string; status?: OrganizationInvitationStatus }","params: { email: string; status?: OrganizationInvitationStatus }","j","input: RespondInvitationInput","member","acceptedInvitation","params: ListInvitationsForSessionParams","invitations: Array<{\n invitation: OrganizationInvitation<string>;\n organization: Organization;\n }>","params: RespondInvitationWithSessionParams","b","params: ListOrganizationInvitationsWithSessionParams","params: CreateOrganizationInvitationWithSessionParams","mapOrganization","organization: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n}","mapMember","member: {\n id: unknown;\n organizationId: unknown;\n userId: unknown;\n createdAt: Date;\n updatedAt: Date;\n }","roles: string[]","overrides?: { organizationId?: string; userId?: string }","filterRolesForMemberId","roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }[]","member: { id?: unknown; _internalId?: unknown } | null","roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { organizationId: unknown } | null;\n }[]","organizationInternalId: unknown","resolveInternalId","value: unknown","normalizeMany","value: T | T[] | null | undefined","extractRoles","roles: Array<{\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }>","allowedMemberIds?: Set<string>","result: Record<string, string[]>","left: unknown","right: unknown","options: OrganizationMemberServiceOptions","params: { organizationId: string; userId: string }","input: CreateMemberInput","params: {\n organizationId: string;\n memberId: string;\n role: string;\n actor: { userId: string; userRole: Role };\n }","params: {\n organizationId: string;\n memberId: string;\n roles: readonly string[];\n actor: { userId: string; userRole: Role };\n }","params: {\n organizationId: string;\n memberId: string;\n actor: { userId: string; userRole: Role };\n }","params: { organizationId: string; pageSize: number; cursor?: Cursor }","memberId: string","memberIds: readonly string[]","rolesByMemberId: Record<string, string[]>","params: ListOrganizationMembersWithSessionParams","roles","params: CreateOrganizationMemberWithSessionParams","b","params: UpdateOrganizationMemberWithSessionParams","params: DeleteOrganizationMemberWithSessionParams","organization: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n organizationCreator?: { id?: unknown } | null;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n}","member: {\n id: unknown;\n organizationId: unknown;\n userId: unknown;\n createdAt: Date;\n updatedAt: Date;\n }","roles: string[]","overrides?: { organizationId?: string; userId?: string }","roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }[]","member: { id?: unknown; _internalId?: unknown } | null","value: unknown","normalizeMany","value: T | T[] | null | undefined","options: OrganizationServiceOptions","ctx: { userId: string; userRole: Role }","input: CreateOrganizationInput","organizationId: string","slug: string","patch: {\n name?: string;\n slug?: string;\n logoUrl?: string | null;\n metadata?: Record<string, unknown> | null;\n }","actor: { userId: string; userRole: Role }","params: { userId: string; pageSize: number; cursor?: Cursor }","j","params: CreateOrganizationWithSessionInput","b","member","memberId","params: GetOrganizationsForSessionParams","orderedMemberIds: string[]","params: GetActiveOrganizationForSessionParams","params: SetActiveOrganizationForSessionParams","params: GetOrganizationForSessionParams","params: UpdateOrganizationWithSessionParams","params: DeleteOrganizationWithSessionParams","value: unknown","organization: OrganizationLike","member: OrganizationMember<TRole>","invitation: OrganizationInvitation<TRole>","cursorParam: string | null","route: Parameters<typeof defineRoute>[0]","body: z.infer<typeof createOrganizationInputSchema> | null","inputError: unknown","services: Record<string, unknown>","normalizeMany","value: T | T[] | null | undefined","organization: OrganizationRow","member: OrganizationMemberRow","organizationId: string","userId: string","roles: string[]","invitation: OrganizationInvitationRow","rows: SessionMemberRow[]","rows: SessionInvitationRow[]","invitations: Array<{\n invitation: ReturnType<typeof serializeInvitationSummary>;\n organization: ReturnType<typeof serializeOrganization>;\n }>","cookieOptions?: CookieOptions","session?: SessionSeedInput | null","sessionId: string","options?: { activeOrganizationId?: string | null }","b","headers: Headers","expiredSession","password: string","storedHash: string","value: string","value: T | T[] | null | undefined","rows: TUser[]","options?: AutoCreateOrganizationOptions","beforeCreateUser?: BeforeCreateUserHook","email: string","role: \"user\" | \"admin\"","passwordHash: string","autoCreateOptions?: AutoCreateOrganizationOptions","userId: string","sessionId: string","b","passwordCheck:\n | { ok: true }\n | { ok: false; code: \"invalid_credentials\" | \"user_banned\" }\n | null","j","sessionId","user: {\n id: unknown;\n email: string;\n role: string;\n createdAt: Date;\n }","params: GetUsersParams","effectiveSortBy: SortField","query","parseCursor","cursorParam: string | null","sortBy: SortField","options?: {\n fetcher?: typeof fetch;\n userAgent?: string;\n}","accessToken: string","options: GithubOptions","token: OAuth2Tokens","mapOrganization","organization: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n organizationCreator?: { id?: unknown } | null;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n }","mapInvitation","invitation: {\n id: unknown;\n organizationId: unknown;\n email: string;\n roles: unknown;\n status: string;\n token: string;\n inviterId: unknown;\n expiresAt: Date;\n createdAt: Date;\n respondedAt: Date | null;\n }","j","config: AuthConfig","fragnoConfig: FragnoPublicConfigWithDatabase","fragnoConfig?: FragnoPublicClientConfig","params?: { sessionId?: string }","params: {\n provider: string;\n returnTo?: string;\n link?: boolean;\n sessionId?: string;\n session?: {\n activeOrganizationId?: string;\n };\n redirectUri?: string;\n scope?: string;\n loginHint?: string;\n }","params: {\n provider: string;\n code: string;\n state: string;\n requestSignUp?: boolean;\n }"],"sources":["../../src/client/default-organization.ts","../../src/schema.ts","../../src/organization/utils.ts","../../src/session/session-seed.ts","../../src/user/auto-organization.ts","../../src/user/summary.ts","../../src/utils/crypto.ts","../../src/oauth/utils.ts","../../src/oauth/oauth-services.ts","../../src/utils/cookie.ts","../../src/oauth/routes.ts","../../src/organization/active-organization.ts","../../src/organization/permissions.ts","../../src/organization/invitation-services.ts","../../src/organization/member-services.ts","../../src/organization/organization-services.ts","../../src/organization/schemas.ts","../../src/organization/serializers.ts","../../src/organization/routes.ts","../../src/session/session.ts","../../src/user/password.ts","../../src/user/user-actions.ts","../../src/user/user-overview.ts","../../src/oauth/providers/github/github.ts","../../src/index.ts"],"sourcesContent":["import { atom, computed, onMount, type ReadableAtom, type Store } from \"nanostores\";\n\nexport interface AuthMeLike {\n organizations: Array<{\n organization: {\n id: string;\n name: string;\n };\n member: {\n organizationId: string;\n };\n }>;\n activeOrganization: {\n organization: {\n id: string;\n name: string;\n };\n member: {\n organizationId: string;\n };\n } | null;\n}\n\nexport type DefaultOrganizationEntry<TMe extends AuthMeLike> = TMe[\"organizations\"][number];\nexport type DefaultOrganizationResolutionStatus = \"reused\" | \"initialized\" | \"repaired\";\nexport type DefaultOrganizationResolution<TMe extends AuthMeLike> = {\n status: DefaultOrganizationResolutionStatus;\n storedOrganizationId: string | null;\n resolvedOrganizationId: string;\n entry: DefaultOrganizationEntry<TMe>;\n organization: DefaultOrganizationEntry<TMe>[\"organization\"];\n member: DefaultOrganizationEntry<TMe>[\"member\"];\n};\n\nexport const DEFAULT_ORGANIZATION_STORAGE_KEY = \"fragno-auth.default-organization-id\";\nexport const DEFAULT_ORGANIZATION_CHANGE_EVENT = \"fragno-auth:default-organization-change\";\nexport const NO_ORGANIZATIONS_ERROR_MESSAGE =\n \"Authenticated users must always have at least one organization.\";\n\ntype StorageLike = Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\ntype WindowLike = Pick<Window, \"addEventListener\" | \"removeEventListener\" | \"dispatchEvent\">;\n\nexport type DefaultOrganizationMeStore<TMe extends AuthMeLike> = Store<{\n loading: boolean;\n error?: unknown;\n data?: TMe;\n}>;\n\nexport type DefaultOrganizationPreferenceStore<TMe extends AuthMeLike> = {\n storageKey: string | null;\n storedOrganizationId: ReadableAtom<string | null>;\n resolution: ReadableAtom<DefaultOrganizationResolution<TMe> | null>;\n status: ReadableAtom<DefaultOrganizationResolutionStatus | null>;\n defaultOrganizationId: ReadableAtom<string | null>;\n defaultOrganization: ReadableAtom<DefaultOrganizationEntry<TMe> | null>;\n me: ReadableAtom<TMe | null>;\n loading: ReadableAtom<boolean>;\n error: ReadableAtom<unknown>;\n readDefaultOrganizationId: () => string | null;\n writeDefaultOrganizationId: (organizationId: string) => boolean;\n clearDefaultOrganizationId: () => boolean;\n syncPreference: () => DefaultOrganizationResolution<TMe> | null;\n setDefaultOrganization: (organizationId: string) => DefaultOrganizationResolution<TMe>;\n};\n\nexport type DefaultOrganizationPreferenceState<TMe extends AuthMeLike> = {\n me: (params?: { sessionId?: string }) => Promise<TMe>;\n defaultOrganization: {\n storageKey: string | null;\n read: () => string | null;\n write: (organizationId: string) => boolean;\n clear: () => boolean;\n resolve: (me: TMe, storedOrganizationId: string | null) => DefaultOrganizationResolution<TMe>;\n sync: (me: TMe) => DefaultOrganizationResolution<TMe>;\n setForMe: (me: TMe, organizationId: string) => DefaultOrganizationResolution<TMe>;\n };\n store: DefaultOrganizationPreferenceStore<TMe>;\n};\n\nfunction getStorage(storage?: StorageLike | null): StorageLike | null {\n if (storage != null) {\n return storage;\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction getWindow(win?: WindowLike | null): WindowLike | null {\n if (win != null) {\n return win;\n }\n return typeof window !== \"undefined\" ? window : null;\n}\n\nfunction toNonEmptyString(value: string | null | undefined): string | null {\n const trimmed = value?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : null;\n}\n\nfunction readCurrentDefaultOrganizationId(storage?: StorageLike | null): string | null {\n const s = getStorage(storage);\n if (!s) {\n return null;\n }\n\n return toNonEmptyString(s.getItem(getDefaultOrganizationStorageKey()));\n}\n\nexport function getDefaultOrganizationStorageKey(_accountId?: string): string {\n return DEFAULT_ORGANIZATION_STORAGE_KEY;\n}\n\nexport function getDefaultOrganizationChangeEventName(_accountId?: string): string {\n return DEFAULT_ORGANIZATION_CHANGE_EVENT;\n}\n\nexport function readDefaultOrganizationId(\n _accountId?: string | null,\n storage?: StorageLike | null,\n): string | null {\n const s = getStorage(storage);\n if (!s) {\n return null;\n }\n\n try {\n return readCurrentDefaultOrganizationId(s);\n } catch {\n return null;\n }\n}\n\nexport function writeDefaultOrganizationId(\n _accountId: string | null | undefined,\n organizationId: string,\n storage?: StorageLike | null,\n win?: WindowLike | null,\n): boolean {\n const trimmed = toNonEmptyString(organizationId);\n if (!trimmed) {\n return clearDefaultOrganizationId(_accountId, storage, win);\n }\n\n const s = getStorage(storage);\n const storageKey = getDefaultOrganizationStorageKey();\n const eventName = getDefaultOrganizationChangeEventName();\n if (!s) {\n return false;\n }\n if (readCurrentDefaultOrganizationId(s) === trimmed) {\n return false;\n }\n\n try {\n s.setItem(storageKey, trimmed);\n } catch {\n return false;\n }\n\n getWindow(win)?.dispatchEvent(new Event(eventName));\n return true;\n}\n\nexport function clearDefaultOrganizationId(\n _accountId?: string | null,\n storage?: StorageLike | null,\n win?: WindowLike | null,\n): boolean {\n const s = getStorage(storage);\n const storageKey = getDefaultOrganizationStorageKey();\n const eventName = getDefaultOrganizationChangeEventName();\n if (!s) {\n return false;\n }\n\n if (!readCurrentDefaultOrganizationId(s)) {\n return false;\n }\n\n try {\n s.removeItem(storageKey);\n } catch {\n return false;\n }\n\n getWindow(win)?.dispatchEvent(new Event(eventName));\n return true;\n}\n\nexport function subscribeToDefaultOrganizationPreference(\n _accountId: string | null | undefined,\n onChange: () => void,\n options?: { windowObject?: WindowLike | null },\n): () => void {\n const win = getWindow(options?.windowObject);\n const storageKey = getDefaultOrganizationStorageKey();\n const eventName = getDefaultOrganizationChangeEventName();\n if (!win) {\n return () => {};\n }\n\n const handleChange = () => onChange();\n const handleStorage = (e: Event) => {\n if (typeof StorageEvent === \"undefined\") {\n return onChange();\n }\n if (e instanceof StorageEvent && (!e.key || e.key === storageKey)) {\n onChange();\n }\n };\n\n win.addEventListener(eventName, handleChange);\n win.addEventListener(\"storage\", handleStorage);\n return () => {\n win.removeEventListener(eventName, handleChange);\n win.removeEventListener(\"storage\", handleStorage);\n };\n}\n\nexport function findOrganizationEntry<TMe extends AuthMeLike>(\n me: TMe,\n organizationId: string | null | undefined,\n): DefaultOrganizationEntry<TMe> | null {\n const id = toNonEmptyString(organizationId);\n if (!id) {\n return null;\n }\n return me.organizations.find((e) => e.organization.id === id) ?? null;\n}\n\nfunction toResolution<TMe extends AuthMeLike>(\n entry: DefaultOrganizationEntry<TMe>,\n status: DefaultOrganizationResolutionStatus,\n storedId: string | null,\n): DefaultOrganizationResolution<TMe> {\n return {\n status,\n storedOrganizationId: storedId,\n resolvedOrganizationId: entry.organization.id,\n entry,\n organization: entry.organization,\n member: entry.member,\n };\n}\n\nexport function resolveDefaultOrganization<TMe extends AuthMeLike>(\n me: TMe,\n storedOrganizationId: string | null,\n): DefaultOrganizationResolution<TMe> {\n if (me.organizations.length === 0) {\n throw new Error(NO_ORGANIZATIONS_ERROR_MESSAGE);\n }\n\n const stored = findOrganizationEntry(me, storedOrganizationId);\n if (stored) {\n return toResolution(stored, \"reused\", storedOrganizationId);\n }\n\n const active = findOrganizationEntry(me, me.activeOrganization?.organization.id ?? null);\n const fallback = active ?? me.organizations[0];\n return toResolution(\n fallback,\n storedOrganizationId ? \"repaired\" : \"initialized\",\n storedOrganizationId,\n );\n}\n\nexport function syncDefaultOrganizationPreference<TMe extends AuthMeLike>(\n _accountId: string | null | undefined,\n me: TMe,\n storage?: StorageLike | null,\n win?: WindowLike | null,\n): DefaultOrganizationResolution<TMe> {\n const resolution = resolveDefaultOrganization(me, readDefaultOrganizationId(_accountId, storage));\n if (resolution.status !== \"reused\") {\n writeDefaultOrganizationId(_accountId, resolution.resolvedOrganizationId, storage, win);\n }\n return resolution;\n}\n\nexport function setDefaultOrganizationForMe<TMe extends AuthMeLike>(\n _accountId: string | null | undefined,\n me: TMe,\n organizationId: string,\n storage?: StorageLike | null,\n win?: WindowLike | null,\n): DefaultOrganizationResolution<TMe> {\n const entry = findOrganizationEntry(me, organizationId);\n if (!entry) {\n throw new Error(\"The selected organization is no longer available for this account.\");\n }\n writeDefaultOrganizationId(_accountId, entry.organization.id, storage, win);\n return resolveDefaultOrganization(me, entry.organization.id);\n}\n\nexport function createDefaultOrganizationPreferenceState<TMe extends AuthMeLike>(options: {\n meStore: DefaultOrganizationMeStore<TMe>;\n readMe: (params?: { sessionId?: string }) => Promise<TMe>;\n getAccountId?: (me: TMe) => string | null | undefined;\n storage?: StorageLike | null;\n windowObject?: WindowLike | null;\n}): DefaultOrganizationPreferenceState<TMe> {\n const { meStore, readMe, storage, windowObject } = options;\n const storageVersion = atom(0);\n\n const refresh = () => storageVersion.set(storageVersion.get() + 1);\n const getCurrentStorageKey = () => getDefaultOrganizationStorageKey();\n const storedOrganizationId = computed(storageVersion, () =>\n readDefaultOrganizationId(null, storage),\n );\n\n const write = (id: string) => {\n const ok = writeDefaultOrganizationId(null, id, storage, windowObject);\n if (ok) {\n refresh();\n }\n return ok;\n };\n\n const clear = () => {\n const ok = clearDefaultOrganizationId(null, storage, windowObject);\n if (ok) {\n refresh();\n }\n return ok;\n };\n\n const syncForMe = (me: TMe) => {\n const resolution = syncDefaultOrganizationPreference(null, me, storage, windowObject);\n refresh();\n return resolution;\n };\n\n const setForMe = (me: TMe, id: string) => {\n const entry = findOrganizationEntry(me, id);\n if (!entry) {\n throw new Error(\"The selected organization is no longer available for this account.\");\n }\n const resolution = setDefaultOrganizationForMe(null, me, id, storage, windowObject);\n refresh();\n return resolution;\n };\n\n onMount(storedOrganizationId, () =>\n subscribeToDefaultOrganizationPreference(null, refresh, { windowObject }),\n );\n\n const resolution = computed([meStore, storedOrganizationId], (meState, orgId) => {\n if (!meState.data) {\n return null;\n }\n return resolveDefaultOrganization(meState.data, orgId);\n });\n\n onMount(resolution, () =>\n resolution.listen((next) => {\n if (!next || next.status === \"reused\") {\n return;\n }\n if (writeDefaultOrganizationId(null, next.resolvedOrganizationId, storage, windowObject)) {\n refresh();\n }\n }),\n );\n\n const effectiveMe = computed([meStore, resolution], (meState) => meState.data ?? null);\n\n return {\n me: async (params) => {\n const me = await readMe(params);\n if (getWindow(windowObject)) {\n syncForMe(me);\n }\n return me;\n },\n defaultOrganization: {\n get storageKey() {\n return getCurrentStorageKey();\n },\n read: () => readDefaultOrganizationId(null, storage),\n write,\n clear,\n resolve: resolveDefaultOrganization,\n sync: syncForMe,\n setForMe,\n },\n store: {\n get storageKey() {\n return getCurrentStorageKey();\n },\n storedOrganizationId,\n resolution,\n status: computed(resolution, (r) => r?.status ?? null),\n defaultOrganizationId: computed(resolution, (r) => r?.resolvedOrganizationId ?? null),\n defaultOrganization: computed(resolution, (r) => r?.entry ?? null),\n me: effectiveMe,\n loading: computed(meStore, (s) => s.loading),\n error: computed(meStore, (s) => s.error),\n readDefaultOrganizationId: () => readDefaultOrganizationId(null, storage),\n writeDefaultOrganizationId: write,\n clearDefaultOrganizationId: clear,\n syncPreference: () => {\n const me = effectiveMe.get();\n return me ? syncForMe(me) : null;\n },\n setDefaultOrganization: (id) => {\n const me = effectiveMe.get();\n if (!me) {\n throw new Error(\"Cannot set a default organization without an authenticated user.\");\n }\n return setForMe(me, id);\n },\n },\n };\n}\n","import { column, idColumn, referenceColumn, schema } from \"@fragno-dev/db/schema\";\n\nexport const authSchema = schema(\"auth\", (s) => {\n return s\n .addTable(\"user\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"email\", column(\"string\"))\n .addColumn(\"passwordHash\", column(\"string\"))\n .addColumn(\"role\", column(\"string\").defaultTo(\"user\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_user_email\", [\"email\"])\n .createIndex(\"idx_user_id\", [\"id\"], { unique: true });\n })\n .addTable(\"session\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"userId\", referenceColumn())\n .addColumn(\"expiresAt\", column(\"timestamp\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_session_user\", [\"userId\"]);\n })\n .alterTable(\"user\", (t) => {\n return t\n .addColumn(\"bannedAt\", column(\"timestamp\").nullable())\n .createIndex(\"idx_user_createdAt\", [\"createdAt\"]);\n })\n .alterTable(\"session\", (t) => {\n return t.addColumn(\"activeOrganizationId\", referenceColumn().nullable());\n })\n .addTable(\"organization\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"name\", column(\"string\"))\n .addColumn(\"slug\", column(\"string\"))\n .addColumn(\"logoUrl\", column(\"string\").nullable())\n .addColumn(\"metadata\", column(\"json\").nullable())\n .addColumn(\"createdBy\", referenceColumn())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"deletedAt\", column(\"timestamp\").nullable())\n .createIndex(\"idx_organization_slug\", [\"slug\"], { unique: true })\n .createIndex(\"idx_organization_createdBy\", [\"createdBy\"]);\n })\n .addTable(\"organizationMember\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"organizationId\", referenceColumn())\n .addColumn(\"userId\", referenceColumn())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_org_member_org_user\", [\"organizationId\", \"userId\"], {\n unique: true,\n })\n .createIndex(\"idx_org_member_user\", [\"userId\"])\n .createIndex(\"idx_org_member_org\", [\"organizationId\"]);\n })\n .addTable(\"organizationMemberRole\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"memberId\", referenceColumn())\n .addColumn(\"role\", column(\"string\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_org_member_role_member_role\", [\"memberId\", \"role\"], {\n unique: true,\n })\n .createIndex(\"idx_org_member_role_member\", [\"memberId\"])\n .createIndex(\"idx_org_member_role_role\", [\"role\"]);\n })\n .addTable(\"organizationInvitation\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"organizationId\", referenceColumn())\n .addColumn(\"email\", column(\"string\"))\n .addColumn(\"roles\", column(\"json\"))\n .addColumn(\"status\", column(\"string\"))\n .addColumn(\"token\", column(\"string\"))\n .addColumn(\"inviterId\", referenceColumn())\n .addColumn(\"expiresAt\", column(\"timestamp\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"respondedAt\", column(\"timestamp\").nullable())\n .createIndex(\"idx_org_invitation_token\", [\"token\"], { unique: true })\n .createIndex(\"idx_org_invitation_org_status\", [\"organizationId\", \"status\"])\n .createIndex(\"idx_org_invitation_email\", [\"email\"])\n .createIndex(\"idx_org_invitation_email_status\", [\"email\", \"status\"]);\n })\n .addReference(\"sessionOwner\", {\n from: {\n table: \"session\",\n column: \"userId\",\n },\n to: {\n table: \"user\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"sessionActiveOrganization\", {\n from: {\n table: \"session\",\n column: \"activeOrganizationId\",\n },\n to: {\n table: \"organization\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"organizationCreator\", {\n from: {\n table: \"organization\",\n column: \"createdBy\",\n },\n to: {\n table: \"user\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"organizationMemberOrganization\", {\n from: {\n table: \"organizationMember\",\n column: \"organizationId\",\n },\n to: {\n table: \"organization\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"organizationMembers\", {\n from: {\n table: \"organization\",\n column: \"id\",\n },\n to: {\n table: \"organizationMember\",\n column: \"organizationId\",\n },\n type: \"many\",\n foreignKey: false,\n })\n .addReference(\"organizationMemberUser\", {\n from: {\n table: \"organizationMember\",\n column: \"userId\",\n },\n to: {\n table: \"user\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"organizationMemberRoleMember\", {\n from: {\n table: \"organizationMemberRole\",\n column: \"memberId\",\n },\n to: {\n table: \"organizationMember\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"organizationInvitationOrganization\", {\n from: {\n table: \"organizationInvitation\",\n column: \"organizationId\",\n },\n to: {\n table: \"organization\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"organizationInvitationInviter\", {\n from: {\n table: \"organizationInvitation\",\n column: \"inviterId\",\n },\n to: {\n table: \"user\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addTable(\"oauthAccount\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"userId\", referenceColumn())\n .addColumn(\"provider\", column(\"string\"))\n .addColumn(\"providerAccountId\", column(\"string\"))\n .addColumn(\"email\", column(\"string\").nullable())\n .addColumn(\"emailVerified\", column(\"bool\").defaultTo(false))\n .addColumn(\"image\", column(\"string\").nullable())\n .addColumn(\"accessToken\", column(\"string\").nullable())\n .addColumn(\"refreshToken\", column(\"string\").nullable())\n .addColumn(\"idToken\", column(\"string\").nullable())\n .addColumn(\"tokenType\", column(\"string\").nullable())\n .addColumn(\"tokenExpiresAt\", column(\"timestamp\").nullable())\n .addColumn(\"scopes\", column(\"json\").nullable())\n .addColumn(\"rawProfile\", column(\"json\").nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_oauth_account_provider_account\", [\"provider\", \"providerAccountId\"], {\n unique: true,\n })\n .createIndex(\"idx_oauth_account_user\", [\"userId\"])\n .createIndex(\"idx_oauth_account_provider\", [\"provider\"]);\n })\n .addTable(\"oauthState\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"provider\", column(\"string\"))\n .addColumn(\"state\", column(\"string\"))\n .addColumn(\"codeVerifier\", column(\"string\").nullable())\n .addColumn(\"redirectUri\", column(\"string\").nullable())\n .addColumn(\"returnTo\", column(\"string\").nullable())\n .addColumn(\"linkUserId\", referenceColumn().nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"expiresAt\", column(\"timestamp\"))\n .createIndex(\"idx_oauth_state_state\", [\"state\"], { unique: true })\n .createIndex(\"idx_oauth_state_provider\", [\"provider\"])\n .createIndex(\"idx_oauth_state_expiresAt\", [\"expiresAt\"]);\n })\n .addReference(\"oauthAccountUser\", {\n from: {\n table: \"oauthAccount\",\n column: \"userId\",\n },\n to: {\n table: \"user\",\n column: \"id\",\n },\n type: \"one\",\n })\n .addReference(\"oauthStateLinkUser\", {\n from: {\n table: \"oauthState\",\n column: \"linkUserId\",\n },\n to: {\n table: \"user\",\n column: \"id\",\n },\n type: \"one\",\n })\n .alterTable(\"user\", (t) => {\n return t.alterColumn(\"passwordHash\").nullable();\n })\n .addReference(\"sessionOrganizationMembers\", {\n type: \"many\",\n from: {\n table: \"session\",\n column: \"userId\",\n },\n to: {\n table: \"organizationMember\",\n column: \"userId\",\n },\n foreignKey: false,\n })\n .addReference(\"sessionMembers\", {\n type: \"many\",\n from: {\n table: \"session\",\n column: \"userId\",\n },\n to: {\n table: \"organizationMember\",\n column: \"userId\",\n },\n foreignKey: false,\n })\n .addReference(\"organizationMemberRoles\", {\n type: \"many\",\n from: {\n table: \"organizationMember\",\n // Join-only relations coerce `id` to internal ID.\n column: \"id\",\n },\n to: {\n table: \"organizationMemberRole\",\n column: \"memberId\",\n },\n foreignKey: false,\n })\n .addReference(\"roles\", {\n type: \"many\",\n from: {\n table: \"organizationMember\",\n // Join-only relations coerce `id` to internal ID.\n column: \"id\",\n },\n to: {\n table: \"organizationMemberRole\",\n column: \"memberId\",\n },\n foreignKey: false,\n })\n .addReference(\"organization\", {\n type: \"one\",\n from: {\n table: \"organizationMember\",\n column: \"organizationId\",\n },\n to: {\n table: \"organization\",\n column: \"id\",\n },\n foreignKey: false,\n })\n .addReference(\"userOrganizationInvitations\", {\n type: \"many\",\n from: {\n table: \"user\",\n column: \"email\",\n },\n to: {\n table: \"organizationInvitation\",\n column: \"email\",\n },\n foreignKey: false,\n })\n .addReference(\"invitations\", {\n type: \"many\",\n from: {\n table: \"user\",\n column: \"email\",\n },\n to: {\n table: \"organizationInvitation\",\n column: \"email\",\n },\n foreignKey: false,\n })\n .addReference(\"organization\", {\n type: \"one\",\n from: {\n table: \"organizationInvitation\",\n column: \"organizationId\",\n },\n to: {\n table: \"organization\",\n column: \"id\",\n },\n foreignKey: false,\n })\n .alterTable(\"session\", (t) => {\n return t.createIndex(\"idx_session_id_expiresAt\", [\"id\", \"expiresAt\"]);\n })\n .addReference(\"userOrganizationMembers\", {\n type: \"many\",\n from: {\n table: \"user\",\n column: \"id\",\n },\n to: {\n table: \"organizationMember\",\n column: \"userId\",\n },\n foreignKey: false,\n })\n .alterTable(\"oauthState\", (t) => {\n return t.addColumn(\"sessionSeed\", column(\"json\").nullable());\n });\n});\n","import type { AutoCreateOrganizationConfig, OrganizationRoleName } from \"./types\";\n\nexport const ORGANIZATION_SLUG_REGEX = /^[a-z0-9][a-z0-9-]{2,62}$/;\n\nexport const DEFAULT_CREATOR_ROLES = [\"owner\"] as const;\nexport const DEFAULT_MEMBER_ROLES = [\"member\"] as const;\n\nexport function slugifyOrganizationName(value: string): string {\n return value\n .toLowerCase()\n .trim()\n .replace(/['\"]/g, \"\")\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/--+/g, \"-\");\n}\n\nexport function normalizeOrganizationSlug(value: string): string | null {\n if (!value || !value.trim()) {\n return null;\n }\n const slug = slugifyOrganizationName(value);\n if (!ORGANIZATION_SLUG_REGEX.test(slug)) {\n return null;\n }\n return slug;\n}\n\nexport function normalizeRoleNames<TRole extends string>(\n roles: readonly TRole[] | undefined | null,\n fallback: readonly TRole[],\n): OrganizationRoleName<TRole>[] {\n const base = roles && roles.length > 0 ? roles : fallback;\n const unique = new Set(base.map((role) => String(role).trim()).filter(Boolean));\n return Array.from(unique) as OrganizationRoleName<TRole>[];\n}\n\nexport function buildDefaultOrganizationName(email: string): string {\n const localPart = email.split(\"@\")[0] ?? \"\";\n const safeLocalPart = localPart.trim() || \"user\";\n return `${safeLocalPart}'s Organization`;\n}\n\nexport function buildAutoOrganizationInput(\n config: AutoCreateOrganizationConfig | undefined,\n ctx: { userId: string; email: string },\n): {\n name: string;\n slug: string | null;\n logoUrl: string | null | undefined;\n metadata: Record<string, unknown> | null | undefined;\n} {\n const name = config?.name?.(ctx) ?? buildDefaultOrganizationName(ctx.email);\n const rawSlug = config?.slug?.(ctx) ?? name;\n return {\n name,\n slug: normalizeOrganizationSlug(rawSlug),\n logoUrl: config?.logoUrl?.(ctx),\n metadata: config?.metadata?.(ctx),\n };\n}\n\nexport function toExternalId(value: unknown): string {\n if (value && typeof value === \"object\" && \"externalId\" in value) {\n const externalId = (value as { externalId?: string }).externalId;\n if (externalId) {\n return externalId;\n }\n }\n return String(value);\n}\n","import { z } from \"zod\";\n\nimport { toExternalId } from \"../organization/utils\";\n\nexport const sessionSeedSchema = z\n .object({\n activeOrganizationId: z.string().trim().min(1).optional(),\n })\n .strict();\n\nexport type SessionSeedInput = z.input<typeof sessionSeedSchema>;\nexport type SessionSeed = z.output<typeof sessionSeedSchema>;\nexport type ResolvedSessionSeed = {\n status: \"accepted\" | \"ignored\" | \"repaired\";\n requestedActiveOrganizationId: string | null;\n activeOrganizationId: string | null;\n};\n\nexport function normalizeSessionSeed(session?: SessionSeedInput | null): SessionSeed | null {\n const parsed = sessionSeedSchema.safeParse(session ?? {});\n if (!parsed.success) {\n return null;\n }\n\n return parsed.data.activeOrganizationId ? parsed.data : null;\n}\n\nexport function parseSessionSeed(value: unknown): SessionSeed | null {\n const parsed = sessionSeedSchema.safeParse(value);\n if (!parsed.success) {\n return null;\n }\n\n return parsed.data.activeOrganizationId ? parsed.data : null;\n}\n\nexport function resolveSessionSeedFromMembers<\n TMember extends {\n createdAt: Date;\n organization: {\n id: unknown;\n deletedAt: Date | null;\n } | null;\n },\n>(members: TMember[], session?: SessionSeedInput | null): ResolvedSessionSeed {\n const normalizedSession = normalizeSessionSeed(session);\n const requestedActiveOrganizationId = normalizedSession?.activeOrganizationId ?? null;\n\n if (!requestedActiveOrganizationId) {\n return {\n status: \"ignored\",\n requestedActiveOrganizationId: null,\n activeOrganizationId: null,\n };\n }\n\n const validMembers = members\n .filter((member) => member.organization && !member.organization.deletedAt)\n .sort((left, right) => left.createdAt.getTime() - right.createdAt.getTime());\n const requestedMember =\n validMembers.find(\n (member) => toExternalId(member.organization!.id) === requestedActiveOrganizationId,\n ) ?? null;\n const repairedMember = requestedMember ?? validMembers[0] ?? null;\n\n return {\n status: requestedMember ? \"accepted\" : repairedMember ? \"repaired\" : \"ignored\",\n requestedActiveOrganizationId,\n activeOrganizationId: repairedMember ? toExternalId(repairedMember.organization!.id) : null,\n };\n}\n\nexport function parseSessionSeedFromQuery(value: string | null): SessionSeed | null | \"invalid\" {\n if (value === null) {\n return null;\n }\n if (value === \"\") {\n return \"invalid\";\n }\n\n try {\n const parsed = parseSessionSeed(JSON.parse(value));\n return parsed ?? \"invalid\";\n } catch {\n return \"invalid\";\n }\n}\n\nexport function serializeSessionSeedForQuery(\n session?: SessionSeedInput | null,\n): string | undefined {\n const normalized = normalizeSessionSeed(session);\n return normalized ? JSON.stringify(normalized) : undefined;\n}\n","import type { TypedUnitOfWork } from \"@fragno-dev/db\";\n\nimport type { AuthHooksMap } from \"../hooks\";\nimport type {\n AutoCreateOrganizationConfig,\n Organization,\n OrganizationMember,\n} from \"../organization/types\";\nimport {\n DEFAULT_CREATOR_ROLES,\n buildAutoOrganizationInput,\n normalizeOrganizationSlug,\n normalizeRoleNames,\n toExternalId,\n} from \"../organization/utils\";\nimport { authSchema } from \"../schema\";\n\nexport type AutoCreateOrganizationOptions = {\n autoCreateOrganization?: AutoCreateOrganizationConfig;\n creatorRoles?: readonly string[];\n};\n\nexport type AutoCreateOrganizationResult = {\n organization: Organization;\n member: OrganizationMember<string>;\n};\n\ntype AuthUow = TypedUnitOfWork<typeof authSchema, unknown[], unknown, AuthHooksMap>;\n\nconst resolveAutoOrganizationSlug = (name: string, userId: string): string => {\n const normalized = normalizeOrganizationSlug(name);\n if (normalized) {\n return normalized;\n }\n\n const fallback = normalizeOrganizationSlug(`org-${userId.slice(0, 8)}`);\n if (!fallback) {\n throw new Error(\"Invalid auto organization slug\");\n }\n return fallback;\n};\n\nexport const createAutoOrganization = (\n uow: AuthUow,\n input: {\n userId: string;\n email: string;\n now: Date;\n options?: AutoCreateOrganizationOptions;\n },\n): AutoCreateOrganizationResult | null => {\n if (!input.options?.autoCreateOrganization) {\n return null;\n }\n\n const { name, slug, logoUrl, metadata } = buildAutoOrganizationInput(\n input.options.autoCreateOrganization,\n {\n userId: input.userId,\n email: input.email,\n },\n );\n\n const normalizedSlug = slug ?? resolveAutoOrganizationSlug(name, input.userId);\n const creatorRoles = normalizeRoleNames(input.options.creatorRoles, DEFAULT_CREATOR_ROLES);\n\n const organizationId = uow.create(\"organization\", {\n name,\n slug: normalizedSlug,\n logoUrl: logoUrl ?? null,\n metadata: metadata ?? null,\n createdBy: input.userId,\n createdAt: input.now,\n updatedAt: input.now,\n });\n\n const memberId = uow.create(\"organizationMember\", {\n organizationId,\n userId: input.userId,\n createdAt: input.now,\n updatedAt: input.now,\n });\n\n for (const role of creatorRoles) {\n uow.create(\"organizationMemberRole\", {\n memberId,\n role,\n createdAt: input.now,\n });\n }\n\n return {\n organization: {\n id: toExternalId(organizationId),\n name,\n slug: normalizedSlug,\n logoUrl: logoUrl ?? null,\n metadata: metadata ?? null,\n createdBy: input.userId,\n createdAt: input.now,\n updatedAt: input.now,\n deletedAt: null,\n },\n member: {\n id: toExternalId(memberId),\n organizationId: toExternalId(organizationId),\n userId: input.userId,\n roles: creatorRoles,\n createdAt: input.now,\n updatedAt: input.now,\n },\n };\n};\n","import type { Role, UserSummary } from \"../types\";\n\ntype UserSummaryInput = {\n id: unknown;\n email: string;\n role: string;\n bannedAt?: Date | null;\n};\n\nexport const mapUserSummary = (user: UserSummaryInput): UserSummary => ({\n id: String(user.id),\n email: user.email,\n role: user.role as Role,\n bannedAt: user.bannedAt ?? null,\n});\n","const BASE64_TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nconst HEX_TABLE = \"0123456789abcdef\";\n\nfunction getCrypto() {\n const cryptoApi = globalThis.crypto;\n if (!cryptoApi || typeof cryptoApi.getRandomValues !== \"function\") {\n throw new Error(\"Web Crypto API is not available in this environment.\");\n }\n return cryptoApi;\n}\n\nexport function randomBytes(length: number): Uint8Array {\n if (!Number.isFinite(length) || length <= 0) {\n throw new Error(\"randomBytes length must be a positive number.\");\n }\n const bytes = new Uint8Array(length);\n getCrypto().getRandomValues(bytes);\n return bytes;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let output = \"\";\n let i = 0;\n\n for (; i + 2 < bytes.length; i += 3) {\n const chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];\n output +=\n BASE64_TABLE[(chunk >> 18) & 63] +\n BASE64_TABLE[(chunk >> 12) & 63] +\n BASE64_TABLE[(chunk >> 6) & 63] +\n BASE64_TABLE[chunk & 63];\n }\n\n const remaining = bytes.length - i;\n if (remaining === 1) {\n const chunk = bytes[i] << 16;\n output += BASE64_TABLE[(chunk >> 18) & 63] + BASE64_TABLE[(chunk >> 12) & 63] + \"==\";\n } else if (remaining === 2) {\n const chunk = (bytes[i] << 16) | (bytes[i + 1] << 8);\n output +=\n BASE64_TABLE[(chunk >> 18) & 63] +\n BASE64_TABLE[(chunk >> 12) & 63] +\n BASE64_TABLE[(chunk >> 6) & 63] +\n \"=\";\n }\n\n return output;\n}\n\nexport function bytesToBase64Url(bytes: Uint8Array): string {\n return bytesToBase64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let output = \"\";\n for (const byte of bytes) {\n output += HEX_TABLE[byte >> 4] + HEX_TABLE[byte & 15];\n }\n return output;\n}\n","import { bytesToBase64Url, randomBytes } from \"../utils/crypto\";\nimport type { AnyOAuthProvider, AuthOAuthConfig, OAuth2Tokens } from \"./types\";\n\nexport const DEFAULT_STATE_TTL_MS = 10 * 60 * 1000;\n\nexport const createOAuthState = (bytes = 32): string => {\n return bytesToBase64Url(randomBytes(bytes));\n};\n\nexport const createAuthorizationURL = (params: {\n authorizationEndpoint: string;\n clientId: string;\n redirectURI: string;\n state: string;\n scopes?: string[];\n prompt?: string;\n loginHint?: string;\n codeChallenge?: string;\n codeChallengeMethod?: \"S256\" | \"plain\";\n extraParams?: Record<string, string | undefined>;\n}): URL => {\n const url = new URL(params.authorizationEndpoint);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"client_id\", params.clientId);\n url.searchParams.set(\"redirect_uri\", params.redirectURI);\n url.searchParams.set(\"state\", params.state);\n\n if (params.scopes && params.scopes.length > 0) {\n url.searchParams.set(\"scope\", params.scopes.join(\" \"));\n }\n\n if (params.prompt) {\n url.searchParams.set(\"prompt\", params.prompt);\n }\n\n if (params.loginHint) {\n url.searchParams.set(\"login_hint\", params.loginHint);\n }\n\n if (params.codeChallenge) {\n url.searchParams.set(\"code_challenge\", params.codeChallenge);\n url.searchParams.set(\"code_challenge_method\", params.codeChallengeMethod ?? \"S256\");\n }\n\n if (params.extraParams) {\n for (const [key, value] of Object.entries(params.extraParams)) {\n if (typeof value === \"string\" && value.length > 0) {\n url.searchParams.set(key, value);\n }\n }\n }\n\n return url;\n};\n\nconst parseScopes = (scopeValue: unknown): string[] | undefined => {\n if (typeof scopeValue !== \"string\") {\n return undefined;\n }\n const scopes = scopeValue\n .split(/[,\\s]+/)\n .map((scope) => scope.trim())\n .filter(Boolean);\n return scopes.length > 0 ? scopes : undefined;\n};\n\nconst readNumber = (value: unknown): number | undefined => {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : undefined;\n }\n if (typeof value === \"string\") {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n};\n\nexport const normalizeOAuthTokens = (response: Record<string, unknown>): OAuth2Tokens => {\n const accessToken =\n typeof response[\"access_token\"] === \"string\" ? response[\"access_token\"] : undefined;\n const refreshToken =\n typeof response[\"refresh_token\"] === \"string\" ? response[\"refresh_token\"] : undefined;\n const tokenType = typeof response[\"token_type\"] === \"string\" ? response[\"token_type\"] : undefined;\n const idToken = typeof response[\"id_token\"] === \"string\" ? response[\"id_token\"] : undefined;\n\n const expiresIn = readNumber(response[\"expires_in\"]);\n const accessTokenExpiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1000) : undefined;\n\n return {\n accessToken,\n refreshToken,\n tokenType,\n idToken,\n accessTokenExpiresAt,\n scopes: parseScopes(response[\"scope\"]),\n raw: response,\n };\n};\n\nexport const parseOAuthTokenResponse = async (\n response: Response,\n): Promise<\n | {\n ok: true;\n data: Record<string, unknown>;\n }\n | {\n ok: false;\n status: number;\n error: string;\n data?: unknown;\n }\n> => {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const status = response.status;\n\n let data: unknown;\n try {\n if (contentType.includes(\"application/json\")) {\n data = await response.json();\n } else {\n const text = await response.text();\n data = Object.fromEntries(new URLSearchParams(text));\n }\n } catch (err) {\n return {\n ok: false,\n status,\n error: err instanceof Error ? err.message : \"Invalid token response\",\n };\n }\n\n if (!response.ok) {\n const message =\n typeof (data as { error_description?: string }).error_description === \"string\"\n ? (data as { error_description?: string }).error_description!\n : typeof (data as { error?: string }).error === \"string\"\n ? (data as { error?: string }).error!\n : `Token request failed with status ${status}`;\n return {\n ok: false,\n status,\n error: message,\n data,\n };\n }\n\n if (!data || typeof data !== \"object\") {\n return {\n ok: false,\n status,\n error: \"Token response was empty\",\n };\n }\n\n return {\n ok: true,\n data: data as Record<string, unknown>,\n };\n};\n\nexport const normalizeOAuthProvider = (provider: AnyOAuthProvider): AnyOAuthProvider => {\n const providerOptions = provider.options;\n if (!providerOptions) {\n return provider;\n }\n\n const disableSignUp = provider.disableSignUp ?? providerOptions.disableSignUp;\n const disableImplicitSignUp =\n provider.disableImplicitSignUp ?? providerOptions.disableImplicitSignUp;\n\n if (\n disableSignUp === provider.disableSignUp &&\n disableImplicitSignUp === provider.disableImplicitSignUp\n ) {\n return provider;\n }\n\n return {\n ...provider,\n disableSignUp,\n disableImplicitSignUp,\n };\n};\n\nexport const normalizeOAuthConfig = (config?: AuthOAuthConfig): AuthOAuthConfig | undefined => {\n if (!config) {\n return config;\n }\n\n const entries = Object.entries(config.providers);\n let changed = false;\n const normalizedProviders: Record<string, AnyOAuthProvider> = {};\n\n for (const [key, provider] of entries) {\n const normalized = normalizeOAuthProvider(provider);\n normalizedProviders[key] = normalized;\n if (normalized !== provider) {\n changed = true;\n }\n }\n\n if (!changed) {\n return config;\n }\n\n return {\n ...config,\n providers: normalizedProviders,\n };\n};\n","import type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport type { AuthHooksMap, BeforeCreateUserHook } from \"../hooks\";\nimport { authSchema } from \"../schema\";\nimport {\n normalizeSessionSeed,\n parseSessionSeed,\n resolveSessionSeedFromMembers,\n type SessionSeedInput,\n} from \"../session/session-seed\";\nimport {\n createAutoOrganization,\n type AutoCreateOrganizationOptions,\n} from \"../user/auto-organization\";\nimport { mapUserSummary } from \"../user/summary\";\nimport type { AnyOAuthProvider, AuthOAuthConfig, OAuth2Tokens, OAuth2UserInfo } from \"./types\";\nimport { createOAuthState, DEFAULT_STATE_TTL_MS, normalizeOAuthConfig } from \"./utils\";\n\nexport type OAuthStateResult =\n | {\n ok: true;\n state: string;\n redirectUri: string;\n returnTo: string | null;\n expiresAt: Date;\n }\n | {\n ok: false;\n code: \"session_invalid\";\n };\n\nexport type OAuthCallbackResult =\n | {\n ok: true;\n sessionId: string;\n userId: string;\n email: string;\n role: \"user\" | \"admin\";\n returnTo: string | null;\n }\n | {\n ok: false;\n code:\n | \"invalid_state\"\n | \"email_required\"\n | \"signup_disabled\"\n | \"signup_required\"\n | \"user_banned\";\n };\n\ntype AuthServiceContext = DatabaseServiceContext<AuthHooksMap>;\ntype SessionSeedMemberRow = {\n createdAt: Date;\n organizationMemberOrganization?: {\n id: unknown;\n deletedAt: Date | null;\n } | null;\n};\n\ntype SeedableUserRow = {\n id: { valueOf(): string };\n email: string;\n role: string;\n bannedAt?: Date | null;\n userOrganizationMembers?: SessionSeedMemberRow | SessionSeedMemberRow[] | null;\n};\n\nconst normalizeMany = <T>(value: T | T[] | null | undefined): T[] => {\n if (!value) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n};\n\nconst mapSessionSeedMembers = (\n value: SessionSeedMemberRow | SessionSeedMemberRow[] | null | undefined,\n) => {\n return normalizeMany(value).map((member) => ({\n createdAt: member.createdAt,\n organization: member.organizationMemberOrganization ?? null,\n }));\n};\n\nconst collectSessionSeedMembers = <\n TUser extends {\n userOrganizationMembers?: SessionSeedMemberRow | SessionSeedMemberRow[] | null;\n },\n>(\n rows: Array<TUser | null | undefined>,\n) => {\n return rows.flatMap((row) => (row ? mapSessionSeedMembers(row.userOrganizationMembers) : []));\n};\n\nconst toResolvedUser = <TUser extends SeedableUserRow>(rows: Array<TUser | null | undefined>) => {\n const first = rows.find((row): row is TUser => Boolean(row));\n if (!first) {\n return null;\n }\n\n return {\n id: first.id.valueOf(),\n email: first.email,\n role: first.role as \"user\" | \"admin\",\n bannedAt: first.bannedAt ?? null,\n members: collectSessionSeedMembers(rows),\n };\n};\n\nconst coerceProviderAccountId = (value: string | number): string => {\n return typeof value === \"string\" ? value : String(value);\n};\n\nconst sanitizeReturnTo = (value?: string | null): string | null => {\n if (!value) {\n return null;\n }\n if (value.startsWith(\"/\") && !value.startsWith(\"//\")) {\n return value;\n }\n return null;\n};\n\nconst resolveTokenStorage = (\n tokens: OAuth2Tokens,\n mode: AuthOAuthConfig[\"tokenStorage\"],\n): {\n accessToken: string | null;\n refreshToken: string | null;\n idToken: string | null;\n tokenType: string | null;\n tokenExpiresAt: Date | null;\n scopes: string[] | null;\n} => {\n const storage = mode ?? \"none\";\n if (storage === \"none\") {\n return {\n accessToken: null,\n refreshToken: null,\n idToken: null,\n tokenType: null,\n tokenExpiresAt: null,\n scopes: null,\n };\n }\n\n if (storage === \"refresh\") {\n return {\n accessToken: null,\n refreshToken: tokens.refreshToken ?? null,\n idToken: null,\n tokenType: tokens.tokenType ?? null,\n tokenExpiresAt: null,\n scopes: tokens.scopes ?? null,\n };\n }\n\n return {\n accessToken: tokens.accessToken ?? null,\n refreshToken: tokens.refreshToken ?? null,\n idToken: tokens.idToken ?? null,\n tokenType: tokens.tokenType ?? null,\n tokenExpiresAt: tokens.accessTokenExpiresAt ?? null,\n scopes: tokens.scopes ?? null,\n };\n};\n\nexport function createOAuthServices(options: {\n oauth?: AuthOAuthConfig;\n autoCreateOptions?: AutoCreateOrganizationOptions;\n beforeCreateUser?: BeforeCreateUserHook;\n}) {\n const oauthConfig = normalizeOAuthConfig(options.oauth);\n\n return {\n /**\n * Create an OAuth state and persist it for the authorization redirect.\n */\n createOAuthState: function (\n this: AuthServiceContext,\n input: {\n providerId: string;\n redirectUri: string;\n returnTo?: string | null;\n sessionId?: string | null;\n link?: boolean;\n session?: SessionSeedInput | null;\n },\n ) {\n const ttlMs = oauthConfig?.stateTtlMs ?? DEFAULT_STATE_TTL_MS;\n const state = createOAuthState();\n const now = new Date();\n const expiresAt = new Date(now.getTime() + ttlMs);\n const returnTo = sanitizeReturnTo(input.returnTo);\n const sessionId = input.sessionId ?? \"\";\n const shouldLink = Boolean(input.link);\n const sessionSeed = normalizeSessionSeed(input.session);\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId)),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }): OAuthStateResult => {\n if (shouldLink) {\n if (!session) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (session.expiresAt < now) {\n uow.delete(\"session\", session.id, (b) => b.check());\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n }\n\n const linkUserId = shouldLink && session ? session.userId : null;\n\n uow.create(\"oauthState\", {\n provider: input.providerId,\n state,\n codeVerifier: null,\n redirectUri: input.redirectUri,\n returnTo,\n sessionSeed,\n linkUserId,\n createdAt: now,\n expiresAt,\n });\n\n return {\n ok: true as const,\n state,\n redirectUri: input.redirectUri,\n returnTo,\n expiresAt,\n };\n })\n .build();\n },\n\n /**\n * Handle the OAuth callback, linking or creating users and issuing a session.\n */\n handleOAuthCallback: function (\n this: AuthServiceContext,\n input: {\n providerId: string;\n state: string;\n tokens: OAuth2Tokens;\n userInfo: OAuth2UserInfo;\n rawProfile: Record<string, unknown> | null;\n provider?: AnyOAuthProvider;\n requestSignUp?: boolean;\n },\n ) {\n const linkByEmail = oauthConfig?.linkByEmail ?? true;\n const tokenStorage = oauthConfig?.tokenStorage ?? \"none\";\n const requestSignUp = input.requestSignUp ?? false;\n\n const providerAccountId = coerceProviderAccountId(input.userInfo.id);\n const email = input.userInfo.email ?? null;\n\n if (!email) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_state\", (eb) => eb(\"state\", \"=\", input.state)),\n ),\n )\n .mutate(({ uow, retrieveResult: [oauthState] }): OAuthCallbackResult => {\n if (!oauthState || oauthState.provider !== input.providerId) {\n return { ok: false as const, code: \"invalid_state\" as const };\n }\n\n uow.delete(\"oauthState\", oauthState.id, (b) => b.check());\n\n return { ok: false as const, code: \"email_required\" as const };\n })\n .build();\n }\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .find(\"oauthState\", (b) =>\n b\n .whereIndex(\"idx_oauth_state_state\", (eb) => eb(\"state\", \"=\", input.state))\n .join((j) =>\n j.oauthStateLinkUser((b) =>\n b\n .select([\"id\", \"email\", \"role\", \"bannedAt\"])\n .join((j) =>\n j[\"userOrganizationMembers\"]((member) =>\n member\n .select([\"createdAt\"])\n .join((j) =>\n j[\"organizationMemberOrganization\"]((organization) =>\n organization.select([\"id\", \"deletedAt\"]),\n ),\n ),\n ),\n ),\n ),\n ),\n )\n .find(\"oauthAccount\", (b) =>\n b\n .whereIndex(\"idx_oauth_account_provider_account\", (eb) =>\n eb.and(\n eb(\"provider\", \"=\", input.providerId),\n eb(\"providerAccountId\", \"=\", providerAccountId),\n ),\n )\n .join((j) =>\n j.oauthAccountUser((b) =>\n b\n .select([\"id\", \"email\", \"role\", \"bannedAt\"])\n .join((j) =>\n j[\"userOrganizationMembers\"]((member) =>\n member\n .select([\"createdAt\"])\n .join((j) =>\n j[\"organizationMemberOrganization\"]((organization) =>\n organization.select([\"id\", \"deletedAt\"]),\n ),\n ),\n ),\n ),\n ),\n ),\n )\n .find(\"user\", (b) =>\n b\n .whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"=\", email))\n .join((j) =>\n j[\"userOrganizationMembers\"]((member) =>\n member\n .select([\"createdAt\"])\n .join((j) =>\n j[\"organizationMemberOrganization\"]((organization) =>\n organization.select([\"id\", \"deletedAt\"]),\n ),\n ),\n ),\n ),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [oauthStates, oauthAccounts, usersByEmail],\n }): OAuthCallbackResult => {\n const now = new Date();\n const oauthState = oauthStates[0] ?? null;\n const oauthAccount = oauthAccounts[0] ?? null;\n\n if (!oauthState || oauthState.provider !== input.providerId) {\n return { ok: false as const, code: \"invalid_state\" as const };\n }\n\n if (oauthState.expiresAt < now) {\n uow.delete(\"oauthState\", oauthState.id, (b) => b.check());\n return { ok: false as const, code: \"invalid_state\" as const };\n }\n\n uow.delete(\"oauthState\", oauthState.id, (b) => b.check());\n\n const providerConfig = input.provider;\n if (!oauthAccount && providerConfig?.disableSignUp) {\n return { ok: false as const, code: \"signup_disabled\" as const };\n }\n\n const sessionSeed = parseSessionSeed(\n (oauthState as { sessionSeed?: unknown }).sessionSeed,\n );\n const linkedUser = toResolvedUser(\n oauthStates.map((state) => state.oauthStateLinkUser ?? null),\n );\n const accountUser = toResolvedUser(\n oauthAccounts.map((account) => account.oauthAccountUser ?? null),\n );\n const existingUserByEmail = toResolvedUser(usersByEmail);\n\n let resolvedUser: {\n id: string;\n email: string;\n role: \"user\" | \"admin\";\n bannedAt?: Date | null;\n members: ReturnType<typeof mapSessionSeedMembers>;\n } | null = null;\n let createdUser = false;\n\n if (accountUser) {\n resolvedUser = accountUser;\n } else if (linkedUser) {\n resolvedUser = linkedUser;\n } else if (\n linkByEmail &&\n existingUserByEmail &&\n input.userInfo.email &&\n input.userInfo.emailVerified === true\n ) {\n resolvedUser = existingUserByEmail;\n }\n\n if (!resolvedUser) {\n if (providerConfig?.disableImplicitSignUp && !requestSignUp) {\n return { ok: false as const, code: \"signup_required\" as const };\n }\n\n if (!email) {\n return { ok: false as const, code: \"email_required\" as const };\n }\n\n options.beforeCreateUser?.({ email, role: \"user\" });\n const userId = uow.create(\"user\", {\n email,\n passwordHash: null,\n role: \"user\",\n });\n\n resolvedUser = {\n id: userId.valueOf(),\n email,\n role: \"user\",\n bannedAt: null,\n members: [],\n };\n createdUser = true;\n }\n\n if (resolvedUser.bannedAt) {\n return { ok: false as const, code: \"user_banned\" as const };\n }\n\n const tokenPayload = resolveTokenStorage(input.tokens, tokenStorage);\n const oauthAccountInput = {\n provider: input.providerId,\n providerAccountId,\n email,\n emailVerified: input.userInfo.emailVerified,\n image: typeof input.userInfo.image === \"string\" ? input.userInfo.image : null,\n accessToken: tokenPayload.accessToken,\n refreshToken: tokenPayload.refreshToken,\n idToken: tokenPayload.idToken,\n tokenType: tokenPayload.tokenType,\n tokenExpiresAt: tokenPayload.tokenExpiresAt,\n scopes: tokenPayload.scopes,\n rawProfile: input.rawProfile ?? null,\n updatedAt: now,\n };\n\n if (oauthAccount) {\n uow.update(\"oauthAccount\", oauthAccount.id, (b) => b.set(oauthAccountInput).check());\n } else {\n uow.create(\"oauthAccount\", {\n ...oauthAccountInput,\n userId: resolvedUser.id,\n createdAt: now,\n });\n }\n\n const autoOrganization = createdUser\n ? createAutoOrganization(uow, {\n userId: resolvedUser.id,\n email: resolvedUser.email,\n now,\n options: options.autoCreateOptions,\n })\n : null;\n\n const userSummary = mapUserSummary({\n id: resolvedUser.id,\n email: resolvedUser.email,\n role: resolvedUser.role,\n bannedAt: resolvedUser.bannedAt ?? null,\n });\n\n if (createdUser) {\n uow.triggerHook(\"onUserCreated\", {\n user: userSummary,\n actor: userSummary,\n });\n }\n\n if (autoOrganization) {\n uow.triggerHook(\"onOrganizationCreated\", {\n organization: autoOrganization.organization,\n actor: userSummary,\n });\n uow.triggerHook(\"onMemberAdded\", {\n organization: autoOrganization.organization,\n member: autoOrganization.member,\n actor: userSummary,\n });\n }\n\n const resolvedSessionSeed = resolveSessionSeedFromMembers(\n resolvedUser.members,\n sessionSeed,\n );\n const activeOrganizationId =\n resolvedSessionSeed.activeOrganizationId ?? autoOrganization?.organization.id ?? null;\n const sessionExpiresAt = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);\n const sessionId = uow.create(\"session\", {\n userId: resolvedUser.id,\n activeOrganizationId,\n expiresAt: uow.now().plus({ days: 30 }),\n });\n\n uow.triggerHook(\"onSessionCreated\", {\n session: {\n id: sessionId.valueOf(),\n user: userSummary,\n expiresAt: sessionExpiresAt,\n activeOrganizationId,\n },\n actor: userSummary,\n });\n\n return {\n ok: true as const,\n sessionId: sessionId.valueOf(),\n userId: resolvedUser.id,\n email: resolvedUser.email,\n role: resolvedUser.role,\n returnTo: oauthState.returnTo ?? null,\n };\n },\n )\n .build();\n },\n };\n}\n","/**\n * Cookie utilities for session management\n */\n\nexport const COOKIE_NAME = \"sessionid\";\nconst MAX_AGE = 2592000; // 30 days in seconds\n\nexport interface CookieOptions {\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n maxAge?: number;\n path?: string;\n}\n\n/**\n * Parse cookies from a Cookie header string\n */\nexport function parseCookies(cookieHeader: string | null): Record<string, string> {\n if (!cookieHeader) {\n return {};\n }\n\n const cookies: Record<string, string> = {};\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const [key, ...valueParts] = pair.split(\"=\");\n const trimmedKey = key?.trim();\n const value = valueParts.join(\"=\").trim();\n\n if (trimmedKey) {\n cookies[trimmedKey] = decodeURIComponent(value);\n }\n }\n\n return cookies;\n}\n\n/**\n * Build a Set-Cookie header string with security attributes\n */\nexport function buildSetCookieHeader(value: string, options: CookieOptions = {}): string {\n const {\n httpOnly = true,\n secure = true,\n sameSite = \"Strict\",\n maxAge = MAX_AGE,\n path = \"/\",\n } = options;\n const effectiveSecure = sameSite === \"None\" ? true : secure;\n\n const parts = [\n `${COOKIE_NAME}=${encodeURIComponent(value)}`,\n `Max-Age=${maxAge}`,\n `Path=${path}`,\n ];\n\n if (httpOnly) {\n parts.push(\"HttpOnly\");\n }\n\n if (effectiveSecure) {\n parts.push(\"Secure\");\n }\n\n if (sameSite) {\n parts.push(`SameSite=${sameSite}`);\n }\n\n return parts.join(\"; \");\n}\n\n/**\n * Build a Set-Cookie header to clear the session cookie\n */\nexport function buildClearCookieHeader(options: CookieOptions = {}): string {\n return buildSetCookieHeader(\"\", { ...options, maxAge: 0 });\n}\n\n/**\n * Extract session ID from headers, checking cookies first, then query/body\n */\nexport function extractSessionId(\n headers: Headers,\n queryParam?: string | null,\n bodySessionId?: string,\n): string | null {\n // First, try to get from cookies\n const cookieHeader = headers.get(\"Cookie\");\n const cookies = parseCookies(cookieHeader);\n const sessionIdFromCookie = cookies[COOKIE_NAME];\n\n if (sessionIdFromCookie) {\n return sessionIdFromCookie;\n }\n\n // Fall back to query parameter\n if (queryParam) {\n return queryParam;\n }\n\n // Fall back to body\n if (bodySessionId) {\n return bodySessionId;\n }\n\n return null;\n}\n","import { z } from \"zod\";\n\nimport { defineRoute, defineRoutes } from \"@fragno-dev/core\";\n\nimport type { authFragmentDefinition } from \"..\";\nimport { parseSessionSeedFromQuery } from \"../session/session-seed\";\nimport { buildSetCookieHeader, extractSessionId } from \"../utils/cookie\";\nimport type { AnyOAuthProvider } from \"./types\";\nimport { normalizeOAuthConfig } from \"./utils\";\n\nconst parseScopes = (value: string | null): string[] | undefined => {\n if (!value) {\n return undefined;\n }\n const scopes = value\n .split(/[,\\s]+/)\n .map((scope) => scope.trim())\n .filter(Boolean);\n return scopes.length > 0 ? scopes : undefined;\n};\n\nconst resolveRedirectUri = (\n provider: AnyOAuthProvider | undefined,\n fallback?: string,\n): string | null => {\n const providerRedirect = provider?.options?.redirectURI;\n if (typeof providerRedirect === \"string\" && providerRedirect.length > 0) {\n return providerRedirect;\n }\n if (typeof fallback === \"string\" && fallback.length > 0) {\n return fallback;\n }\n return null;\n};\n\nexport const oauthRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ services, config }) => {\n const oauthConfig = normalizeOAuthConfig(config.oauth);\n\n return [\n defineRoute({\n method: \"GET\",\n path: \"/oauth/:provider/authorize\",\n queryParameters: [\n \"redirectUri\",\n \"returnTo\",\n \"link\",\n \"sessionId\",\n \"scope\",\n \"loginHint\",\n \"session\",\n ],\n outputSchema: z.object({\n url: z.string(),\n }),\n errorCodes: [\n \"oauth_disabled\",\n \"provider_not_found\",\n \"missing_redirect_uri\",\n \"redirect_uri_mismatch\",\n \"invalid_input\",\n \"session_invalid\",\n ],\n handler: async function ({ query, headers, pathParams }, { json, error }) {\n if (!oauthConfig) {\n return error({ message: \"OAuth is not configured\", code: \"oauth_disabled\" }, 400);\n }\n\n const providerId = pathParams.provider;\n const provider = oauthConfig.providers[providerId];\n if (!provider) {\n return error({ message: \"Unknown provider\", code: \"provider_not_found\" }, 404);\n }\n\n const redirectUri = resolveRedirectUri(provider, oauthConfig.defaultRedirectUri);\n if (!redirectUri) {\n return error({ message: \"Missing redirect URI\", code: \"missing_redirect_uri\" }, 400);\n }\n\n const requestedRedirect = query.get(\"redirectUri\");\n if (requestedRedirect && requestedRedirect !== redirectUri) {\n return error({ message: \"Redirect URI mismatch\", code: \"redirect_uri_mismatch\" }, 400);\n }\n\n const link = query.get(\"link\") === \"true\";\n const sessionId = link ? extractSessionId(headers, query.get(\"sessionId\")) : null;\n const sessionSeed = parseSessionSeedFromQuery(query.get(\"session\"));\n if (sessionSeed === \"invalid\") {\n return error({ message: \"Invalid session seed\", code: \"invalid_input\" }, 400);\n }\n\n const [stateResult] = await this.handlerTx()\n .withServiceCalls(() => [\n services.createOAuthState({\n providerId,\n redirectUri,\n returnTo: query.get(\"returnTo\"),\n sessionId,\n link,\n session: sessionSeed,\n }),\n ])\n .execute();\n\n if (!stateResult.ok) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n const scopes = parseScopes(query.get(\"scope\"));\n const loginHint = query.get(\"loginHint\") ?? undefined;\n const url = await provider.createAuthorizationURL({\n state: stateResult.state,\n redirectURI: redirectUri,\n scopes,\n loginHint,\n });\n\n return json({ url: url.toString() });\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/oauth/:provider/callback\",\n queryParameters: [\"code\", \"state\", \"requestSignUp\"],\n outputSchema: z.object({\n sessionId: z.string(),\n userId: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n returnTo: z.string().nullable(),\n }),\n errorCodes: [\n \"oauth_disabled\",\n \"provider_not_found\",\n \"missing_redirect_uri\",\n \"invalid_code\",\n \"invalid_state\",\n \"email_required\",\n \"signup_disabled\",\n \"signup_required\",\n \"user_banned\",\n ],\n handler: async function ({ query, pathParams }, { json, error }) {\n if (!oauthConfig) {\n return error({ message: \"OAuth is not configured\", code: \"oauth_disabled\" }, 400);\n }\n\n const providerId = pathParams.provider;\n const provider = oauthConfig.providers[providerId];\n if (!provider) {\n return error({ message: \"Unknown provider\", code: \"provider_not_found\" }, 404);\n }\n\n const code = query.get(\"code\");\n const state = query.get(\"state\");\n if (!code) {\n return error({ message: \"Missing code\", code: \"invalid_code\" }, 400);\n }\n if (!state) {\n return error({ message: \"Missing state\", code: \"invalid_state\" }, 400);\n }\n\n const redirectUri = resolveRedirectUri(provider, oauthConfig.defaultRedirectUri);\n if (!redirectUri) {\n return error({ message: \"Missing redirect URI\", code: \"missing_redirect_uri\" }, 400);\n }\n\n const tokens = await provider.validateAuthorizationCode({\n code,\n redirectURI: redirectUri,\n });\n if (!tokens) {\n return error({ message: \"Invalid code\", code: \"invalid_code\" }, 401);\n }\n\n const userInfo = await provider.getUserInfo(tokens);\n if (!userInfo) {\n return error({ message: \"Unable to load profile\", code: \"invalid_code\" }, 401);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.handleOAuthCallback({\n providerId,\n state,\n tokens,\n userInfo: userInfo.user,\n rawProfile: userInfo.data as Record<string, unknown>,\n provider,\n requestSignUp: query.get(\"requestSignUp\") === \"true\",\n }),\n ])\n .execute();\n\n if (!result.ok) {\n const status =\n result.code === \"invalid_state\"\n ? 400\n : result.code === \"email_required\"\n ? 400\n : result.code === \"signup_disabled\"\n ? 403\n : result.code === \"signup_required\"\n ? 403\n : result.code === \"user_banned\"\n ? 403\n : 400;\n return error({ message: \"OAuth failed\", code: result.code }, status);\n }\n\n const setCookieHeader = buildSetCookieHeader(result.sessionId, config.cookieOptions);\n\n if (result.returnTo) {\n return new Response(null, {\n status: 302,\n headers: {\n \"Set-Cookie\": setCookieHeader,\n Location: result.returnTo,\n },\n });\n }\n\n return json(\n {\n sessionId: result.sessionId,\n userId: result.userId,\n email: result.email,\n role: result.role,\n returnTo: result.returnTo,\n },\n {\n headers: {\n \"Set-Cookie\": setCookieHeader,\n },\n },\n );\n },\n }),\n ];\n },\n);\n","import type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport { authSchema } from \"../schema\";\nimport { toExternalId } from \"./utils\";\n\ntype AuthServiceContext = DatabaseServiceContext<{}>;\n\nexport function createActiveOrganizationServices() {\n return {\n /**\n * Set the active organization for a session if the user is a member.\n */\n setActiveOrganization: function (\n this: AuthServiceContext,\n sessionId: string,\n organizationId: string,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId)))\n .find(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org\", (eb) => eb(\"organizationId\", \"=\", organizationId)),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, members] }) => {\n if (!session) {\n return { ok: false as const, code: \"session_not_found\" as const };\n }\n\n const normalizeId = (value: unknown) => {\n if (value && typeof value === \"object\") {\n if (\"internalId\" in value) {\n return (value as { internalId?: unknown }).internalId;\n }\n if (\"externalId\" in value) {\n return (value as { externalId?: unknown }).externalId;\n }\n }\n return value;\n };\n const sessionUserId = normalizeId(session.userId);\n const isMember = members.some((member) => normalizeId(member.userId) === sessionUserId);\n if (!isMember) {\n return { ok: false as const, code: \"membership_not_found\" as const };\n }\n\n uow.update(\"session\", session.id, (b) =>\n b.set({ activeOrganizationId: organizationId }).check(),\n );\n\n return { ok: true as const };\n })\n .build();\n },\n\n /**\n * Get the active organization id for a session.\n */\n getActiveOrganization: function (this: AuthServiceContext, sessionId: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId))\n .join((j) => j.sessionActiveOrganization()),\n ),\n )\n .transformRetrieve(([session]) => {\n if (!session || !session.sessionActiveOrganization) {\n return { organizationId: null };\n }\n\n return { organizationId: toExternalId(session.sessionActiveOrganization.id) };\n })\n .build();\n },\n };\n}\n","import type { Role } from \"../types\";\n\nexport const OWNER_ROLE = \"owner\";\n// Organization-scoped admin role (distinct from the global Role = \"admin\").\nexport const ADMIN_ROLE = \"admin\";\n\nexport const isGlobalAdmin = (role: Role) => role === \"admin\";\n\nexport const hasRole = (roles: readonly string[], role: string) => roles.includes(role);\n\nexport const canManageOrganization = (roles: readonly string[]) =>\n hasRole(roles, OWNER_ROLE) || hasRole(roles, ADMIN_ROLE);\n\nexport const canDeleteOrganization = (roles: readonly string[]) => hasRole(roles, OWNER_ROLE);\n","import type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport type { AuthHooksMap } from \"../hooks\";\nimport { authSchema } from \"../schema\";\nimport type { Role } from \"../types\";\nimport { mapUserSummary } from \"../user/summary\";\nimport { bytesToHex, randomBytes } from \"../utils/crypto\";\nimport { canManageOrganization, isGlobalAdmin } from \"./permissions\";\nimport type {\n Organization,\n OrganizationConfig,\n OrganizationInvitation,\n OrganizationInvitationStatus,\n} from \"./types\";\nimport { DEFAULT_MEMBER_ROLES, normalizeRoleNames, toExternalId } from \"./utils\";\n\ntype AuthServiceContext = DatabaseServiceContext<AuthHooksMap>;\n\ntype CreateInvitationInput = {\n organizationId: string;\n email: string;\n roles?: readonly string[];\n inviterId: string;\n expiresAt?: Date;\n expiresInDays?: number;\n actor: { userId: string; userRole: Role };\n actorMemberId?: string;\n};\n\ntype RespondInvitationInput = {\n invitationId: string;\n action: \"accept\" | \"reject\" | \"cancel\";\n token?: string;\n actor: { userId: string; userRole: Role };\n organizationId?: string;\n actorMemberId?: string;\n};\n\ntype ListInvitationsForSessionParams = {\n sessionId: string;\n};\n\ntype RespondInvitationWithSessionParams = {\n sessionId: string;\n invitationId: string;\n action: \"accept\" | \"reject\" | \"cancel\";\n token?: string;\n};\n\ntype ListOrganizationInvitationsWithSessionParams = {\n sessionId: string;\n organizationId: string;\n};\n\ntype CreateOrganizationInvitationWithSessionParams = {\n sessionId: string;\n organizationId: string;\n email: string;\n roles?: readonly string[];\n};\n\ntype OrganizationInvitationServiceOptions = {\n organizationConfig?: OrganizationConfig<string>;\n};\n\ntype OrganizationRow = {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n organizationCreator?: { id?: unknown } | null;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n};\n\ntype InvitationRow = {\n id: unknown;\n organizationId: unknown;\n email: string;\n roles: unknown;\n status: string;\n token: string;\n inviterId: unknown;\n expiresAt: Date;\n createdAt: Date;\n respondedAt: Date | null;\n organization?: OrganizationRow | null;\n};\n\nconst mapOrganization = (organization: OrganizationRow): Organization => ({\n id: toExternalId(organization.id),\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: (organization.metadata ?? null) as Record<string, unknown> | null,\n createdBy: toExternalId(organization.organizationCreator?.id ?? organization.createdBy),\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n});\n\nconst mapInvitation = (invitation: InvitationRow): OrganizationInvitation<string> => ({\n id: toExternalId(invitation.id),\n organizationId: toExternalId(invitation.organizationId),\n email: invitation.email,\n roles: Array.isArray(invitation.roles) ? (invitation.roles as string[]) : [],\n status: invitation.status as OrganizationInvitationStatus,\n token: invitation.token,\n inviterId: toExternalId(invitation.inviterId),\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: invitation.respondedAt ?? null,\n});\n\nconst mapInvitationRow = (\n invitation: InvitationRow,\n organizationIdOverride?: unknown,\n): OrganizationInvitation<string> => ({\n id: toExternalId(invitation.id),\n organizationId: toExternalId(organizationIdOverride ?? invitation.organizationId),\n email: invitation.email,\n roles: Array.isArray(invitation.roles) ? (invitation.roles as string[]) : [],\n status: invitation.status as OrganizationInvitationStatus,\n token: invitation.token,\n inviterId: toExternalId(invitation.inviterId),\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: invitation.respondedAt ?? null,\n});\n\nconst resolveInternalId = (value: unknown): string | bigint | undefined => {\n if (value && typeof value === \"object\") {\n if (\"internalId\" in value) {\n return (value as { internalId?: bigint }).internalId;\n }\n if (\"databaseId\" in value) {\n return (value as { databaseId?: string | bigint }).databaseId;\n }\n }\n return undefined;\n};\n\nconst normalizeMany = <T>(value: T | T[] | null | undefined): T[] => {\n if (!value) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n};\n\nconst extractRoles = (value: unknown): string[] => {\n if (!value) {\n return [];\n }\n if (Array.isArray(value)) {\n return value.map((role) => (role as { role: string }).role);\n }\n if (typeof value === \"object\" && \"role\" in value) {\n return [(value as { role: string }).role];\n }\n return [];\n};\n\nconst matchesOrganizationId = (left: unknown, right: unknown): boolean => {\n const leftInternal = resolveInternalId(left);\n const rightInternal = resolveInternalId(right);\n if (leftInternal !== undefined && rightInternal !== undefined) {\n return String(leftInternal) === String(rightInternal);\n }\n return toExternalId(left) === toExternalId(right);\n};\n\nconst buildExpiresAt = (input: CreateInvitationInput): Date => {\n if (input.expiresAt) {\n return input.expiresAt;\n }\n const days = input.expiresInDays ?? 3;\n const expiresAt = new Date();\n expiresAt.setDate(expiresAt.getDate() + days);\n return expiresAt;\n};\n\nconst normalizeEmail = (value: string) => value.trim().toLowerCase();\n\nconst filterRolesForMemberId = (\n roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }[],\n member: { id?: unknown; _internalId?: unknown } | null,\n) => {\n if (!member) {\n return [];\n }\n const candidates = new Set([member.id, member._internalId].filter(Boolean).map(toExternalId));\n return roles\n .filter(\n (role) =>\n candidates.has(toExternalId(role.memberId)) ||\n (role.organizationMemberRoleMember &&\n candidates.has(toExternalId(role.organizationMemberRoleMember.id))),\n )\n .map((role) => role.role);\n};\n\nexport function createOrganizationInvitationServices(\n options: OrganizationInvitationServiceOptions = {},\n) {\n const limits = options.organizationConfig?.limits;\n const invitationExpiresInDays = options.organizationConfig?.invitationExpiresInDays;\n const defaultMemberRoles = options.organizationConfig?.defaultMemberRoles;\n return {\n /**\n * Fetch an invitation by id and include its organization.\n */\n getOrganizationInvitationById: function (this: AuthServiceContext, invitationId: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"organizationInvitation\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", invitationId))\n .join((j) => j.organizationInvitationOrganization()),\n ),\n )\n .transformRetrieve(([invitation]) =>\n invitation\n ? {\n invitation: mapInvitation({\n id: invitation.id,\n organizationId: invitation.organizationInvitationOrganization\n ? invitation.organizationInvitationOrganization.id\n : invitation.organizationId,\n email: invitation.email,\n roles: invitation.roles,\n status: invitation.status,\n token: invitation.token,\n inviterId: invitation.inviterId,\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: invitation.respondedAt,\n }),\n }\n : null,\n )\n .build();\n },\n\n /**\n * Create an organization invitation with permission checks.\n */\n createOrganizationInvitation: function (\n this: AuthServiceContext,\n input: CreateInvitationInput,\n ) {\n const roles = normalizeRoleNames(input.roles, defaultMemberRoles ?? DEFAULT_MEMBER_ROLES);\n const now = new Date();\n const token = bytesToHex(randomBytes(32));\n const actorMemberId = input.actorMemberId;\n const normalizedEmail = normalizeEmail(input.email);\n const expiresAt = buildExpiresAt({\n ...input,\n expiresInDays: input.expiresInDays ?? invitationExpiresInDays,\n });\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", input.organizationId),\n eb(\"userId\", \"=\", input.actor.userId),\n ),\n )\n .join((j) => j.organizationMemberOrganization()),\n )\n .find(\"organizationMemberRole\", (b) => {\n const scoped = actorMemberId\n ? b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", actorMemberId),\n )\n : b.whereIndex(\"primary\");\n return scoped.join((j) => j.organizationMemberRoleMember());\n })\n .find(\"organizationInvitation\", (b) =>\n b.whereIndex(\"idx_org_invitation_org_status\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", input.organizationId),\n eb(\"status\", \"=\", \"pending\"),\n ),\n ),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.actor.userId)),\n ),\n )\n .mutate(({ uow, retrieveResult: [actorMember, actorRoles, invitations, actorUser] }) => {\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoleNames = filterRolesForMemberId(actorRoles, actorMember);\n if (!isGlobalAdmin(input.actor.userRole) && !canManageOrganization(actorRoleNames)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const pendingInvitesForEmail = invitations.filter(\n (invitation) => normalizeEmail(invitation.email) === normalizedEmail,\n );\n const existingInvitation =\n pendingInvitesForEmail.length > 0\n ? pendingInvitesForEmail.reduce((latest, invitation) =>\n invitation.createdAt > latest.createdAt ? invitation : latest,\n )\n : null;\n\n const organization = actorMember.organizationMemberOrganization\n ? mapOrganization(actorMember.organizationMemberOrganization)\n : null;\n const actorSummary = actorUser ? mapUserSummary(actorUser) : null;\n\n if (existingInvitation) {\n for (const invitation of pendingInvitesForEmail) {\n if (invitation.id !== existingInvitation.id) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"canceled\", respondedAt: now }).check(),\n );\n }\n }\n\n uow.update(\"organizationInvitation\", existingInvitation.id, (b) =>\n b\n .set({\n organizationId: input.organizationId,\n email: input.email,\n roles,\n status: \"pending\",\n token,\n inviterId: input.inviterId,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n })\n .check(),\n );\n\n uow.triggerHook(\n \"onInvitationExpired\",\n { invitationId: toExternalId(existingInvitation.id) },\n { processAt: expiresAt },\n );\n\n const invitation = mapInvitation({\n id: existingInvitation.id,\n organizationId: input.organizationId,\n email: input.email,\n roles,\n status: \"pending\",\n token,\n inviterId: input.inviterId,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n });\n\n if (organization) {\n uow.triggerHook(\"onInvitationCreated\", {\n organization,\n invitation,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation,\n };\n }\n\n if (\n limits?.invitationsPerOrganization !== undefined &&\n invitations.length >= limits.invitationsPerOrganization\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const invitationId = uow.create(\"organizationInvitation\", {\n organizationId: input.organizationId,\n email: input.email,\n roles,\n status: \"pending\",\n token,\n inviterId: input.inviterId,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n });\n\n uow.triggerHook(\n \"onInvitationExpired\",\n { invitationId: toExternalId(invitationId) },\n { processAt: expiresAt },\n );\n\n const invitation = mapInvitation({\n id: invitationId,\n organizationId: input.organizationId,\n email: input.email,\n roles,\n status: \"pending\",\n token,\n inviterId: input.inviterId,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n });\n\n if (organization) {\n uow.triggerHook(\"onInvitationCreated\", {\n organization,\n invitation,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation,\n };\n })\n .build();\n },\n\n /**\n * List invitations for an organization, optionally by status.\n */\n listOrganizationInvitations: function (\n this: AuthServiceContext,\n params: { organizationId: string; status?: OrganizationInvitationStatus },\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.find(\"organizationInvitation\", (b) =>\n b.whereIndex(\"idx_org_invitation_org_status\", (eb) =>\n params.status\n ? eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"status\", \"=\", params.status),\n )\n : eb(\"organizationId\", \"=\", params.organizationId),\n ),\n ),\n )\n .transformRetrieve(([invitations]) => ({\n invitations: invitations.map(mapInvitation),\n }))\n .build();\n },\n\n /**\n * List invitations for an email address with organization details.\n */\n listOrganizationInvitationsForUser: function (\n this: AuthServiceContext,\n params: { email: string; status?: OrganizationInvitationStatus },\n ) {\n const { email, status } = params;\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.find(\"organizationInvitation\", (b) =>\n (status\n ? b.whereIndex(\"idx_org_invitation_email_status\", (eb) =>\n eb.and(eb(\"email\", \"=\", email), eb(\"status\", \"=\", status)),\n )\n : b.whereIndex(\"idx_org_invitation_email\", (eb) => eb(\"email\", \"=\", email))\n ).join((j) =>\n j.organizationInvitationOrganization((org) =>\n org.join((j) => j.organizationCreator()),\n ),\n ),\n ),\n )\n .transformRetrieve(([invitations]) => ({\n invitations: invitations.map((invitation) => ({\n invitation: mapInvitation({\n id: invitation.id,\n organizationId: invitation.organizationId,\n email: invitation.email,\n roles: invitation.roles,\n status: invitation.status,\n token: invitation.token,\n inviterId: invitation.inviterId,\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: invitation.respondedAt,\n }),\n organization:\n invitation.organizationInvitationOrganization &&\n invitation.organizationInvitationOrganization.deletedAt == null\n ? {\n id: toExternalId(invitation.organizationInvitationOrganization.id),\n name: invitation.organizationInvitationOrganization.name,\n slug: invitation.organizationInvitationOrganization.slug,\n logoUrl: invitation.organizationInvitationOrganization.logoUrl ?? null,\n metadata: invitation.organizationInvitationOrganization.metadata ?? null,\n createdBy: toExternalId(\n invitation.organizationInvitationOrganization.organizationCreator?.id ??\n invitation.organizationInvitationOrganization.createdBy,\n ),\n createdAt: invitation.organizationInvitationOrganization.createdAt,\n updatedAt: invitation.organizationInvitationOrganization.updatedAt,\n deletedAt: invitation.organizationInvitationOrganization.deletedAt ?? null,\n }\n : null,\n })),\n }))\n .build();\n },\n\n /**\n * Accept, reject, or cancel an invitation with validation and hooks.\n */\n respondToOrganizationInvitation: function (\n this: AuthServiceContext,\n input: RespondInvitationInput,\n ) {\n const now = new Date();\n const actorMemberId = input.actorMemberId;\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organizationInvitation\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.invitationId))\n .join((j) => j.organizationInvitationOrganization()),\n )\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", input.organizationId ?? \"\"),\n eb(\"userId\", \"=\", input.actor.userId),\n ),\n ),\n )\n .find(\"organizationMemberRole\", (b) => {\n const scoped = actorMemberId\n ? b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", actorMemberId),\n )\n : b.whereIndex(\"primary\");\n return scoped.join((j) => j.organizationMemberRoleMember());\n })\n .find(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", input.organizationId ?? \"\"),\n )\n .join((j) => j.organizationMemberUser()),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.actor.userId)),\n ),\n )\n .mutate(\n ({ uow, retrieveResult: [invitation, actorMember, actorRoles, members, actorUser] }) => {\n if (!invitation) {\n return { ok: false as const, code: \"invitation_not_found\" as const };\n }\n\n const status = invitation.status as OrganizationInvitationStatus;\n if (status !== \"pending\") {\n return {\n ok: false as const,\n code:\n status === \"expired\"\n ? (\"invitation_expired\" as const)\n : (\"invitation_not_found\" as const),\n };\n }\n\n if (input.action !== \"cancel\") {\n if (!input.token || input.token !== invitation.token) {\n return { ok: false as const, code: \"invalid_token\" as const };\n }\n\n if (invitation.expiresAt < now) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"expired\", respondedAt: now }).check(),\n );\n return { ok: false as const, code: \"invitation_expired\" as const };\n }\n\n const actorEmail = actorUser?.email;\n if (!actorEmail) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n if (normalizeEmail(actorEmail) !== normalizeEmail(invitation.email)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n }\n\n if (input.action === \"cancel\") {\n const actorRoleNames = filterRolesForMemberId(actorRoles, actorMember);\n const isInviter = toExternalId(invitation.inviterId) === input.actor.userId;\n const canCancel =\n isInviter ||\n isGlobalAdmin(input.actor.userRole) ||\n (actorMember && canManageOrganization(actorRoleNames));\n\n if (!canCancel) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n }\n\n const organization = invitation.organizationInvitationOrganization\n ? mapOrganization(invitation.organizationInvitationOrganization)\n : null;\n const actorSummary = actorUser ? mapUserSummary(actorUser) : null;\n const invitationRoles = Array.isArray(invitation.roles)\n ? (invitation.roles as string[])\n : [];\n\n if (input.action === \"accept\") {\n const existingMember =\n actorMember ??\n members.find(\n (member) =>\n member.organizationMemberUser &&\n toExternalId(member.organizationMemberUser.id) === input.actor.userId,\n );\n\n if (existingMember) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"accepted\", respondedAt: now }).check(),\n );\n\n const acceptedInvitation = mapInvitation({\n id: invitation.id,\n organizationId: invitation.organizationId,\n email: invitation.email,\n roles: invitation.roles,\n status: \"accepted\",\n token: invitation.token,\n inviterId: invitation.inviterId,\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: now,\n });\n\n if (organization) {\n uow.triggerHook(\"onInvitationAccepted\", {\n organization,\n invitation: acceptedInvitation,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation: acceptedInvitation,\n memberId: toExternalId(existingMember.id),\n };\n }\n\n if (\n limits?.membersPerOrganization !== undefined &&\n members.length >= limits.membersPerOrganization\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const memberId = uow.create(\"organizationMember\", {\n organizationId: invitation.organizationId,\n userId: input.actor.userId,\n createdAt: now,\n updatedAt: now,\n });\n\n for (const role of invitationRoles) {\n uow.create(\"organizationMemberRole\", {\n memberId,\n role,\n createdAt: now,\n });\n }\n\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"accepted\", respondedAt: now }).check(),\n );\n\n const acceptedInvitation = mapInvitation({\n id: invitation.id,\n organizationId: invitation.organizationId,\n email: invitation.email,\n roles: invitation.roles,\n status: \"accepted\",\n token: invitation.token,\n inviterId: invitation.inviterId,\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: now,\n });\n\n const member = {\n id: toExternalId(memberId),\n organizationId: organization?.id ?? toExternalId(invitation.organizationId),\n userId: input.actor.userId,\n roles: invitationRoles,\n createdAt: now,\n updatedAt: now,\n };\n\n if (organization) {\n uow.triggerHook(\"onInvitationAccepted\", {\n organization,\n invitation: acceptedInvitation,\n actor: actorSummary,\n });\n uow.triggerHook(\"onMemberAdded\", {\n organization,\n member,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation: acceptedInvitation,\n memberId: toExternalId(memberId),\n };\n }\n\n const nextStatus = input.action === \"reject\" ? \"rejected\" : \"canceled\";\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: nextStatus, respondedAt: now }).check(),\n );\n\n const nextInvitation = mapInvitation({\n id: invitation.id,\n organizationId: invitation.organizationId,\n email: invitation.email,\n roles: invitation.roles,\n status: nextStatus,\n token: invitation.token,\n inviterId: invitation.inviterId,\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: now,\n });\n\n if (organization) {\n const hookName =\n input.action === \"reject\" ? \"onInvitationRejected\" : \"onInvitationCanceled\";\n uow.triggerHook(hookName, {\n organization,\n invitation: nextInvitation,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation: nextInvitation,\n };\n },\n )\n .build();\n },\n\n /**\n * List invitations for a session.\n */\n listInvitationsForSession: function (\n this: AuthServiceContext,\n params: ListInvitationsForSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((jb) =>\n jb.sessionOwner((ub) =>\n ub\n .select([\"id\", \"email\", \"role\", \"bannedAt\"])\n .join((jb2) =>\n jb2[\"invitations\"]((ib) => ib.join((jb3) => jb3[\"organization\"]())),\n ),\n ),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [sessions, expiredSession] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n const session = sessions[0] ?? null;\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n const invitations: Array<{\n invitation: OrganizationInvitation<string>;\n organization: Organization;\n }> = [];\n const seenInvitationIds = new Set<string>();\n\n for (const row of sessions) {\n const sessionOwner = row.sessionOwner;\n if (!sessionOwner) {\n continue;\n }\n\n const invitationsForUser = normalizeMany(\n (sessionOwner as { invitations?: unknown }).invitations,\n ) as InvitationRow[];\n for (const invitation of invitationsForUser) {\n if (!invitation || invitation.status !== \"pending\") {\n continue;\n }\n\n const organizationRow = invitation.organization;\n if (!organizationRow || organizationRow.deletedAt) {\n continue;\n }\n\n const invitationId = toExternalId(invitation.id);\n if (seenInvitationIds.has(invitationId)) {\n continue;\n }\n seenInvitationIds.add(invitationId);\n\n const organization = mapOrganization(organizationRow);\n const mappedInvitation = mapInvitationRow(invitation, organization.id);\n invitations.push({\n invitation: mappedInvitation,\n organization,\n });\n }\n }\n\n return { ok: true as const, invitations };\n })\n .build();\n },\n\n /**\n * Respond to an invitation using session permissions.\n */\n respondToInvitationWithSession: function (\n this: AuthServiceContext,\n params: RespondInvitationWithSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))\n .sessionMembers((mb) => mb.join((jb) => jb[\"organizationMemberRoles\"]())),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .find(\"organizationInvitation\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.invitationId))\n .join((j) =>\n j.organizationInvitationOrganization((ob) =>\n ob.join((jb) => jb[\"organizationMembers\"]()),\n ),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [sessions, expiredSession, invitations] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n const session = sessions[0] ?? null;\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n const sessionOwner = session.sessionOwner;\n\n const invitation = invitations[0] ?? null;\n if (!invitation) {\n return { ok: false as const, code: \"invitation_not_found\" as const };\n }\n\n const status = invitation.status as OrganizationInvitationStatus;\n if (status !== \"pending\") {\n return {\n ok: false as const,\n code:\n status === \"expired\"\n ? (\"invitation_expired\" as const)\n : (\"invitation_not_found\" as const),\n };\n }\n\n const now = new Date();\n if (params.action !== \"cancel\") {\n if (!params.token || params.token !== invitation.token) {\n return { ok: false as const, code: \"invalid_token\" as const };\n }\n if (invitation.expiresAt < now) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"expired\", respondedAt: now }).check(),\n );\n return { ok: false as const, code: \"invitation_expired\" as const };\n }\n\n const actorEmail = sessionOwner.email;\n if (!actorEmail) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n if (normalizeEmail(actorEmail) !== normalizeEmail(invitation.email)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n }\n\n const invitationOrganization = (\n invitation as {\n organizationInvitationOrganization?:\n | (OrganizationRow & { organizationMembers?: unknown })\n | null;\n }\n ).organizationInvitationOrganization;\n if (!invitationOrganization || invitationOrganization.deletedAt) {\n return { ok: false as const, code: \"invitation_not_found\" as const };\n }\n const organizationSummary = mapOrganization(invitationOrganization);\n const memberRows = invitations.flatMap((entry) => {\n const organization = (\n entry as {\n organizationInvitationOrganization?:\n | (OrganizationRow & { organizationMembers?: unknown })\n | null;\n }\n ).organizationInvitationOrganization;\n if (!organization) {\n return [];\n }\n return normalizeMany(\n (organization as { organizationMembers?: unknown }).organizationMembers,\n ) as Array<{ id: unknown; userId: unknown; organizationId: unknown }>;\n });\n const memberIds = new Set(\n memberRows.map((member) => toExternalId((member as { id?: unknown }).id ?? member)),\n );\n\n const sessionMembers = sessions.flatMap((entry) => normalizeMany(entry.sessionMembers));\n const invitationOrgId = invitationOrganization?.id ?? invitation.organizationId;\n const actorMember = sessionMembers.find((member) =>\n matchesOrganizationId(member.organizationId, invitationOrgId),\n );\n\n if (params.action === \"cancel\") {\n const actorRoles = actorMember\n ? extractRoles(\n (actorMember as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n )\n : [];\n const isInviter = toExternalId(invitation.inviterId) === toExternalId(sessionOwner.id);\n const canCancel =\n isInviter ||\n isGlobalAdmin(sessionOwner.role as Role) ||\n (actorMember && canManageOrganization(actorRoles));\n\n if (!canCancel) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n }\n\n const actorSummary = mapUserSummary({\n id: sessionOwner.id,\n email: sessionOwner.email,\n role: sessionOwner.role,\n bannedAt: sessionOwner.bannedAt ?? null,\n });\n\n const invitationRoles = Array.isArray(invitation.roles)\n ? (invitation.roles as string[])\n : [];\n const existingMember =\n actorMember ??\n memberRows.find(\n (member) => toExternalId(member.userId) === toExternalId(sessionOwner.id),\n );\n\n if (params.action === \"accept\") {\n if (existingMember) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"accepted\", respondedAt: now }).check(),\n );\n\n const acceptedInvitation = mapInvitationRow({\n ...invitation,\n status: \"accepted\",\n respondedAt: now,\n });\n\n if (organizationSummary) {\n uow.triggerHook(\"onInvitationAccepted\", {\n organization: organizationSummary,\n invitation: acceptedInvitation,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation: acceptedInvitation,\n };\n }\n\n if (\n limits?.membersPerOrganization !== undefined &&\n memberIds.size >= limits.membersPerOrganization\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const memberId = uow.create(\"organizationMember\", {\n organizationId: invitation.organizationId,\n userId: sessionOwner.id,\n createdAt: now,\n updatedAt: now,\n });\n\n for (const role of invitationRoles) {\n uow.create(\"organizationMemberRole\", {\n memberId,\n role,\n createdAt: now,\n });\n }\n\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"accepted\", respondedAt: now }).check(),\n );\n\n const acceptedInvitation = mapInvitationRow({\n ...invitation,\n status: \"accepted\",\n respondedAt: now,\n });\n\n if (organizationSummary) {\n uow.triggerHook(\"onInvitationAccepted\", {\n organization: organizationSummary,\n invitation: acceptedInvitation,\n actor: actorSummary,\n });\n uow.triggerHook(\"onMemberAdded\", {\n organization: organizationSummary,\n member: {\n id: toExternalId(memberId),\n organizationId: toExternalId(invitation.organizationId),\n userId: toExternalId(sessionOwner.id),\n roles: invitationRoles,\n createdAt: now,\n updatedAt: now,\n },\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation: acceptedInvitation,\n };\n }\n\n const nextStatus = params.action === \"reject\" ? \"rejected\" : \"canceled\";\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: nextStatus, respondedAt: now }).check(),\n );\n\n const nextInvitation = mapInvitationRow({\n ...invitation,\n status: nextStatus,\n respondedAt: now,\n });\n\n if (organizationSummary) {\n const hookName =\n params.action === \"reject\" ? \"onInvitationRejected\" : \"onInvitationCanceled\";\n uow.triggerHook(hookName, {\n organization: organizationSummary,\n invitation: nextInvitation,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n invitation: nextInvitation,\n };\n })\n .build();\n },\n\n /**\n * List invitations for an organization using session permissions.\n */\n listOrganizationInvitationsWithSession: function (\n this: AuthServiceContext,\n params: ListOrganizationInvitationsWithSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionMembers()),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.organizationId)),\n )\n .find(\"organizationInvitation\", (b) =>\n b.whereIndex(\"idx_org_invitation_org_status\", (eb) =>\n eb(\"organizationId\", \"=\", params.organizationId),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession, organization, invitations] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!organization || organization.deletedAt != null) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n const sessionMembers = normalizeMany(session.sessionMembers);\n const hasMembership = sessionMembers.some((member) =>\n matchesOrganizationId(member.organizationId, organization.id),\n );\n if (!hasMembership) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const mappedInvitations = invitations.map((invitation) => mapInvitationRow(invitation));\n\n return { ok: true as const, invitations: mappedInvitations };\n })\n .build();\n },\n\n /**\n * Create an invitation using session permissions.\n */\n createOrganizationInvitationWithSession: function (\n this: AuthServiceContext,\n params: CreateOrganizationInvitationWithSessionParams,\n ) {\n const roles = normalizeRoleNames(params.roles, defaultMemberRoles ?? DEFAULT_MEMBER_ROLES);\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))\n .sessionMembers((mb) => mb.join((jb) => jb[\"organizationMemberRoles\"]())),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.organizationId)),\n )\n .find(\"organizationInvitation\", (b) =>\n b.whereIndex(\"idx_org_invitation_org_status\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"status\", \"=\", \"pending\"),\n ),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession, organization, invitations] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n const sessionOwner = session.sessionOwner;\n\n if (!organization || organization.deletedAt != null) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n const actorMember = normalizeMany(session.sessionMembers).find((member) =>\n matchesOrganizationId(member.organizationId, organization.id),\n );\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoles = extractRoles(\n (actorMember as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n if (!isGlobalAdmin(sessionOwner.role as Role) && !canManageOrganization(actorRoles)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorSummary = mapUserSummary({\n id: sessionOwner.id,\n email: sessionOwner.email,\n role: sessionOwner.role,\n bannedAt: sessionOwner.bannedAt ?? null,\n });\n\n const normalizedEmail = normalizeEmail(params.email);\n const pendingInvitesForEmail = invitations.filter(\n (invitation) => normalizeEmail(invitation.email) === normalizedEmail,\n );\n const existingInvitation =\n pendingInvitesForEmail.length > 0\n ? pendingInvitesForEmail.reduce((latest, invitation) =>\n invitation.createdAt > latest.createdAt ? invitation : latest,\n )\n : null;\n\n const now = new Date();\n const token = bytesToHex(randomBytes(32));\n const expiresAt = buildExpiresAt({\n organizationId: params.organizationId,\n email: params.email,\n roles,\n inviterId: toExternalId(sessionOwner.id),\n actor: {\n userId: toExternalId(sessionOwner.id),\n userRole: sessionOwner.role as Role,\n },\n expiresInDays: invitationExpiresInDays,\n });\n\n if (existingInvitation) {\n for (const invitation of pendingInvitesForEmail) {\n if (invitation.id !== existingInvitation.id) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"canceled\", respondedAt: now }).check(),\n );\n }\n }\n\n uow.update(\"organizationInvitation\", existingInvitation.id, (b) =>\n b\n .set({\n organizationId: params.organizationId,\n email: params.email,\n roles,\n status: \"pending\",\n token,\n inviterId: sessionOwner.id,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n })\n .check(),\n );\n\n uow.triggerHook(\n \"onInvitationExpired\",\n { invitationId: toExternalId(existingInvitation.id) },\n { processAt: expiresAt },\n );\n\n const invitation = mapInvitationRow({\n id: existingInvitation.id,\n organizationId: params.organizationId,\n email: params.email,\n roles,\n status: \"pending\",\n token,\n inviterId: sessionOwner.id,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n });\n\n uow.triggerHook(\"onInvitationCreated\", {\n organization: mapOrganization(organization),\n invitation,\n actor: actorSummary,\n });\n\n return {\n ok: true as const,\n invitation,\n };\n }\n\n if (\n limits?.invitationsPerOrganization !== undefined &&\n invitations.length >= limits.invitationsPerOrganization\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const invitationId = uow.create(\"organizationInvitation\", {\n organizationId: params.organizationId,\n email: params.email,\n roles,\n status: \"pending\",\n token,\n inviterId: sessionOwner.id,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n });\n\n uow.triggerHook(\n \"onInvitationExpired\",\n { invitationId: toExternalId(invitationId) },\n { processAt: expiresAt },\n );\n\n const invitation = mapInvitationRow({\n id: invitationId,\n organizationId: params.organizationId,\n email: params.email,\n roles,\n status: \"pending\",\n token,\n inviterId: sessionOwner.id,\n expiresAt,\n createdAt: now,\n respondedAt: null,\n });\n\n uow.triggerHook(\"onInvitationCreated\", {\n organization: mapOrganization(organization),\n invitation,\n actor: actorSummary,\n });\n\n return {\n ok: true as const,\n invitation,\n };\n })\n .build();\n },\n };\n}\n","import type { Cursor } from \"@fragno-dev/db/cursor\";\n\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport type { AuthHooksMap } from \"../hooks\";\nimport { authSchema } from \"../schema\";\nimport type { Role } from \"../types\";\nimport { mapUserSummary } from \"../user/summary\";\nimport { canManageOrganization, isGlobalAdmin, OWNER_ROLE } from \"./permissions\";\nimport type {\n Organization,\n OrganizationConfig,\n OrganizationMember,\n OrganizationMemberSummary,\n} from \"./types\";\nimport { DEFAULT_MEMBER_ROLES, normalizeRoleNames, toExternalId } from \"./utils\";\n\ntype AuthServiceContext = DatabaseServiceContext<AuthHooksMap>;\n\ntype CreateMemberInput = {\n organizationId: string;\n userId: string;\n roles?: readonly string[];\n actor: { userId: string; userRole: Role };\n};\n\ntype ListOrganizationMembersWithSessionParams = {\n sessionId: string;\n organizationId: string;\n pageSize: number;\n cursor?: Cursor;\n};\n\ntype CreateOrganizationMemberWithSessionParams = {\n sessionId: string;\n organizationId: string;\n userId: string;\n roles?: readonly string[];\n};\n\ntype UpdateOrganizationMemberWithSessionParams = {\n sessionId: string;\n organizationId: string;\n memberId: string;\n roles: readonly string[];\n};\n\ntype DeleteOrganizationMemberWithSessionParams = {\n sessionId: string;\n organizationId: string;\n memberId: string;\n};\n\ntype OrganizationMemberServiceOptions = {\n organizationConfig?: OrganizationConfig<string>;\n};\n\nconst mapOrganization = (organization: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n}): Organization => ({\n id: toExternalId(organization.id),\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: (organization.metadata ?? null) as Record<string, unknown> | null,\n createdBy: toExternalId(organization.createdBy),\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n});\n\nconst mapMember = (\n member: {\n id: unknown;\n organizationId: unknown;\n userId: unknown;\n createdAt: Date;\n updatedAt: Date;\n },\n roles: string[],\n overrides?: { organizationId?: string; userId?: string },\n): OrganizationMember<string> => ({\n id: toExternalId(member.id),\n organizationId: overrides?.organizationId ?? toExternalId(member.organizationId),\n userId: overrides?.userId ?? toExternalId(member.userId),\n roles,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n});\n\nconst mapMemberSummary = (\n member: {\n id: unknown;\n organizationId: unknown;\n userId: unknown;\n createdAt: Date;\n updatedAt: Date;\n },\n overrides?: { organizationId?: string; userId?: string },\n): OrganizationMemberSummary => ({\n id: toExternalId(member.id),\n organizationId: overrides?.organizationId ?? toExternalId(member.organizationId),\n userId: overrides?.userId ?? toExternalId(member.userId),\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n});\n\nconst filterRolesForMemberId = (\n roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }[],\n member: { id?: unknown; _internalId?: unknown } | null,\n) => {\n if (!member) {\n return [];\n }\n const candidates = new Set([member.id, member._internalId].filter(Boolean).map(toExternalId));\n return roles\n .filter(\n (role) =>\n candidates.has(toExternalId(role.memberId)) ||\n (role.organizationMemberRoleMember &&\n candidates.has(toExternalId(role.organizationMemberRoleMember.id))),\n )\n .map((role) => role.role);\n};\n\nconst filterOwnerMemberIds = (\n roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { organizationId: unknown } | null;\n }[],\n organizationInternalId: unknown,\n) => {\n const ids = new Set<string>();\n for (const role of roles) {\n const member = role.organizationMemberRoleMember;\n if (member && String(member.organizationId) === String(organizationInternalId)) {\n ids.add(toExternalId(role.memberId));\n }\n }\n return ids;\n};\n\nconst resolveInternalId = (value: unknown): string | bigint | undefined => {\n if (value && typeof value === \"object\") {\n if (\"internalId\" in value) {\n return (value as { internalId?: bigint }).internalId;\n }\n if (\"databaseId\" in value) {\n return (value as { databaseId?: string | bigint }).databaseId;\n }\n }\n return undefined;\n};\n\nconst normalizeMany = <T>(value: T | T[] | null | undefined): T[] => {\n if (!value) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n};\n\nconst extractRoles = (value: unknown): string[] => {\n if (!value) {\n return [];\n }\n if (Array.isArray(value)) {\n return value.map((role) => (role as { role: string }).role);\n }\n if (typeof value === \"object\" && \"role\" in value) {\n return [(value as { role: string }).role];\n }\n return [];\n};\n\nconst collectRolesByMemberId = (\n roles: Array<{\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }>,\n allowedMemberIds?: Set<string>,\n): Record<string, string[]> => {\n const rolesByMemberId = new Map<string, Set<string>>();\n\n for (const role of roles) {\n const memberId = role.organizationMemberRoleMember?.id\n ? toExternalId(role.organizationMemberRoleMember.id)\n : toExternalId(role.memberId);\n\n if (allowedMemberIds && !allowedMemberIds.has(memberId)) {\n continue;\n }\n\n const existing = rolesByMemberId.get(memberId) ?? new Set<string>();\n existing.add(role.role);\n rolesByMemberId.set(memberId, existing);\n }\n\n const result: Record<string, string[]> = {};\n for (const [memberId, roleSet] of rolesByMemberId) {\n result[memberId] = Array.from(roleSet);\n }\n\n return result;\n};\n\nconst matchesOrganizationId = (left: unknown, right: unknown): boolean => {\n const leftInternal = resolveInternalId(left);\n const rightInternal = resolveInternalId(right);\n if (leftInternal !== undefined && rightInternal !== undefined) {\n return String(leftInternal) === String(rightInternal);\n }\n return toExternalId(left) === toExternalId(right);\n};\n\nexport function createOrganizationMemberServices(options: OrganizationMemberServiceOptions = {}) {\n const limits = options.organizationConfig?.limits;\n const defaultMemberRoles = options.organizationConfig?.defaultMemberRoles;\n return {\n /**\n * Fetch a member record for a user within an organization.\n */\n getOrganizationMemberByUser: function (\n this: AuthServiceContext,\n params: { organizationId: string; userId: string },\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"userId\", \"=\", params.userId),\n ),\n ),\n ),\n )\n .transformRetrieve(([member]) =>\n member\n ? mapMemberSummary({\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n })\n : null,\n )\n .build();\n },\n\n /**\n * Create an organization member with permission checks.\n */\n createOrganizationMember: function (this: AuthServiceContext, input: CreateMemberInput) {\n const roles = normalizeRoleNames(input.roles, defaultMemberRoles ?? DEFAULT_MEMBER_ROLES);\n const now = new Date();\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", input.organizationId),\n eb(\"userId\", \"=\", input.userId),\n ),\n ),\n )\n .findFirst(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", input.organizationId),\n eb(\"userId\", \"=\", input.actor.userId),\n ),\n )\n .join((j) => j.organizationMemberOrganization()),\n )\n // NOTE: actorMember is resolved in the same retrieve phase, so we filter in memory.\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"primary\").join((j) => j.organizationMemberRoleMember()),\n )\n .find(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", input.organizationId),\n ),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.actor.userId)),\n ),\n )\n .mutate(\n ({ uow, retrieveResult: [existing, actorMember, actorRoles, members, actorUser] }) => {\n if (existing) {\n return { ok: false as const, code: \"member_already_exists\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoleNames = filterRolesForMemberId(actorRoles, actorMember);\n if (!isGlobalAdmin(input.actor.userRole) && !canManageOrganization(actorRoleNames)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n if (\n limits?.membersPerOrganization !== undefined &&\n members.length >= limits.membersPerOrganization\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const memberId = uow.create(\"organizationMember\", {\n organizationId: input.organizationId,\n userId: input.userId,\n createdAt: now,\n updatedAt: now,\n });\n\n for (const role of roles) {\n uow.create(\"organizationMemberRole\", {\n memberId,\n role,\n createdAt: now,\n });\n }\n\n const organization = actorMember?.organizationMemberOrganization\n ? mapOrganization(actorMember.organizationMemberOrganization)\n : null;\n const member = mapMember(\n {\n id: memberId,\n organizationId: input.organizationId,\n userId: input.userId,\n createdAt: now,\n updatedAt: now,\n },\n roles,\n );\n const actorSummary = actorUser ? mapUserSummary(actorUser) : null;\n\n if (organization) {\n uow.triggerHook(\"onMemberAdded\", {\n organization,\n member,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n member,\n };\n },\n )\n .build();\n },\n\n /**\n * Add a role to a member with permission checks.\n */\n createOrganizationMemberRole: function (\n this: AuthServiceContext,\n params: {\n organizationId: string;\n memberId: string;\n role: string;\n actor: { userId: string; userRole: Role };\n },\n ) {\n const roleNames = normalizeRoleNames([params.role], [params.role]);\n if (roleNames.length === 0) {\n return this.serviceTx(authSchema)\n .mutate(() => ({ ok: false as const, code: \"invalid_role\" as const }))\n .build();\n }\n\n const roleName = roleNames[0]!;\n const now = new Date();\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.memberId)),\n )\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", params.memberId),\n ),\n )\n .findFirst(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"userId\", \"=\", params.actor.userId),\n ),\n )\n .join((j) => j.organizationMemberOrganization()),\n )\n // NOTE: actorMember is resolved in the same retrieve phase, so we filter in memory.\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"primary\").join((j) => j.organizationMemberRoleMember()),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.actor.userId)),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [member, existingRoles, actorMember, actorRoles, actorUser],\n }) => {\n if (!member) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (\n actorMember &&\n String(member.organizationId) !== String(actorMember.organizationId)\n ) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoleNames = filterRolesForMemberId(actorRoles, actorMember);\n if (!isGlobalAdmin(params.actor.userRole) && !canManageOrganization(actorRoleNames)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const roleExists = existingRoles.some((entry) => entry.role === roleName);\n const nextRoles = roleExists\n ? existingRoles.map((entry) => entry.role)\n : [...existingRoles.map((entry) => entry.role), roleName];\n\n if (roleExists) {\n return {\n ok: true as const,\n member: mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n nextRoles,\n ),\n };\n }\n\n uow.create(\"organizationMemberRole\", {\n memberId: params.memberId,\n role: roleName,\n createdAt: now,\n });\n\n uow.update(\"organizationMember\", member.id, (b) => b.set({ updatedAt: now }).check());\n\n const organization = actorMember?.organizationMemberOrganization\n ? mapOrganization(actorMember.organizationMemberOrganization)\n : null;\n const actorSummary = actorUser ? mapUserSummary(actorUser) : null;\n const updatedMember = mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: now,\n },\n nextRoles,\n );\n\n if (organization) {\n uow.triggerHook(\"onMemberRolesUpdated\", {\n organization,\n member: updatedMember,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n member: updatedMember,\n };\n },\n )\n .build();\n },\n\n /**\n * Remove a role from a member with permission checks.\n */\n removeOrganizationMemberRole: function (\n this: AuthServiceContext,\n params: {\n organizationId: string;\n memberId: string;\n role: string;\n actor: { userId: string; userRole: Role };\n },\n ) {\n const roleNames = normalizeRoleNames([params.role], [params.role]);\n if (roleNames.length === 0) {\n return this.serviceTx(authSchema)\n .mutate(() => ({ ok: false as const, code: \"invalid_role\" as const }))\n .build();\n }\n\n const roleName = roleNames[0]!;\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.memberId)),\n )\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", params.memberId),\n ),\n )\n .findFirst(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"userId\", \"=\", params.actor.userId),\n ),\n )\n .join((j) => j.organizationMemberOrganization()),\n )\n // NOTE: actorMember is resolved in the same retrieve phase, so we filter in memory.\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"primary\").join((j) => j.organizationMemberRoleMember()),\n )\n .find(\"organizationMemberRole\", (b) =>\n b\n .whereIndex(\"idx_org_member_role_role\", (eb) => eb(\"role\", \"=\", OWNER_ROLE))\n .join((j) => j.organizationMemberRoleMember()),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.actor.userId)),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [member, existingRoles, actorMember, actorRoles, ownerRoles, actorUser],\n }) => {\n if (!member) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (\n actorMember &&\n String(member.organizationId) !== String(actorMember.organizationId)\n ) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoleNames = filterRolesForMemberId(actorRoles, actorMember);\n if (!isGlobalAdmin(params.actor.userRole) && !canManageOrganization(actorRoleNames)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const existingRole = existingRoles.find((entry) => entry.role === roleName);\n if (!existingRole) {\n return { ok: false as const, code: \"role_not_found\" as const };\n }\n\n if (roleName === OWNER_ROLE) {\n const ownerMemberIds = filterOwnerMemberIds(ownerRoles, member.organizationId);\n if (ownerMemberIds.size <= 1) {\n return { ok: false as const, code: \"last_owner\" as const };\n }\n }\n\n const now = new Date();\n uow.delete(\"organizationMemberRole\", existingRole.id, (b) => b.check());\n uow.update(\"organizationMember\", member.id, (b) => b.set({ updatedAt: now }).check());\n\n const nextRoles = existingRoles\n .filter((entry) => entry.id !== existingRole.id)\n .map((entry) => entry.role);\n\n const organization = actorMember?.organizationMemberOrganization\n ? mapOrganization(actorMember.organizationMemberOrganization)\n : null;\n const actorSummary = actorUser ? mapUserSummary(actorUser) : null;\n const updatedMember = mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: now,\n },\n nextRoles,\n );\n\n if (organization) {\n uow.triggerHook(\"onMemberRolesUpdated\", {\n organization,\n member: updatedMember,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n member: updatedMember,\n };\n },\n )\n .build();\n },\n\n /**\n * Replace a member's roles with a normalized set.\n */\n updateOrganizationMemberRoles: function (\n this: AuthServiceContext,\n params: {\n organizationId: string;\n memberId: string;\n roles: readonly string[];\n actor: { userId: string; userRole: Role };\n },\n ) {\n const nextRoles = normalizeRoleNames(params.roles, DEFAULT_MEMBER_ROLES);\n const now = new Date();\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.memberId)),\n )\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", params.memberId),\n ),\n )\n .findFirst(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"userId\", \"=\", params.actor.userId),\n ),\n )\n .join((j) => j.organizationMemberOrganization()),\n )\n // NOTE: actorMember is resolved in the same retrieve phase, so we filter in memory.\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"primary\").join((j) => j.organizationMemberRoleMember()),\n )\n .find(\"organizationMemberRole\", (b) =>\n b\n .whereIndex(\"idx_org_member_role_role\", (eb) => eb(\"role\", \"=\", OWNER_ROLE))\n .join((j) => j.organizationMemberRoleMember()),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.actor.userId)),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [member, existingRoles, actorMember, actorRoles, ownerRoles, actorUser],\n }) => {\n if (!member) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (\n actorMember &&\n String(member.organizationId) !== String(actorMember.organizationId)\n ) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoleNames = filterRolesForMemberId(actorRoles, actorMember);\n if (!isGlobalAdmin(params.actor.userRole) && !canManageOrganization(actorRoleNames)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const hadOwnerRole = existingRoles.some((role) => role.role === OWNER_ROLE);\n if (hadOwnerRole && !nextRoles.includes(OWNER_ROLE)) {\n const ownerMemberIds = filterOwnerMemberIds(ownerRoles, member.organizationId);\n if (ownerMemberIds.size <= 1) {\n return { ok: false as const, code: \"last_owner\" as const };\n }\n }\n\n for (const existing of existingRoles) {\n uow.delete(\"organizationMemberRole\", existing.id, (b) => b.check());\n }\n\n for (const role of nextRoles) {\n uow.create(\"organizationMemberRole\", {\n memberId: params.memberId,\n role,\n createdAt: now,\n });\n }\n\n uow.update(\"organizationMember\", member.id, (b) => b.set({ updatedAt: now }).check());\n\n const organization = actorMember?.organizationMemberOrganization\n ? mapOrganization(actorMember.organizationMemberOrganization)\n : null;\n const actorSummary = actorUser ? mapUserSummary(actorUser) : null;\n const updatedMember = mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: now,\n },\n nextRoles,\n );\n\n if (organization) {\n uow.triggerHook(\"onMemberRolesUpdated\", {\n organization,\n member: updatedMember,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n member: updatedMember,\n };\n },\n )\n .build();\n },\n\n /**\n * Remove a member from an organization with permission checks.\n */\n removeOrganizationMember: function (\n this: AuthServiceContext,\n params: {\n organizationId: string;\n memberId: string;\n actor: { userId: string; userRole: Role };\n },\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.memberId)),\n )\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", params.memberId),\n ),\n )\n .findFirst(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"userId\", \"=\", params.actor.userId),\n ),\n )\n .join((j) => j.organizationMemberOrganization()),\n )\n // NOTE: actorMember is resolved in the same retrieve phase, so we filter in memory.\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"primary\").join((j) => j.organizationMemberRoleMember()),\n )\n .find(\"organizationMemberRole\", (b) =>\n b\n .whereIndex(\"idx_org_member_role_role\", (eb) => eb(\"role\", \"=\", OWNER_ROLE))\n .join((j) => j.organizationMemberRoleMember()),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.actor.userId)),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [member, roles, actorMember, actorRoles, ownerRoles, actorUser],\n }) => {\n if (!member) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (\n actorMember &&\n String(member.organizationId) !== String(actorMember.organizationId)\n ) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const isSelf = toExternalId(member.userId) === params.actor.userId;\n const actorRoleNames = filterRolesForMemberId(actorRoles, actorMember);\n if (\n !isSelf &&\n !isGlobalAdmin(params.actor.userRole) &&\n !canManageOrganization(actorRoleNames)\n ) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const hadOwnerRole = roles.some((role) => role.role === OWNER_ROLE);\n if (hadOwnerRole) {\n const ownerMemberIds = filterOwnerMemberIds(ownerRoles, member.organizationId);\n if (ownerMemberIds.size <= 1) {\n return { ok: false as const, code: \"last_owner\" as const };\n }\n }\n\n for (const role of roles) {\n uow.delete(\"organizationMemberRole\", role.id, (b) => b.check());\n }\n\n uow.delete(\"organizationMember\", member.id, (b) => b.check());\n const organization = actorMember?.organizationMemberOrganization\n ? mapOrganization(actorMember.organizationMemberOrganization)\n : null;\n const actorSummary = actorUser ? mapUserSummary(actorUser) : null;\n const removedMember = mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n roles.map((role) => role.role),\n );\n\n if (organization) {\n uow.triggerHook(\"onMemberRemoved\", {\n organization,\n member: removedMember,\n actor: actorSummary,\n });\n }\n return { ok: true as const };\n },\n )\n .build();\n },\n\n /**\n * List organization members with cursor-based pagination.\n */\n listOrganizationMembers: function (\n this: AuthServiceContext,\n params: { organizationId: string; pageSize: number; cursor?: Cursor },\n ) {\n const { organizationId, cursor, pageSize } = params;\n const effectivePageSize = cursor ? cursor.pageSize : pageSize;\n const effectiveSortOrder = cursor ? cursor.orderDirection : \"asc\";\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findWithCursor(\"organizationMember\", (b) => {\n const query = b\n .whereIndex(\"idx_org_member_org\", (eb) => eb(\"organizationId\", \"=\", organizationId))\n .orderByIndex(\"idx_org_member_org\", effectiveSortOrder)\n .pageSize(effectivePageSize)\n .join((j) => j.organizationMemberOrganization().organizationMemberUser());\n\n return cursor ? query.after(cursor) : query;\n }),\n )\n .transformRetrieve(([result]) => {\n const members = result.items.map((member) =>\n mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n [],\n {\n organizationId: member.organizationMemberOrganization\n ? toExternalId(member.organizationMemberOrganization.id)\n : toExternalId(member.organizationId),\n userId: member.organizationMemberUser\n ? toExternalId(member.organizationMemberUser.id)\n : toExternalId(member.userId),\n },\n ),\n );\n\n return {\n members,\n cursor: result.cursor,\n hasNextPage: result.hasNextPage,\n };\n })\n .build();\n },\n\n /**\n * List roles for a single organization member.\n */\n listOrganizationMemberRoles: function (this: AuthServiceContext, memberId: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"idx_org_member_role_member\", (eb) => eb(\"memberId\", \"=\", memberId)),\n ),\n )\n .transformRetrieve(([roles]) => ({\n roles: roles.map((role) => role.role),\n }))\n .build();\n },\n\n /**\n * List roles for multiple organization members.\n */\n listOrganizationMemberRolesForMembers: function (\n this: AuthServiceContext,\n memberIds: readonly string[],\n ) {\n if (memberIds.length === 0) {\n return this.serviceTx(authSchema)\n .mutate(() => ({ rolesByMemberId: {} as Record<string, string[]> }))\n .build();\n }\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.find(\"organizationMemberRole\", (b) =>\n b\n .whereIndex(\"idx_org_member_role_member\", (eb) =>\n memberIds.length === 1\n ? eb(\"memberId\", \"=\", memberIds[0])\n : eb.or(...memberIds.map((memberId) => eb(\"memberId\", \"=\", memberId))),\n )\n .join((j) => j.organizationMemberRoleMember()),\n ),\n )\n .transformRetrieve(([roles]) => {\n const rolesByMemberId: Record<string, string[]> = {};\n\n for (const role of roles) {\n const memberId = role.organizationMemberRoleMember\n ? toExternalId(role.organizationMemberRoleMember.id)\n : toExternalId(role.memberId);\n const list = rolesByMemberId[memberId] ?? [];\n list.push(role.role);\n rolesByMemberId[memberId] = list;\n }\n\n return { rolesByMemberId };\n })\n .build();\n },\n\n /**\n * List organization members for a session.\n */\n listOrganizationMembersWithSession: function (\n this: AuthServiceContext,\n params: ListOrganizationMembersWithSessionParams,\n ) {\n const { sessionId, organizationId, cursor } = params;\n const effectivePageSize = cursor ? cursor.pageSize : params.pageSize;\n const effectiveSortOrder = cursor ? cursor.orderDirection : \"asc\";\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionMembers()),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", organizationId)),\n )\n .findWithCursor(\"organizationMember\", (b) => {\n let query = b\n .whereIndex(\"idx_org_member_org\", (eb) => eb(\"organizationId\", \"=\", organizationId))\n .orderByIndex(\"idx_org_member_org\", effectiveSortOrder)\n .pageSize(effectivePageSize)\n .join((j) => j.organizationMemberOrganization().organizationMemberUser());\n\n return cursor ? query.after(cursor) : query;\n })\n .find(\"organizationMemberRole\", (b) =>\n b\n .whereIndex(\"idx_org_member_role_member\")\n .join((j) =>\n j.organizationMemberRoleMember((mb) =>\n mb.whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", organizationId),\n ),\n ),\n ),\n ),\n )\n .mutate(\n ({ uow, retrieveResult: [sessions, expiredSession, organization, members, roles] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n const session = sessions[0] ?? null;\n if (!session) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!organization || organization.deletedAt != null) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n const sessionMembers = normalizeMany(session.sessionMembers);\n const hasMembership = sessionMembers.some((member) =>\n matchesOrganizationId(member.organizationId, organization.id),\n );\n\n if (!hasMembership) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const memberIds = new Set(members.items.map((member) => toExternalId(member.id)));\n const rolesByMemberId = collectRolesByMemberId(roles, memberIds);\n\n const mappedMembers = members.items.map((member) => {\n const resolvedMemberId = toExternalId(member.id);\n const roles = rolesByMemberId[resolvedMemberId] ?? [];\n const joinedOrganization = (\n member as { organizationMemberOrganization?: { id: unknown } }\n ).organizationMemberOrganization;\n const joinedUser = (member as { organizationMemberUser?: { id: unknown } })\n .organizationMemberUser;\n const resolvedOrganizationId = joinedOrganization\n ? toExternalId(joinedOrganization.id)\n : toExternalId(member.organizationId);\n const resolvedUserId = joinedUser\n ? toExternalId(joinedUser.id)\n : toExternalId(member.userId);\n\n return mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n roles,\n {\n organizationId: resolvedOrganizationId,\n userId: resolvedUserId,\n },\n );\n });\n\n return {\n ok: true as const,\n members: mappedMembers,\n cursor: members.cursor?.encode(),\n hasNextPage: members.hasNextPage,\n };\n },\n )\n .build();\n },\n\n /**\n * Create a member using session permissions.\n */\n createOrganizationMemberWithSession: function (\n this: AuthServiceContext,\n params: CreateOrganizationMemberWithSessionParams,\n ) {\n const roles = normalizeRoleNames(params.roles, defaultMemberRoles ?? DEFAULT_MEMBER_ROLES);\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))\n .sessionMembers((mb) => mb.join((jb) => jb[\"organizationMemberRoles\"]())),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.organizationId)),\n )\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"userId\", \"=\", params.userId),\n ),\n ),\n )\n .find(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", params.organizationId),\n ),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [session, expiredSession, organization, existingMember, members],\n }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!organization || organization.deletedAt != null) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n if (existingMember) {\n return { ok: false as const, code: \"member_already_exists\" as const };\n }\n\n const actorMember = normalizeMany(session.sessionMembers).find((member) =>\n matchesOrganizationId(member.organizationId, organization.id),\n );\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoles = extractRoles(\n (actorMember as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n if (\n !isGlobalAdmin(session.sessionOwner.role as Role) &&\n !canManageOrganization(actorRoles)\n ) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n if (\n limits?.membersPerOrganization !== undefined &&\n members.length >= limits.membersPerOrganization\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const now = new Date();\n const memberId = uow.create(\"organizationMember\", {\n organizationId: params.organizationId,\n userId: params.userId,\n createdAt: now,\n updatedAt: now,\n });\n\n for (const role of roles) {\n uow.create(\"organizationMemberRole\", {\n memberId,\n role,\n createdAt: now,\n });\n }\n\n const organizationSummary = mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: organization.metadata ?? null,\n createdBy: organization.createdBy,\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n });\n const memberSummary = mapMember(\n {\n id: memberId,\n organizationId: organization.id,\n userId: params.userId,\n createdAt: now,\n updatedAt: now,\n },\n roles,\n {\n organizationId: toExternalId(organization.id),\n userId: params.userId,\n },\n );\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n\n uow.triggerHook(\"onMemberAdded\", {\n organization: organizationSummary,\n member: memberSummary,\n actor: actorSummary,\n });\n\n return {\n ok: true as const,\n member: memberSummary,\n };\n },\n )\n .build();\n },\n\n /**\n * Update member roles using session permissions.\n */\n updateOrganizationMemberRolesWithSession: function (\n this: AuthServiceContext,\n params: UpdateOrganizationMemberWithSessionParams,\n ) {\n const nextRoles = normalizeRoleNames(params.roles, DEFAULT_MEMBER_ROLES);\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))\n .sessionMembers((mb) =>\n mb.join((jb) =>\n jb.organizationMemberOrganization()[\"organizationMemberRoles\"](),\n ),\n ),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.memberId)),\n )\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", params.memberId),\n ),\n )\n .find(\"organizationMemberRole\", (b) =>\n b\n .whereIndex(\"idx_org_member_role_role\", (eb) => eb(\"role\", \"=\", OWNER_ROLE))\n .join((j) => j.organizationMemberRoleMember()),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [session, expiredSession, member, existingRoles, ownerRoles],\n }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!member) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n const actorMember = normalizeMany(session.sessionMembers).find((entry) => {\n const entryOrganizationId = (\n entry as { organizationMemberOrganization?: { id: unknown } }\n ).organizationMemberOrganization?.id;\n return matchesOrganizationId(\n entryOrganizationId ?? entry.organizationId,\n params.organizationId,\n );\n });\n\n if (\n actorMember &&\n !matchesOrganizationId(\n member.organizationId,\n (actorMember as { organizationMemberOrganization?: { id: unknown } })\n .organizationMemberOrganization?.id ?? actorMember.organizationId,\n )\n ) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const actorRoles = extractRoles(\n (actorMember as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n if (\n !isGlobalAdmin(session.sessionOwner.role as Role) &&\n !canManageOrganization(actorRoles)\n ) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const hadOwnerRole = existingRoles.some((role) => role.role === OWNER_ROLE);\n if (hadOwnerRole && !nextRoles.includes(OWNER_ROLE)) {\n const ownerMemberIds = new Set<string>();\n for (const role of ownerRoles) {\n const ownerMember = (\n role as { organizationMemberRoleMember?: { organizationId: unknown } }\n ).organizationMemberRoleMember;\n if (\n ownerMember &&\n matchesOrganizationId(ownerMember.organizationId, member.organizationId)\n ) {\n ownerMemberIds.add(toExternalId(role.memberId));\n }\n }\n\n if (ownerMemberIds.size <= 1) {\n return { ok: false as const, code: \"last_owner\" as const };\n }\n }\n\n for (const existing of existingRoles) {\n uow.delete(\"organizationMemberRole\", existing.id, (b) => b.check());\n }\n\n const now = new Date();\n for (const role of nextRoles) {\n uow.create(\"organizationMemberRole\", {\n memberId: member.id,\n role,\n createdAt: now,\n });\n }\n\n uow.update(\"organizationMember\", member.id, (b) => b.set({ updatedAt: now }).check());\n\n const organization = (\n actorMember as {\n organizationMemberOrganization?: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n };\n }\n ).organizationMemberOrganization;\n const organizationSummary = organization\n ? mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: organization.metadata ?? null,\n createdBy: organization.createdBy,\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n })\n : null;\n\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n\n const updatedMember = mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: now,\n },\n nextRoles,\n );\n\n if (organizationSummary) {\n uow.triggerHook(\"onMemberRolesUpdated\", {\n organization: organizationSummary,\n member: updatedMember,\n actor: actorSummary,\n });\n }\n\n return {\n ok: true as const,\n member: updatedMember,\n };\n },\n )\n .build();\n },\n\n /**\n * Remove a member using session permissions.\n */\n deleteOrganizationMemberWithSession: function (\n this: AuthServiceContext,\n params: DeleteOrganizationMemberWithSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))\n .sessionMembers((mb) =>\n mb.join((jb) =>\n jb.organizationMemberOrganization()[\"organizationMemberRoles\"](),\n ),\n ),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.memberId)),\n )\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"idx_org_member_role_member\", (eb) =>\n eb(\"memberId\", \"=\", params.memberId),\n ),\n )\n .find(\"organizationMemberRole\", (b) =>\n b\n .whereIndex(\"idx_org_member_role_role\", (eb) => eb(\"role\", \"=\", OWNER_ROLE))\n .join((j) => j.organizationMemberRoleMember()),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession, member, roles, ownerRoles] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!member) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n const actorMember = normalizeMany(session.sessionMembers).find((entry) => {\n const entryOrganizationId = (\n entry as { organizationMemberOrganization?: { id: unknown } }\n ).organizationMemberOrganization?.id;\n return matchesOrganizationId(\n entryOrganizationId ?? entry.organizationId,\n params.organizationId,\n );\n });\n\n if (\n actorMember &&\n !matchesOrganizationId(\n member.organizationId,\n (actorMember as { organizationMemberOrganization?: { id: unknown } })\n .organizationMemberOrganization?.id ?? actorMember.organizationId,\n )\n ) {\n return { ok: false as const, code: \"member_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const isSelf = toExternalId(member.userId) === toExternalId(session.sessionOwner.id);\n const actorRoles = extractRoles(\n (actorMember as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n if (\n !isSelf &&\n !isGlobalAdmin(session.sessionOwner.role as Role) &&\n !canManageOrganization(actorRoles)\n ) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const hadOwnerRole = roles.some((role) => role.role === OWNER_ROLE);\n if (hadOwnerRole) {\n const ownerMemberIds = new Set<string>();\n for (const role of ownerRoles) {\n const ownerMember = (\n role as { organizationMemberRoleMember?: { organizationId: unknown } }\n ).organizationMemberRoleMember;\n if (\n ownerMember &&\n matchesOrganizationId(ownerMember.organizationId, member.organizationId)\n ) {\n ownerMemberIds.add(toExternalId(role.memberId));\n }\n }\n\n if (ownerMemberIds.size <= 1) {\n return { ok: false as const, code: \"last_owner\" as const };\n }\n }\n\n for (const role of roles) {\n uow.delete(\"organizationMemberRole\", role.id, (b) => b.check());\n }\n\n uow.delete(\"organizationMember\", member.id, (b) => b.check());\n\n const organization = (\n actorMember as {\n organizationMemberOrganization?: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n };\n }\n ).organizationMemberOrganization;\n const organizationSummary = organization\n ? mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: organization.metadata ?? null,\n createdBy: organization.createdBy,\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n })\n : null;\n\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n\n const removedMember = mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n roles.map((role) => role.role),\n );\n\n if (organizationSummary) {\n uow.triggerHook(\"onMemberRemoved\", {\n organization: organizationSummary,\n member: removedMember,\n actor: actorSummary,\n });\n }\n\n return { ok: true as const };\n })\n .build();\n },\n };\n}\n","import { createCursorFromRecord, type Cursor } from \"@fragno-dev/db/cursor\";\n\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport type { AuthHooksMap } from \"../hooks\";\nimport { authSchema } from \"../schema\";\nimport type { Role } from \"../types\";\nimport { mapUserSummary } from \"../user/summary\";\nimport { canDeleteOrganization, canManageOrganization, isGlobalAdmin } from \"./permissions\";\nimport type { Organization, OrganizationConfig, OrganizationMember } from \"./types\";\nimport {\n DEFAULT_CREATOR_ROLES,\n normalizeOrganizationSlug,\n normalizeRoleNames,\n toExternalId,\n} from \"./utils\";\n\ntype AuthServiceContext = DatabaseServiceContext<AuthHooksMap>;\n\ntype CreateOrganizationInput = {\n name: string;\n slug: string;\n creatorUserId: string;\n creatorUserRole: Role;\n logoUrl?: string | null;\n metadata?: Record<string, unknown> | null;\n creatorRoles?: readonly string[];\n sessionId?: string;\n};\n\ntype CreateOrganizationWithSessionInput = {\n sessionId: string;\n input: {\n name: string;\n slug: string;\n logoUrl?: string | null;\n metadata?: Record<string, unknown> | null;\n } | null;\n inputError?: unknown | null;\n};\n\ntype GetOrganizationsForSessionParams = {\n sessionId: string;\n pageSize: number;\n cursor?: Cursor;\n};\n\ntype GetActiveOrganizationForSessionParams = {\n sessionId: string;\n};\n\ntype SetActiveOrganizationForSessionParams = {\n sessionId: string;\n organizationId: string;\n};\n\ntype GetOrganizationForSessionParams = {\n sessionId: string;\n organizationId: string;\n};\n\ntype UpdateOrganizationWithSessionParams = {\n sessionId: string;\n organizationId: string;\n patch: {\n name?: string;\n slug?: string;\n logoUrl?: string | null;\n metadata?: Record<string, unknown> | null;\n };\n};\n\ntype DeleteOrganizationWithSessionParams = {\n sessionId: string;\n organizationId: string;\n};\n\ntype OrganizationServiceOptions = {\n organizationConfig?: OrganizationConfig<string>;\n};\n\nconst mapOrganization = (organization: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n organizationCreator?: { id?: unknown } | null;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n}): Organization => ({\n id: toExternalId(organization.id),\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: (organization.metadata ?? null) as Record<string, unknown> | null,\n createdBy: toExternalId(organization.organizationCreator?.id ?? organization.createdBy),\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n});\n\nconst mapMember = (\n member: {\n id: unknown;\n organizationId: unknown;\n userId: unknown;\n createdAt: Date;\n updatedAt: Date;\n },\n roles: string[],\n overrides?: { organizationId?: string; userId?: string },\n): OrganizationMember<string> => ({\n id: toExternalId(member.id),\n organizationId: overrides?.organizationId ?? toExternalId(member.organizationId),\n userId: overrides?.userId ?? toExternalId(member.userId),\n roles,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n});\n\nconst filterRolesForMemberId = (\n roles: {\n role: string;\n memberId: unknown;\n organizationMemberRoleMember?: { id?: unknown } | null;\n }[],\n member: { id?: unknown; _internalId?: unknown } | null,\n) => {\n if (!member) {\n return [];\n }\n const candidates = new Set([member.id, member._internalId].filter(Boolean).map(toExternalId));\n return roles\n .filter(\n (role) =>\n candidates.has(toExternalId(role.memberId)) ||\n (role.organizationMemberRoleMember &&\n candidates.has(toExternalId(role.organizationMemberRoleMember.id))),\n )\n .map((role) => role.role);\n};\n\nconst resolveInternalId = (value: unknown): string | bigint | undefined => {\n if (value && typeof value === \"object\") {\n if (\"internalId\" in value) {\n return (value as { internalId?: bigint }).internalId;\n }\n if (\"databaseId\" in value) {\n return (value as { databaseId?: string | bigint }).databaseId;\n }\n }\n return undefined;\n};\n\nconst normalizeMany = <T>(value: T | T[] | null | undefined): T[] => {\n if (!value) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n};\n\nconst extractRoles = (value: unknown): string[] => {\n if (!value) {\n return [];\n }\n if (Array.isArray(value)) {\n return value.map((role) => (role as { role: string }).role);\n }\n if (typeof value === \"object\" && \"role\" in value) {\n return [(value as { role: string }).role];\n }\n return [];\n};\n\nexport function createOrganizationServices(options: OrganizationServiceOptions = {}) {\n const organizationConfig = options.organizationConfig;\n const allowUserToCreateOrganization = organizationConfig?.allowUserToCreateOrganization;\n const limits = organizationConfig?.limits;\n const defaultCreatorRoles = organizationConfig?.creatorRoles;\n\n const resolveAllowUserToCreateOrganization = async (ctx: { userId: string; userRole: Role }) => {\n if (allowUserToCreateOrganization === undefined) {\n return true;\n }\n if (typeof allowUserToCreateOrganization === \"boolean\") {\n return allowUserToCreateOrganization;\n }\n return allowUserToCreateOrganization(ctx);\n };\n\n return {\n /**\n * Create a new organization and creator membership.\n */\n createOrganization: function (this: AuthServiceContext, input: CreateOrganizationInput) {\n const normalizedSlug = normalizeOrganizationSlug(input.slug);\n if (!normalizedSlug) {\n return this.serviceTx(authSchema)\n .mutate(() => ({\n ok: false as const,\n code: \"invalid_slug\" as const,\n }))\n .build();\n }\n\n const creatorRoles = normalizeRoleNames(\n input.creatorRoles ?? defaultCreatorRoles,\n DEFAULT_CREATOR_ROLES,\n );\n const now = new Date();\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"idx_organization_slug\", (eb) => eb(\"slug\", \"=\", normalizedSlug)),\n )\n .find(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_user\", (eb) => eb(\"userId\", \"=\", input.creatorUserId)),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.sessionId ?? \"\")),\n )\n .findFirst(\"user\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.creatorUserId)),\n ),\n )\n .mutate(async ({ uow, retrieveResult: [existing, members, session, creatorUser] }) => {\n if (existing) {\n return { ok: false as const, code: \"organization_slug_taken\" as const };\n }\n\n const allowed = await resolveAllowUserToCreateOrganization({\n userId: input.creatorUserId,\n userRole: input.creatorUserRole,\n });\n if (!allowed) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n if (\n limits?.organizationsPerUser !== undefined &&\n members.length >= limits.organizationsPerUser\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const organizationId = uow.create(\"organization\", {\n name: input.name,\n slug: normalizedSlug,\n logoUrl: input.logoUrl ?? null,\n metadata: input.metadata ?? null,\n createdBy: input.creatorUserId,\n createdAt: now,\n updatedAt: now,\n });\n\n const memberId = uow.create(\"organizationMember\", {\n organizationId,\n userId: input.creatorUserId,\n createdAt: now,\n updatedAt: now,\n });\n\n for (const role of creatorRoles) {\n uow.create(\"organizationMemberRole\", {\n memberId,\n role,\n createdAt: now,\n });\n }\n\n if (input.sessionId && session && !session.activeOrganizationId) {\n uow.update(\"session\", session.id, (b) =>\n b.set({ activeOrganizationId: organizationId }).check(),\n );\n }\n\n const organization = mapOrganization({\n id: organizationId,\n name: input.name,\n slug: normalizedSlug,\n logoUrl: input.logoUrl ?? null,\n metadata: input.metadata ?? null,\n createdBy: input.creatorUserId,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n });\n\n const member = mapMember(\n {\n id: memberId,\n organizationId,\n userId: input.creatorUserId,\n createdAt: now,\n updatedAt: now,\n },\n creatorRoles,\n );\n\n const actorSummary = creatorUser\n ? mapUserSummary({\n id: creatorUser.id,\n email: creatorUser.email,\n role: creatorUser.role,\n bannedAt: creatorUser.bannedAt ?? null,\n })\n : null;\n\n uow.triggerHook(\"onOrganizationCreated\", {\n organization,\n actor: actorSummary,\n });\n uow.triggerHook(\"onMemberAdded\", {\n organization,\n member,\n actor: actorSummary,\n });\n\n return {\n ok: true as const,\n organization,\n member,\n };\n })\n .build();\n },\n\n /**\n * Fetch an organization by id, excluding deleted records.\n */\n getOrganizationById: function (this: AuthServiceContext, organizationId: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"organization\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", organizationId))\n .join((j) => j.organizationCreator()),\n ),\n )\n .transformRetrieve(([organization]) =>\n organization && organization.deletedAt == null\n ? {\n organization: mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl,\n metadata: organization.metadata,\n createdBy: organization.createdBy,\n organizationCreator: organization.organizationCreator ?? null,\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt,\n }),\n }\n : null,\n )\n .build();\n },\n\n /**\n * Fetch an organization by slug, excluding deleted records.\n */\n getOrganizationBySlug: function (this: AuthServiceContext, slug: string) {\n const normalizedSlug = normalizeOrganizationSlug(slug);\n if (!normalizedSlug) {\n return this.serviceTx(authSchema)\n .mutate(() => null)\n .build();\n }\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"organization\", (b) =>\n b\n .whereIndex(\"idx_organization_slug\", (eb) => eb(\"slug\", \"=\", normalizedSlug))\n .join((j) => j.organizationCreator()),\n ),\n )\n .transformRetrieve(([organization]) =>\n organization && organization.deletedAt == null\n ? {\n organization: mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl,\n metadata: organization.metadata,\n createdBy: organization.createdBy,\n organizationCreator: organization.organizationCreator ?? null,\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt,\n }),\n }\n : null,\n )\n .build();\n },\n\n /**\n * Update organization fields with permission checks.\n */\n updateOrganization: function (\n this: AuthServiceContext,\n organizationId: string,\n patch: {\n name?: string;\n slug?: string;\n logoUrl?: string | null;\n metadata?: Record<string, unknown> | null;\n },\n actor: { userId: string; userRole: Role },\n ) {\n const nextSlug = patch.slug ? normalizeOrganizationSlug(patch.slug) : undefined;\n if (patch.slug && !nextSlug) {\n return this.serviceTx(authSchema)\n .mutate(() => ({\n ok: false as const,\n code: \"invalid_slug\" as const,\n }))\n .build();\n }\n\n const now = new Date();\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organization\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", organizationId))\n .join((j) => j.organizationCreator()),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"idx_organization_slug\", (eb) => eb(\"slug\", \"=\", nextSlug ?? \"\")),\n )\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(eb(\"organizationId\", \"=\", organizationId), eb(\"userId\", \"=\", actor.userId)),\n ),\n )\n // NOTE: actorMember is resolved in the same retrieve phase, so we filter in memory.\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"primary\").join((j) => j.organizationMemberRoleMember()),\n )\n .findFirst(\"user\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", actor.userId))),\n )\n .mutate(\n ({ uow, retrieveResult: [existing, slugMatch, actorMember, actorRoles, actorUser] }) => {\n if (!existing) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const roles = filterRolesForMemberId(actorRoles, actorMember);\n if (!isGlobalAdmin(actor.userRole) && !canManageOrganization(roles)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n if (nextSlug && slugMatch && toExternalId(slugMatch.id) !== organizationId) {\n return { ok: false as const, code: \"organization_slug_taken\" as const };\n }\n\n const updated = {\n name: patch.name ?? existing.name,\n slug: nextSlug ?? existing.slug,\n logoUrl: patch.logoUrl !== undefined ? patch.logoUrl : existing.logoUrl,\n metadata: patch.metadata !== undefined ? patch.metadata : existing.metadata,\n createdBy: existing.createdBy,\n createdAt: existing.createdAt,\n updatedAt: now,\n deletedAt: existing.deletedAt,\n };\n\n uow.update(\"organization\", existing.id, (b) =>\n b\n .set({\n name: updated.name,\n slug: updated.slug,\n logoUrl: updated.logoUrl,\n metadata: updated.metadata,\n updatedAt: updated.updatedAt,\n })\n .check(),\n );\n\n const organization = mapOrganization({\n id: existing.id,\n name: updated.name,\n slug: updated.slug,\n logoUrl: updated.logoUrl,\n metadata: updated.metadata,\n createdBy: existing.createdBy,\n organizationCreator: existing.organizationCreator ?? null,\n createdAt: updated.createdAt,\n updatedAt: updated.updatedAt,\n deletedAt: updated.deletedAt,\n });\n\n const actorSummary = actorUser\n ? mapUserSummary({\n id: actorUser.id,\n email: actorUser.email,\n role: actorUser.role,\n bannedAt: actorUser.bannedAt ?? null,\n })\n : null;\n\n uow.triggerHook(\"onOrganizationUpdated\", {\n organization,\n actor: actorSummary,\n });\n\n return {\n ok: true as const,\n organization,\n };\n },\n )\n .build();\n },\n\n /**\n * Soft-delete an organization with permission checks.\n */\n deleteOrganization: function (\n this: AuthServiceContext,\n organizationId: string,\n actor: { userId: string; userRole: Role },\n ) {\n const now = new Date();\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"organization\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", organizationId))\n .join((j) => j.organizationCreator()),\n )\n .findFirst(\"organizationMember\", (b) =>\n b.whereIndex(\"idx_org_member_org_user\", (eb) =>\n eb.and(eb(\"organizationId\", \"=\", organizationId), eb(\"userId\", \"=\", actor.userId)),\n ),\n )\n // NOTE: actorMember is resolved in the same retrieve phase, so we filter in memory.\n .find(\"organizationMemberRole\", (b) =>\n b.whereIndex(\"primary\").join((j) => j.organizationMemberRoleMember()),\n )\n .find(\"organizationInvitation\", (b) =>\n b.whereIndex(\"idx_org_invitation_org_status\", (eb) =>\n eb.and(eb(\"organizationId\", \"=\", organizationId), eb(\"status\", \"=\", \"pending\")),\n ),\n )\n .findFirst(\"user\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", actor.userId))),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [organization, actorMember, actorRoles, invitations, actorUser],\n }) => {\n if (!organization) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const roles = filterRolesForMemberId(actorRoles, actorMember);\n if (!isGlobalAdmin(actor.userRole) && !canDeleteOrganization(roles)) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n uow.update(\"organization\", organization.id, (b) =>\n b.set({ deletedAt: now, updatedAt: now }).check(),\n );\n\n if (invitations.length > 0) {\n for (const invitation of invitations) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"canceled\", respondedAt: now }).check(),\n );\n }\n }\n\n const organizationSummary = mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl,\n metadata: organization.metadata,\n createdBy: organization.createdBy,\n organizationCreator: organization.organizationCreator ?? null,\n createdAt: organization.createdAt,\n updatedAt: now,\n deletedAt: now,\n });\n\n const actorSummary = actorUser\n ? mapUserSummary({\n id: actorUser.id,\n email: actorUser.email,\n role: actorUser.role,\n bannedAt: actorUser.bannedAt ?? null,\n })\n : null;\n\n uow.triggerHook(\"onOrganizationDeleted\", {\n organization: organizationSummary,\n actor: actorSummary,\n });\n\n return { ok: true as const };\n },\n )\n .build();\n },\n\n /**\n * List organizations for a user with cursor-based pagination.\n */\n getOrganizationsForUser: function (\n this: AuthServiceContext,\n params: { userId: string; pageSize: number; cursor?: Cursor },\n ) {\n const { userId, cursor, pageSize } = params;\n const effectivePageSize = cursor ? cursor.pageSize : pageSize;\n const effectiveSortOrder = cursor ? cursor.orderDirection : \"asc\";\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findWithCursor(\"organizationMember\", (b) => {\n const query = b\n .whereIndex(\"idx_org_member_user\", (eb) => eb(\"userId\", \"=\", userId))\n .orderByIndex(\"idx_org_member_user\", effectiveSortOrder)\n .pageSize(effectivePageSize)\n .join((j) =>\n j\n .organizationMemberOrganization((org) => org.join((j) => j.organizationCreator()))\n .organizationMemberUser(),\n );\n\n return cursor ? query.after(cursor) : query;\n }),\n )\n .transformRetrieve(([result]) => {\n const organizations = result.items\n .filter(\n (member) =>\n member.organizationMemberOrganization &&\n member.organizationMemberOrganization.deletedAt == null,\n )\n .map((member) => {\n const organization = member.organizationMemberOrganization;\n const memberUserId = member.organizationMemberUser\n ? toExternalId(member.organizationMemberUser.id)\n : toExternalId(member.userId);\n return {\n organization: mapOrganization({\n id: organization!.id,\n name: organization!.name,\n slug: organization!.slug,\n logoUrl: organization!.logoUrl,\n metadata: organization!.metadata,\n createdBy: organization!.createdBy,\n organizationCreator: organization!.organizationCreator ?? null,\n createdAt: organization!.createdAt,\n updatedAt: organization!.updatedAt,\n deletedAt: organization!.deletedAt,\n }),\n member: mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n [],\n {\n organizationId: toExternalId(organization!.id),\n userId: memberUserId,\n },\n ),\n };\n });\n\n return {\n organizations,\n cursor: result.cursor,\n hasNextPage: result.hasNextPage,\n };\n })\n .build();\n },\n\n /**\n * Create an organization using session context.\n */\n createOrganizationWithSession: function (\n this: AuthServiceContext,\n params: CreateOrganizationWithSessionInput,\n ) {\n const normalizedSlug = params.input ? normalizeOrganizationSlug(params.input.slug) : null;\n const slugLookup = normalizedSlug ?? \"__invalid__\";\n const creatorRoles = normalizeRoleNames(defaultCreatorRoles, DEFAULT_CREATOR_ROLES);\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))\n .sessionMembers(),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"idx_organization_slug\", (eb) => eb(\"slug\", \"=\", slugLookup)),\n ),\n )\n .mutate(async ({ uow, retrieveResult: [sessions, expiredSession, existing] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n const session = sessions[0] ?? null;\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (params.inputError) {\n return { ok: false as const, code: \"input_invalid\" as const };\n }\n\n if (!params.input || !normalizedSlug) {\n return { ok: false as const, code: \"invalid_slug\" as const };\n }\n\n if (existing) {\n return { ok: false as const, code: \"organization_slug_taken\" as const };\n }\n\n const creatorUserId = toExternalId(session.sessionOwner.id);\n const creatorUserRole = session.sessionOwner.role as Role;\n const allowed = await resolveAllowUserToCreateOrganization({\n userId: creatorUserId,\n userRole: creatorUserRole,\n });\n if (!allowed) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const memberIds = new Set<string>();\n for (const entry of sessions) {\n for (const member of normalizeMany(entry.sessionMembers)) {\n const memberId = (member as { id?: unknown }).id ?? member;\n memberIds.add(toExternalId(memberId));\n }\n }\n\n if (\n limits?.organizationsPerUser !== undefined &&\n memberIds.size >= limits.organizationsPerUser\n ) {\n return { ok: false as const, code: \"limit_reached\" as const };\n }\n\n const now = new Date();\n const organizationId = uow.create(\"organization\", {\n name: params.input.name,\n slug: normalizedSlug,\n logoUrl: params.input.logoUrl ?? null,\n metadata: params.input.metadata ?? null,\n createdBy: creatorUserId,\n createdAt: now,\n updatedAt: now,\n });\n\n const memberId = uow.create(\"organizationMember\", {\n organizationId,\n userId: creatorUserId,\n createdAt: now,\n updatedAt: now,\n });\n\n for (const role of creatorRoles) {\n uow.create(\"organizationMemberRole\", {\n memberId,\n role,\n createdAt: now,\n });\n }\n\n if (!session.activeOrganizationId) {\n uow.update(\"session\", session.id, (b) =>\n b.set({ activeOrganizationId: organizationId }).check(),\n );\n }\n\n const organization = mapOrganization({\n id: organizationId,\n name: params.input.name,\n slug: normalizedSlug,\n logoUrl: params.input.logoUrl ?? null,\n metadata: params.input.metadata ?? null,\n createdBy: creatorUserId,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n });\n\n const member = mapMember(\n {\n id: memberId,\n organizationId,\n userId: creatorUserId,\n createdAt: now,\n updatedAt: now,\n },\n creatorRoles,\n {\n organizationId: toExternalId(organizationId),\n userId: creatorUserId,\n },\n );\n\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n\n uow.triggerHook(\"onOrganizationCreated\", {\n organization,\n actor: actorSummary,\n });\n uow.triggerHook(\"onMemberAdded\", {\n organization,\n member,\n actor: actorSummary,\n });\n\n return {\n ok: true as const,\n organization,\n member,\n };\n })\n .build();\n },\n\n /**\n * List organizations for a session with pagination.\n */\n getOrganizationsForSession: function (\n this: AuthServiceContext,\n params: GetOrganizationsForSessionParams,\n ) {\n const { sessionId, cursor } = params;\n const effectivePageSize = cursor ? cursor.pageSize : params.pageSize;\n const effectiveSortOrder = cursor ? cursor.orderDirection : \"asc\";\n const resolveCursorId = (value: unknown): string | null => {\n if (typeof value === \"string\") {\n return value;\n }\n if (value && typeof value === \"object\" && \"externalId\" in value) {\n const externalId = (value as { externalId?: unknown }).externalId;\n if (typeof externalId === \"string\") {\n return externalId;\n }\n }\n return null;\n };\n const cursorId = cursor ? resolveCursorId(cursor.indexValues[\"id\"]) : null;\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\"]))\n .sessionMembers((mb) => {\n let memberQuery = mb\n .orderByIndex(\"primary\", effectiveSortOrder)\n .pageSize(effectivePageSize + 1)\n .join((jb) => jb[\"organization\"]()[\"roles\"]((rb) => rb.select([\"role\"])));\n\n if (cursorId) {\n memberQuery = memberQuery.whereIndex(\"primary\", (eb) =>\n eb(\"id\", effectiveSortOrder === \"asc\" ? \">\" : \"<\", cursorId),\n );\n }\n\n return memberQuery;\n }),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [sessions, expiredSession] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n const session = Array.isArray(sessions) ? sessions[0] : null;\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n const sessionOwner = session.sessionOwner;\n type SessionMemberRow = {\n id: unknown;\n organizationId: unknown;\n userId: unknown;\n createdAt: Date;\n updatedAt: Date;\n organization?: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n } | null;\n roles?: { role: string }[];\n };\n\n const orderedMemberIds: string[] = [];\n const membersById = new Map<\n string,\n {\n member: SessionMemberRow;\n organization: NonNullable<SessionMemberRow[\"organization\"]>;\n roles: Set<string>;\n }\n >();\n\n for (const row of sessions) {\n const members = normalizeMany(row.sessionMembers) as SessionMemberRow[];\n for (const member of members) {\n const organization = member.organization;\n if (!organization || organization.deletedAt) {\n continue;\n }\n\n const memberId = toExternalId(member.id);\n let entry = membersById.get(memberId);\n if (!entry) {\n entry = { member, organization, roles: new Set() };\n membersById.set(memberId, entry);\n orderedMemberIds.push(memberId);\n }\n\n const roles = normalizeMany(member.roles);\n for (const role of roles) {\n entry.roles.add(role.role);\n }\n }\n }\n\n const orderedEntries = orderedMemberIds\n .map((memberId) => membersById.get(memberId))\n .filter(Boolean) as Array<{\n member: SessionMemberRow;\n organization: NonNullable<SessionMemberRow[\"organization\"]>;\n roles: Set<string>;\n }>;\n\n const hasNextPage = orderedEntries.length > effectivePageSize;\n const pagedEntries = orderedEntries.slice(0, effectivePageSize);\n const cursorRecord =\n hasNextPage && pagedEntries.length > 0\n ? pagedEntries[pagedEntries.length - 1]!.member\n : null;\n const nextCursor = cursorRecord\n ? createCursorFromRecord(\n cursorRecord,\n [authSchema.tables.organizationMember.getIdColumn()],\n {\n indexName: \"_primary\",\n orderDirection: effectiveSortOrder,\n pageSize: effectivePageSize,\n },\n )\n : undefined;\n\n const organizations = pagedEntries.map((entry) => {\n const memberOrganizationId = toExternalId(entry.organization.id);\n const memberUserId = toExternalId(sessionOwner.id);\n\n return {\n organization: mapOrganization({\n id: entry.organization.id,\n name: entry.organization.name,\n slug: entry.organization.slug,\n logoUrl: entry.organization.logoUrl ?? null,\n metadata: entry.organization.metadata ?? null,\n createdBy: entry.organization.createdBy,\n createdAt: entry.organization.createdAt,\n updatedAt: entry.organization.updatedAt,\n deletedAt: entry.organization.deletedAt ?? null,\n }),\n member: mapMember(\n {\n id: entry.member.id,\n organizationId: entry.member.organizationId,\n userId: entry.member.userId,\n createdAt: entry.member.createdAt,\n updatedAt: entry.member.updatedAt,\n },\n Array.from(entry.roles),\n {\n organizationId: memberOrganizationId,\n userId: memberUserId,\n },\n ),\n };\n });\n\n return {\n ok: true as const,\n organizations,\n cursor: nextCursor?.encode(),\n hasNextPage,\n };\n })\n .build();\n },\n\n /**\n * Resolve the active organization for a session.\n */\n getActiveOrganizationForSession: function (\n this: AuthServiceContext,\n params: GetActiveOrganizationForSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) =>\n j\n .sessionOwner((b) => b.select([\"id\"]))\n .sessionActiveOrganization()\n .sessionMembers((mb) => mb.join((jb) => jb[\"organizationMemberRoles\"]())),\n ),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n const activeOrganization = session.sessionActiveOrganization;\n if (!activeOrganization || activeOrganization.deletedAt != null) {\n return { ok: true as const, data: null };\n }\n\n const member = normalizeMany(session.sessionMembers).find((entry) => {\n const entryInternal = resolveInternalId(entry.organizationId);\n const activeInternal = resolveInternalId(activeOrganization.id);\n const entryUserInternal = resolveInternalId(entry.userId);\n const sessionUserInternal = resolveInternalId(session.userId);\n if (entryInternal !== undefined && activeInternal !== undefined) {\n if (String(entryInternal) !== String(activeInternal)) {\n return false;\n }\n if (entryUserInternal !== undefined && sessionUserInternal !== undefined) {\n return String(entryUserInternal) === String(sessionUserInternal);\n }\n return false;\n }\n return false;\n });\n if (!member) {\n return { ok: true as const, data: null };\n }\n\n const roles = extractRoles(\n (member as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n const memberOrganizationId = toExternalId(activeOrganization.id);\n const memberUserId = toExternalId(session.sessionOwner.id);\n\n return {\n ok: true as const,\n data: {\n organization: mapOrganization({\n id: activeOrganization.id,\n name: activeOrganization.name,\n slug: activeOrganization.slug,\n logoUrl: activeOrganization.logoUrl ?? null,\n metadata: activeOrganization.metadata ?? null,\n createdBy: activeOrganization.createdBy,\n createdAt: activeOrganization.createdAt,\n updatedAt: activeOrganization.updatedAt,\n deletedAt: activeOrganization.deletedAt ?? null,\n }),\n member: mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n roles,\n {\n organizationId: memberOrganizationId,\n userId: memberUserId,\n },\n ),\n },\n };\n })\n .build();\n },\n\n /**\n * Set the active organization for a session.\n */\n setActiveOrganizationForSession: function (\n this: AuthServiceContext,\n params: SetActiveOrganizationForSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionOwner((b) => b.select([\"id\"]))),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.organizationId)),\n )\n .find(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", params.organizationId),\n )\n .join((j) => j[\"organizationMemberRoles\"]()),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession, organization, members] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!organization || organization.deletedAt != null) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n const member = normalizeMany(members).find((entry) => {\n const entryUserInternal = resolveInternalId(entry.userId);\n const sessionUserInternal = resolveInternalId(session.userId);\n if (entryUserInternal !== undefined && sessionUserInternal !== undefined) {\n return String(entryUserInternal) === String(sessionUserInternal);\n }\n return false;\n });\n if (!member) {\n return { ok: false as const, code: \"membership_not_found\" as const };\n }\n\n uow.update(\"session\", session.id, (b) =>\n b.set({ activeOrganizationId: params.organizationId }).check(),\n );\n\n const roles = extractRoles(\n (member as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n const memberOrganizationId = toExternalId(organization.id);\n const memberUserId = toExternalId(session.sessionOwner.id);\n\n return {\n ok: true as const,\n organization: mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: organization.metadata ?? null,\n createdBy: organization.createdBy,\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n }),\n member: mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n roles,\n {\n organizationId: memberOrganizationId,\n userId: memberUserId,\n },\n ),\n };\n })\n .build();\n },\n\n /**\n * Fetch organization details for a session.\n */\n getOrganizationForSession: function (\n this: AuthServiceContext,\n params: GetOrganizationForSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\"]))),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.organizationId)),\n )\n .find(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", params.organizationId),\n )\n .join((j) => j[\"organizationMemberRoles\"]()),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession, organization, members] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!organization || organization.deletedAt != null) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n const member = normalizeMany(members).find((entry) => {\n const entryInternal = resolveInternalId(entry.organizationId);\n const organizationInternal = resolveInternalId(organization.id);\n const entryUserInternal = resolveInternalId(entry.userId);\n const sessionUserInternal = resolveInternalId(session.userId);\n if (entryInternal !== undefined && organizationInternal !== undefined) {\n if (String(entryInternal) !== String(organizationInternal)) {\n return false;\n }\n if (entryUserInternal !== undefined && sessionUserInternal !== undefined) {\n return String(entryUserInternal) === String(sessionUserInternal);\n }\n return false;\n }\n return false;\n });\n if (!member) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const roles = extractRoles(\n (member as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n const memberOrganizationId = toExternalId(organization.id);\n const memberUserId = toExternalId(session.sessionOwner.id);\n\n return {\n ok: true as const,\n organization: mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: organization.metadata ?? null,\n createdBy: organization.createdBy,\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n }),\n member: mapMember(\n {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n },\n roles,\n {\n organizationId: memberOrganizationId,\n userId: memberUserId,\n },\n ),\n };\n })\n .build();\n },\n\n /**\n * Update an organization using session permissions.\n */\n updateOrganizationWithSession: function (\n this: AuthServiceContext,\n params: UpdateOrganizationWithSessionParams,\n ) {\n const nextSlug = params.patch.slug ? normalizeOrganizationSlug(params.patch.slug) : undefined;\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.organizationId)),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"idx_organization_slug\", (eb) => eb(\"slug\", \"=\", nextSlug ?? \"\")),\n )\n .find(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", params.organizationId),\n )\n .join((j) => j[\"organizationMemberRoles\"]()),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [session, expiredSession, organization, slugMatch, members],\n }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (params.patch.slug && !nextSlug) {\n return { ok: false as const, code: \"invalid_slug\" as const };\n }\n\n if (!organization) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n const actorMember = normalizeMany(members).find((entry) => {\n const entryInternal = resolveInternalId(entry.organizationId);\n const organizationInternal = resolveInternalId(organization.id);\n const entryUserInternal = resolveInternalId(entry.userId);\n const sessionUserInternal = resolveInternalId(session.userId);\n if (entryInternal !== undefined && organizationInternal !== undefined) {\n if (String(entryInternal) !== String(organizationInternal)) {\n return false;\n }\n if (entryUserInternal !== undefined && sessionUserInternal !== undefined) {\n return String(entryUserInternal) === String(sessionUserInternal);\n }\n return false;\n }\n return false;\n });\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const roles = extractRoles(\n (actorMember as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n if (\n !isGlobalAdmin(session.sessionOwner.role as Role) &&\n !canManageOrganization(roles)\n ) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n if (nextSlug && slugMatch && toExternalId(slugMatch.id) !== params.organizationId) {\n return { ok: false as const, code: \"organization_slug_taken\" as const };\n }\n\n const now = new Date();\n const updated = {\n name: params.patch.name ?? organization.name,\n slug: nextSlug ?? organization.slug,\n logoUrl:\n params.patch.logoUrl !== undefined ? params.patch.logoUrl : organization.logoUrl,\n metadata:\n params.patch.metadata !== undefined ? params.patch.metadata : organization.metadata,\n createdBy: organization.createdBy,\n createdAt: organization.createdAt,\n updatedAt: now,\n deletedAt: organization.deletedAt,\n };\n\n uow.update(\"organization\", organization.id, (b) =>\n b\n .set({\n name: updated.name,\n slug: updated.slug,\n logoUrl: updated.logoUrl,\n metadata: updated.metadata,\n updatedAt: updated.updatedAt,\n })\n .check(),\n );\n\n const organizationSummary = mapOrganization({\n id: organization.id,\n name: updated.name,\n slug: updated.slug,\n logoUrl: updated.logoUrl ?? null,\n metadata: updated.metadata ?? null,\n createdBy: organization.createdBy,\n createdAt: updated.createdAt,\n updatedAt: updated.updatedAt,\n deletedAt: updated.deletedAt ?? null,\n });\n\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n\n uow.triggerHook(\"onOrganizationUpdated\", {\n organization: organizationSummary,\n actor: actorSummary,\n });\n\n return {\n ok: true as const,\n organization: organizationSummary,\n };\n },\n )\n .build();\n },\n\n /**\n * Delete an organization using session permissions.\n */\n deleteOrganizationWithSession: function (\n this: AuthServiceContext,\n params: DeleteOrganizationWithSessionParams,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", params.sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n )\n .findFirst(\"organization\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", params.organizationId)),\n )\n .find(\"organizationInvitation\", (b) =>\n b.whereIndex(\"idx_org_invitation_org_status\", (eb) =>\n eb.and(\n eb(\"organizationId\", \"=\", params.organizationId),\n eb(\"status\", \"=\", \"pending\"),\n ),\n ),\n )\n .find(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_org\", (eb) =>\n eb(\"organizationId\", \"=\", params.organizationId),\n )\n .join((j) => j[\"organizationMemberRoles\"]()),\n ),\n )\n .mutate(\n ({\n uow,\n retrieveResult: [session, expiredSession, organization, invitations, members],\n }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (!organization) {\n return { ok: false as const, code: \"organization_not_found\" as const };\n }\n\n const actorMember = normalizeMany(members).find((entry) => {\n const entryInternal = resolveInternalId(entry.organizationId);\n const organizationInternal = resolveInternalId(organization.id);\n const entryUserInternal = resolveInternalId(entry.userId);\n const sessionUserInternal = resolveInternalId(session.userId);\n if (entryInternal !== undefined && organizationInternal !== undefined) {\n if (String(entryInternal) !== String(organizationInternal)) {\n return false;\n }\n if (entryUserInternal !== undefined && sessionUserInternal !== undefined) {\n return String(entryUserInternal) === String(sessionUserInternal);\n }\n return false;\n }\n return false;\n });\n if (!actorMember) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const roles = extractRoles(\n (actorMember as { organizationMemberRoles?: unknown }).organizationMemberRoles,\n );\n if (\n !isGlobalAdmin(session.sessionOwner.role as Role) &&\n !canDeleteOrganization(roles)\n ) {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n const now = new Date();\n uow.update(\"organization\", organization.id, (b) =>\n b.set({ deletedAt: now, updatedAt: now }).check(),\n );\n\n if (invitations.length > 0) {\n for (const invitation of invitations) {\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"canceled\", respondedAt: now }).check(),\n );\n }\n }\n\n const organizationSummary = mapOrganization({\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: organization.metadata ?? null,\n createdBy: organization.createdBy,\n createdAt: organization.createdAt,\n updatedAt: now,\n deletedAt: now,\n });\n\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n\n uow.triggerHook(\"onOrganizationDeleted\", {\n organization: organizationSummary,\n actor: actorSummary,\n });\n\n return { ok: true as const };\n },\n )\n .build();\n },\n };\n}\n","import { z } from \"zod\";\n\nexport const organizationSchema = z.object({\n id: z.string(),\n name: z.string(),\n slug: z.string(),\n logoUrl: z.string().nullable(),\n metadata: z.record(z.string(), z.unknown()).nullable(),\n createdBy: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n deletedAt: z.string().nullable(),\n});\n\nexport const memberSchema = z.object({\n id: z.string(),\n organizationId: z.string(),\n userId: z.string(),\n roles: z.array(z.string()),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nexport const invitationSchema = z.object({\n id: z.string(),\n organizationId: z.string(),\n email: z.string(),\n roles: z.array(z.string()),\n status: z.enum([\"pending\", \"accepted\", \"rejected\", \"canceled\", \"expired\"]),\n token: z.string(),\n inviterId: z.string(),\n expiresAt: z.string(),\n createdAt: z.string(),\n respondedAt: z.string().nullable(),\n});\n\nexport const invitationSummarySchema = invitationSchema.omit({ token: true });\n","import type { OrganizationInvitation, OrganizationMember } from \"./types\";\n\ntype OrganizationLike = {\n id: string;\n name: string;\n slug: string;\n logoUrl?: string | null;\n metadata?: Record<string, unknown> | null | unknown;\n createdBy: string;\n createdAt: Date;\n updatedAt: Date;\n deletedAt?: Date | null;\n};\n\ntype SerializableOrganization = {\n id: string;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: Record<string, unknown> | null;\n createdBy: string;\n createdAt: string;\n updatedAt: string;\n deletedAt: string | null;\n};\n\ntype SerializableMember = {\n id: string;\n organizationId: string;\n userId: string;\n roles: string[];\n createdAt: string;\n updatedAt: string;\n};\n\ntype SerializableInvitation = {\n id: string;\n organizationId: string;\n email: string;\n roles: string[];\n status: OrganizationInvitation<string>[\"status\"];\n token: string;\n inviterId: string;\n expiresAt: string;\n createdAt: string;\n respondedAt: string | null;\n};\n\ntype SerializableInvitationSummary = Omit<SerializableInvitation, \"token\">;\n\nconst normalizeMetadata = (value: unknown): Record<string, unknown> | null => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n return value as Record<string, unknown>;\n};\n\nexport function serializeOrganization(organization: OrganizationLike): SerializableOrganization {\n return {\n id: organization.id,\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: normalizeMetadata(organization.metadata),\n createdBy: organization.createdBy,\n createdAt: organization.createdAt.toISOString(),\n updatedAt: organization.updatedAt.toISOString(),\n deletedAt: organization.deletedAt ? organization.deletedAt.toISOString() : null,\n };\n}\n\nexport function serializeMember<TRole extends string>(\n member: OrganizationMember<TRole>,\n): SerializableMember {\n return {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n roles: member.roles as string[],\n createdAt: member.createdAt.toISOString(),\n updatedAt: member.updatedAt.toISOString(),\n };\n}\n\nexport function serializeInvitation<TRole extends string>(\n invitation: OrganizationInvitation<TRole>,\n): SerializableInvitation {\n return {\n id: invitation.id,\n organizationId: invitation.organizationId,\n email: invitation.email,\n roles: invitation.roles as string[],\n status: invitation.status,\n token: invitation.token,\n inviterId: invitation.inviterId,\n expiresAt: invitation.expiresAt.toISOString(),\n createdAt: invitation.createdAt.toISOString(),\n respondedAt: invitation.respondedAt ? invitation.respondedAt.toISOString() : null,\n };\n}\n\nexport function serializeInvitationSummary<TRole extends string>(\n invitation: OrganizationInvitation<TRole>,\n): SerializableInvitationSummary {\n const { token: _token, ...rest } = serializeInvitation(invitation);\n return rest;\n}\n","import { type Cursor, decodeCursor } from \"@fragno-dev/db/cursor\";\nimport { z } from \"zod\";\n\nimport { defineRoute, defineRoutes } from \"@fragno-dev/core\";\n\nimport type { authFragmentDefinition } from \"..\";\nimport { extractSessionId } from \"../utils/cookie\";\nimport { invitationSchema, memberSchema, organizationSchema } from \"./schemas\";\nimport { serializeInvitation, serializeMember, serializeOrganization } from \"./serializers\";\n\nconst createOrganizationInputSchema = z.object({\n name: z.string().min(1).max(120),\n slug: z.string().min(1),\n logoUrl: z.string().nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n});\n\nconst updateOrganizationInputSchema = z\n .object({\n name: z.string().min(1).max(120).optional(),\n slug: z.string().min(1).optional(),\n logoUrl: z.string().nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n })\n .refine((value) => Object.keys(value).length > 0, {\n message: \"At least one field must be provided\",\n });\n\nconst pageQuerySchema = z.object({\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n});\n\nconst parseCursor = (cursorParam: string | null): Cursor | undefined => {\n if (!cursorParam) {\n return undefined;\n }\n try {\n return decodeCursor(cursorParam);\n } catch {\n return undefined;\n }\n};\n\nexport const organizationRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ config, services }) => {\n const organizationsEnabled = config.organizations !== false;\n const defineOrganizationRoute = ((route: Parameters<typeof defineRoute>[0]) =>\n defineRoute({\n ...route,\n errorCodes: route.errorCodes\n ? Array.from(new Set([...route.errorCodes, \"feature_disabled\"]))\n : [\"feature_disabled\"],\n handler: async function (input, helpers) {\n if (!organizationsEnabled) {\n return helpers.error(\n { message: \"Organizations are disabled\", code: \"feature_disabled\" },\n 403,\n );\n }\n return (route.handler as typeof route.handler).call(this, input, helpers);\n },\n })) as typeof defineRoute;\n\n return [\n defineOrganizationRoute({\n method: \"POST\",\n path: \"/organizations\",\n inputSchema: createOrganizationInputSchema,\n outputSchema: z.object({\n organization: organizationSchema,\n member: memberSchema,\n }),\n errorCodes: [\n \"invalid_input\",\n \"organization_slug_taken\",\n \"permission_denied\",\n \"limit_reached\",\n \"session_invalid\",\n ],\n handler: async function ({ input, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n let body: z.infer<typeof createOrganizationInputSchema> | null = null;\n let inputError: unknown = null;\n try {\n body = await input.valid();\n } catch (err) {\n inputError = err;\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.createOrganizationWithSession({\n sessionId,\n input: body,\n inputError,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"input_invalid\") {\n if (inputError) {\n throw inputError;\n }\n return error({ message: \"Invalid input\", code: \"invalid_input\" }, 400);\n }\n\n if (result.code === \"organization_slug_taken\") {\n return error(\n { message: \"Organization slug taken\", code: \"organization_slug_taken\" },\n 400,\n );\n }\n\n if (result.code === \"invalid_slug\") {\n return error({ message: \"Invalid input\", code: \"invalid_input\" }, 400);\n }\n\n if (result.code === \"limit_reached\") {\n return error({ message: \"Limit reached\", code: \"limit_reached\" }, 400);\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({\n organization: serializeOrganization(result.organization),\n member: serializeMember(result.member),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"GET\",\n path: \"/organizations\",\n queryParameters: [\"pageSize\", \"cursor\", \"sessionId\"],\n outputSchema: z.object({\n organizations: z.array(\n z.object({\n organization: organizationSchema,\n member: memberSchema,\n }),\n ),\n cursor: z.string().optional(),\n hasNextPage: z.boolean(),\n }),\n errorCodes: [\"invalid_input\", \"session_invalid\"],\n handler: async function ({ query, headers }, { json, error }) {\n const parsed = pageQuerySchema.safeParse(Object.fromEntries(query.entries()));\n if (!parsed.success) {\n return error({ message: \"Invalid query parameters\", code: \"invalid_input\" }, 400);\n }\n\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const rawCursor = parseCursor(query.get(\"cursor\"));\n const cursor =\n rawCursor && (rawCursor.indexName === \"_primary\" || rawCursor.indexName === \"primary\")\n ? rawCursor\n : undefined;\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.getOrganizationsForSession({\n sessionId,\n pageSize: parsed.data.pageSize,\n cursor,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({\n organizations: result.organizations.map((entry) => ({\n organization: serializeOrganization(entry.organization),\n member: serializeMember(entry.member),\n })),\n cursor: result.cursor,\n hasNextPage: result.hasNextPage,\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"GET\",\n path: \"/organizations/active\",\n queryParameters: [\"sessionId\"],\n outputSchema: z\n .object({\n organization: organizationSchema,\n member: memberSchema,\n })\n .nullable(),\n errorCodes: [\"session_invalid\"],\n handler: async function ({ headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.getActiveOrganizationForSession({\n sessionId,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (!result.data) {\n return json(null);\n }\n\n return json({\n organization: serializeOrganization(result.data.organization),\n member: serializeMember(result.data.member),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"POST\",\n path: \"/organizations/active\",\n queryParameters: [\"sessionId\"],\n inputSchema: z.object({\n organizationId: z.string(),\n }),\n outputSchema: z.object({\n organization: organizationSchema,\n member: memberSchema,\n }),\n errorCodes: [\"organization_not_found\", \"membership_not_found\", \"session_invalid\"],\n handler: async function ({ input, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const body = await input.valid();\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.setActiveOrganizationForSession({\n sessionId,\n organizationId: body.organizationId,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n if (result.code === \"membership_not_found\") {\n return error({ message: \"Membership not found\", code: \"membership_not_found\" }, 404);\n }\n\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({\n organization: serializeOrganization(result.organization),\n member: serializeMember(result.member),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"GET\",\n path: \"/organizations/invitations\",\n queryParameters: [\"sessionId\"],\n outputSchema: z.object({\n invitations: z.array(\n z.object({\n invitation: invitationSchema,\n organization: organizationSchema,\n }),\n ),\n }),\n errorCodes: [\"session_invalid\"],\n handler: async function ({ headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.listInvitationsForSession({ sessionId })])\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({\n invitations: result.invitations.map((entry) => ({\n invitation: serializeInvitation(entry.invitation),\n organization: serializeOrganization(entry.organization),\n })),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"PATCH\",\n path: \"/organizations/invitations/:invitationId\",\n queryParameters: [\"sessionId\"],\n inputSchema: z.object({\n action: z.enum([\"accept\", \"reject\", \"cancel\"]),\n token: z.string().optional(),\n }),\n outputSchema: z.object({\n invitation: invitationSchema,\n }),\n errorCodes: [\n \"invitation_not_found\",\n \"invitation_expired\",\n \"permission_denied\",\n \"invalid_token\",\n \"limit_reached\",\n \"session_invalid\",\n ],\n handler: async function ({ input, pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const body = await input.valid();\n\n if ((body.action === \"accept\" || body.action === \"reject\") && !body.token) {\n return error({ message: \"Invalid token\", code: \"invalid_token\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.respondToInvitationWithSession({\n sessionId,\n invitationId: pathParams.invitationId,\n action: body.action,\n token: body.token,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"invalid_token\") {\n return error({ message: \"Invalid token\", code: \"invalid_token\" }, 400);\n }\n\n if (result.code === \"invitation_expired\") {\n return error({ message: \"Invitation expired\", code: \"invitation_expired\" }, 400);\n }\n\n if (result.code === \"limit_reached\") {\n return error({ message: \"Limit reached\", code: \"limit_reached\" }, 400);\n }\n\n if (result.code === \"permission_denied\") {\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return error({ message: \"Invitation not found\", code: \"invitation_not_found\" }, 404);\n }\n\n return json({\n invitation: serializeInvitation(result.invitation),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"GET\",\n path: \"/organizations/:organizationId\",\n queryParameters: [\"sessionId\"],\n outputSchema: z.object({\n organization: organizationSchema,\n member: memberSchema,\n }),\n errorCodes: [\"organization_not_found\", \"permission_denied\", \"session_invalid\"],\n handler: async function ({ pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.getOrganizationForSession({\n sessionId,\n organizationId: pathParams.organizationId,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n if (result.code === \"permission_denied\") {\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({\n organization: serializeOrganization(result.organization),\n member: serializeMember(result.member),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"PATCH\",\n path: \"/organizations/:organizationId\",\n queryParameters: [\"sessionId\"],\n inputSchema: updateOrganizationInputSchema,\n outputSchema: z.object({\n organization: organizationSchema,\n }),\n errorCodes: [\n \"invalid_input\",\n \"organization_not_found\",\n \"organization_slug_taken\",\n \"permission_denied\",\n \"session_invalid\",\n ],\n handler: async function ({ input, pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const body = await input.valid();\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.updateOrganizationWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n patch: body,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n if (result.code === \"organization_slug_taken\") {\n return error(\n { message: \"Organization slug taken\", code: \"organization_slug_taken\" },\n 400,\n );\n }\n\n if (result.code === \"permission_denied\") {\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return error({ message: \"Invalid input\", code: \"invalid_input\" }, 400);\n }\n\n return json({\n organization: serializeOrganization(result.organization),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"DELETE\",\n path: \"/organizations/:organizationId\",\n queryParameters: [\"sessionId\"],\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"organization_not_found\", \"permission_denied\", \"session_invalid\"],\n handler: async function ({ pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.deleteOrganizationWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({ success: true });\n },\n }),\n\n defineOrganizationRoute({\n method: \"GET\",\n path: \"/organizations/:organizationId/members\",\n queryParameters: [\"pageSize\", \"cursor\", \"sessionId\"],\n outputSchema: z.object({\n members: z.array(memberSchema),\n cursor: z.string().optional(),\n hasNextPage: z.boolean(),\n }),\n errorCodes: [\n \"invalid_input\",\n \"organization_not_found\",\n \"permission_denied\",\n \"session_invalid\",\n ],\n handler: async function ({ pathParams, query, headers }, { json, error }) {\n const parsed = pageQuerySchema.safeParse(Object.fromEntries(query.entries()));\n if (!parsed.success) {\n return error({ message: \"Invalid query parameters\", code: \"invalid_input\" }, 400);\n }\n\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n const cursor = parseCursor(query.get(\"cursor\"));\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.listOrganizationMembersWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n pageSize: parsed.data.pageSize,\n cursor,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({\n members: result.members.map((member) => serializeMember(member)),\n cursor: result.cursor,\n hasNextPage: result.hasNextPage,\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"POST\",\n path: \"/organizations/:organizationId/members\",\n queryParameters: [\"sessionId\"],\n inputSchema: z.object({\n userId: z.string(),\n roles: z.array(z.string()).optional(),\n }),\n outputSchema: z.object({\n member: memberSchema,\n }),\n errorCodes: [\n \"organization_not_found\",\n \"permission_denied\",\n \"member_already_exists\",\n \"limit_reached\",\n \"session_invalid\",\n ],\n handler: async function ({ input, pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n const body = await input.valid();\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.createOrganizationMemberWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n userId: body.userId,\n roles: body.roles,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n if (result.code === \"member_already_exists\") {\n return error(\n { message: \"Member already exists\", code: \"member_already_exists\" },\n 400,\n );\n }\n\n if (result.code === \"limit_reached\") {\n return error({ message: \"Limit reached\", code: \"limit_reached\" }, 400);\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({\n member: serializeMember(result.member),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"PATCH\",\n path: \"/organizations/:organizationId/members/:memberId\",\n queryParameters: [\"sessionId\"],\n inputSchema: z.object({\n roles: z.array(z.string()).min(1),\n }),\n outputSchema: z.object({\n member: memberSchema,\n }),\n errorCodes: [\"member_not_found\", \"permission_denied\", \"last_owner\", \"session_invalid\"],\n handler: async function ({ input, pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n const body = await input.valid();\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.updateOrganizationMemberRolesWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n memberId: pathParams.memberId,\n roles: body.roles,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"member_not_found\") {\n return error({ message: \"Member not found\", code: \"member_not_found\" }, 404);\n }\n\n if (result.code === \"last_owner\") {\n return error({ message: \"Last owner\", code: \"last_owner\" }, 400);\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({\n member: serializeMember(result.member),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"DELETE\",\n path: \"/organizations/:organizationId/members/:memberId\",\n queryParameters: [\"sessionId\"],\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"member_not_found\", \"permission_denied\", \"last_owner\", \"session_invalid\"],\n handler: async function ({ pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.deleteOrganizationMemberWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n memberId: pathParams.memberId,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"member_not_found\") {\n return error({ message: \"Member not found\", code: \"member_not_found\" }, 404);\n }\n\n if (result.code === \"last_owner\") {\n return error({ message: \"Last owner\", code: \"last_owner\" }, 400);\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({ success: true });\n },\n }),\n\n defineOrganizationRoute({\n method: \"GET\",\n path: \"/organizations/:organizationId/invitations\",\n queryParameters: [\"sessionId\"],\n outputSchema: z.object({\n invitations: z.array(invitationSchema),\n }),\n errorCodes: [\"organization_not_found\", \"permission_denied\", \"session_invalid\"],\n handler: async function ({ pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.listOrganizationInvitationsWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({\n invitations: result.invitations.map(serializeInvitation),\n });\n },\n }),\n\n defineOrganizationRoute({\n method: \"POST\",\n path: \"/organizations/:organizationId/invitations\",\n queryParameters: [\"sessionId\"],\n inputSchema: z.object({\n email: z.email(),\n roles: z.array(z.string()).optional(),\n }),\n outputSchema: z.object({\n invitation: invitationSchema,\n }),\n errorCodes: [\n \"organization_not_found\",\n \"permission_denied\",\n \"limit_reached\",\n \"session_invalid\",\n ],\n handler: async function ({ input, pathParams, headers, query }, { json, error }) {\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const body = await input.valid();\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [\n services.createOrganizationInvitationWithSession({\n sessionId,\n organizationId: pathParams.organizationId,\n email: body.email,\n roles: body.roles,\n }),\n ])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"session_invalid\") {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n if (result.code === \"organization_not_found\") {\n return error(\n { message: \"Organization not found\", code: \"organization_not_found\" },\n 404,\n );\n }\n\n if (result.code === \"limit_reached\") {\n return error({ message: \"Limit reached\", code: \"limit_reached\" }, 400);\n }\n\n return error({ message: \"Permission denied\", code: \"permission_denied\" }, 403);\n }\n\n return json({\n invitation: serializeInvitation(result.invitation),\n });\n },\n }),\n ];\n },\n);\n","import type { FragnoId } from \"@fragno-dev/db/schema\";\nimport { z } from \"zod\";\n\nimport { defineRoute, defineRoutes } from \"@fragno-dev/core\";\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport type { Role, authFragmentDefinition } from \"..\";\nimport type { AuthHooksMap } from \"../hooks\";\nimport { invitationSummarySchema, memberSchema, organizationSchema } from \"../organization/schemas\";\nimport {\n serializeInvitationSummary,\n serializeMember,\n serializeOrganization,\n} from \"../organization/serializers\";\nimport type {\n Organization,\n OrganizationInvitation,\n OrganizationInvitationStatus,\n OrganizationMember,\n} from \"../organization/types\";\nimport { toExternalId } from \"../organization/utils\";\nimport { authSchema } from \"../schema\";\nimport { mapUserSummary } from \"../user/summary\";\nimport {\n buildClearCookieHeader,\n buildSetCookieHeader,\n extractSessionId,\n type CookieOptions,\n} from \"../utils/cookie\";\nimport { resolveSessionSeedFromMembers, type SessionSeedInput } from \"./session-seed\";\n\ntype AuthServiceContext = DatabaseServiceContext<AuthHooksMap>;\n\nconst requiredOrganizationServiceNames = [\n \"getOrganizationsForUser\",\n \"listOrganizationMemberRolesForMembers\",\n \"listOrganizationInvitationsForUser\",\n \"getActiveOrganization\",\n] as const;\n\nexport function assertOrganizationServices(\n services: Record<string, unknown>,\n): asserts services is Record<\n (typeof requiredOrganizationServiceNames)[number],\n (...args: unknown[]) => unknown\n> {\n const missing = requiredOrganizationServiceNames.filter(\n (name) => typeof services[name] !== \"function\",\n );\n if (missing.length > 0) {\n throw new Error(`Missing organization services: ${missing.join(\", \")}`);\n }\n}\n\ntype OrganizationRow = {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n};\n\ntype ActiveOrganizationRow = {\n id: unknown;\n};\n\ntype OrganizationMemberRoleRow = {\n role: string;\n};\n\ntype OrganizationMemberRow = {\n id: unknown;\n createdAt: Date;\n updatedAt: Date;\n organization?: OrganizationRow | null;\n roles?: OrganizationMemberRoleRow | OrganizationMemberRoleRow[] | null;\n};\n\ntype OrganizationInvitationRow = {\n id: unknown;\n organizationId: unknown;\n email: string;\n roles: unknown;\n status: string;\n token: string;\n inviterId: unknown;\n expiresAt: Date;\n createdAt: Date;\n respondedAt: Date | null;\n organization?: OrganizationRow | null;\n};\n\ntype SessionOwnerRow = {\n id: unknown;\n email: string;\n role: Role;\n};\n\ntype SessionMemberRow = {\n id: FragnoId;\n expiresAt: Date;\n sessionOwner?: SessionOwnerRow | null;\n sessionActiveOrganization?: ActiveOrganizationRow | null;\n sessionMembers?: OrganizationMemberRow | OrganizationMemberRow[] | null;\n};\n\ntype SessionInvitationRow = {\n id: FragnoId;\n expiresAt: Date;\n sessionActiveOrganization?: ActiveOrganizationRow | null;\n sessionOwner?:\n | (SessionOwnerRow & {\n invitations?: OrganizationInvitationRow | OrganizationInvitationRow[] | null;\n })\n | null;\n};\n\ntype SessionExpiryRow = {\n id: FragnoId;\n};\n\ntype SessionSeedMemberRow = {\n createdAt: Date;\n organizationMemberOrganization?: OrganizationRow | null;\n};\n\nconst organizationSelect = [\n \"id\",\n \"name\",\n \"slug\",\n \"logoUrl\",\n \"metadata\",\n \"createdBy\",\n \"createdAt\",\n \"updatedAt\",\n \"deletedAt\",\n] as const;\n\nconst normalizeMany = <T>(value: T | T[] | null | undefined): T[] => {\n if (!value) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n};\n\nconst mapOrganizationRow = (organization: OrganizationRow): Organization => ({\n id: toExternalId(organization.id),\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: (organization.metadata ?? null) as Record<string, unknown> | null,\n createdBy: toExternalId(organization.createdBy),\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n});\n\nconst mapMemberRow = (\n member: OrganizationMemberRow,\n organizationId: string,\n userId: string,\n roles: string[],\n): OrganizationMember<string> => ({\n id: toExternalId(member.id),\n organizationId,\n userId,\n roles,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n});\n\nconst mapInvitationRow = (\n invitation: OrganizationInvitationRow,\n organizationId: string,\n): OrganizationInvitation<string> => ({\n id: toExternalId(invitation.id),\n organizationId,\n email: invitation.email,\n roles: Array.isArray(invitation.roles) ? (invitation.roles as string[]) : [],\n status: invitation.status as OrganizationInvitationStatus,\n token: invitation.token,\n inviterId: toExternalId(invitation.inviterId),\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: invitation.respondedAt ?? null,\n});\n\nconst buildOrganizationsFromRows = (\n rows: SessionMemberRow[],\n): Array<{\n organization: ReturnType<typeof serializeOrganization>;\n member: ReturnType<typeof serializeMember>;\n}> => {\n const organizationsByMemberId = new Map<\n string,\n {\n organization: Organization;\n member: OrganizationMember<string>;\n roles: Set<string>;\n }\n >();\n\n for (const row of rows) {\n const sessionOwner = row.sessionOwner;\n if (!sessionOwner) {\n continue;\n }\n const userId = toExternalId(sessionOwner.id);\n const members = normalizeMany(row.sessionMembers) as OrganizationMemberRow[];\n for (const member of members) {\n const organizationRow = member.organization;\n if (!organizationRow || organizationRow.deletedAt) {\n continue;\n }\n const memberId = toExternalId(member.id);\n let entry = organizationsByMemberId.get(memberId);\n if (!entry) {\n const organization = mapOrganizationRow(organizationRow);\n entry = {\n organization,\n member: mapMemberRow(member, organization.id, userId, []),\n roles: new Set(),\n };\n organizationsByMemberId.set(memberId, entry);\n }\n\n const roles = normalizeMany(member.roles) as OrganizationMemberRoleRow[];\n for (const role of roles) {\n if (role?.role) {\n entry.roles.add(role.role);\n }\n }\n }\n }\n\n return Array.from(organizationsByMemberId.values()).map((entry) => ({\n organization: serializeOrganization(entry.organization),\n member: serializeMember({\n ...entry.member,\n roles: Array.from(entry.roles),\n }),\n }));\n};\n\nconst buildInvitationsFromRows = (\n rows: SessionInvitationRow[],\n): Array<{\n invitation: ReturnType<typeof serializeInvitationSummary>;\n organization: ReturnType<typeof serializeOrganization>;\n}> => {\n const invitations: Array<{\n invitation: ReturnType<typeof serializeInvitationSummary>;\n organization: ReturnType<typeof serializeOrganization>;\n }> = [];\n const seenInvitationIds = new Set<string>();\n\n for (const row of rows) {\n const sessionOwner = row.sessionOwner;\n if (!sessionOwner) {\n continue;\n }\n const invitationsForUser = normalizeMany(\n sessionOwner.invitations,\n ) as OrganizationInvitationRow[];\n for (const invitation of invitationsForUser) {\n if (!invitation || invitation.status !== \"pending\") {\n continue;\n }\n const organizationRow = invitation.organization;\n if (!organizationRow || organizationRow.deletedAt) {\n continue;\n }\n const invitationId = toExternalId(invitation.id);\n if (seenInvitationIds.has(invitationId)) {\n continue;\n }\n seenInvitationIds.add(invitationId);\n\n const organization = mapOrganizationRow(organizationRow);\n const mappedInvitation = mapInvitationRow(invitation, organization.id);\n invitations.push({\n invitation: serializeInvitationSummary(mappedInvitation),\n organization: serializeOrganization(organization),\n });\n }\n }\n\n return invitations;\n};\n\nexport function createSessionServices(cookieOptions?: CookieOptions) {\n const services = {\n resolveSessionSeedForUser: function (\n this: AuthServiceContext,\n userId: string,\n session?: SessionSeedInput | null,\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.find(\"organizationMember\", (b) =>\n b\n .whereIndex(\"idx_org_member_user\", (eb) => eb(\"userId\", \"=\", userId))\n .join((j) =>\n j.organizationMemberOrganization((ob) =>\n ob.select([\"id\", \"deletedAt\", \"createdAt\"]),\n ),\n ),\n ),\n )\n .transformRetrieve(([members]) => {\n return resolveSessionSeedFromMembers(\n (members as SessionSeedMemberRow[]).map((member) => ({\n createdAt: member.createdAt,\n organization: member.organizationMemberOrganization ?? null,\n })),\n session,\n );\n })\n .mutate(({ retrieveResult }) => retrieveResult)\n .build();\n },\n /**\n * Build a Set-Cookie header value for the session id.\n */\n buildSessionCookie: function (sessionId: string): string {\n return buildSetCookieHeader(sessionId, cookieOptions);\n },\n /**\n * Create a session for a user, rejecting banned or missing users.\n *\n * When `options.activeOrganizationId` is provided, it is written into the session as-is.\n * This function does not verify that the user is a member of that organization; callers\n * must validate membership before passing the id.\n */\n createSession: function (\n this: AuthServiceContext,\n userId: string,\n options?: { activeOrganizationId?: string | null },\n ) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"user\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", userId))),\n )\n .mutate(({ uow, retrieveResult: [user] }) => {\n if (!user) {\n return { ok: false as const, code: \"user_not_found\" as const };\n }\n if (user.bannedAt) {\n return { ok: false as const, code: \"user_banned\" as const };\n }\n\n const expiresAt = uow.now().plus({ days: 30 });\n const id = uow.create(\"session\", {\n userId,\n activeOrganizationId: options?.activeOrganizationId ?? null,\n expiresAt,\n });\n const userSummary = mapUserSummary(user);\n\n uow.triggerHook(\"onSessionCreated\", {\n session: {\n id: id.valueOf(),\n user: userSummary,\n expiresAt,\n activeOrganizationId: options?.activeOrganizationId ?? null,\n },\n actor: userSummary,\n });\n\n return {\n ok: true as const,\n session: {\n id: id.valueOf(),\n userId,\n expiresAt,\n activeOrganizationId: options?.activeOrganizationId ?? null,\n },\n };\n })\n .build();\n },\n /**\n * Validate a session and return user info or null when invalid.\n */\n validateSession: function (this: AuthServiceContext, sessionId: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\"]))),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n if (!session) {\n return null;\n }\n if (!session.sessionOwner) {\n return null;\n }\n\n return {\n id: session.id.valueOf(),\n userId: session.userId as unknown as string,\n user: {\n id: session.sessionOwner.id.valueOf(),\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n },\n };\n })\n .build();\n },\n /**\n * Invalidate a session and emit session invalidation hooks.\n */\n invalidateSession: function (this: AuthServiceContext, sessionId: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId))\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }) => {\n if (!session) {\n return false;\n }\n\n uow.delete(\"session\", session.id, (b) => b.check());\n if (session.sessionOwner) {\n const userSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n uow.triggerHook(\"onSessionInvalidated\", {\n session: {\n id: session.id.valueOf(),\n user: userSummary,\n expiresAt: session.expiresAt,\n activeOrganizationId: session.activeOrganizationId\n ? String(session.activeOrganizationId)\n : null,\n },\n actor: userSummary,\n });\n }\n return true;\n })\n .build();\n },\n /**\n * Resolve a session from request headers for sign-in checks.\n */\n getSession: function (this: AuthServiceContext, headers: Headers) {\n const sessionId = extractSessionId(headers);\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId ?? \"\"), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\"]))),\n )\n .findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId ?? \"\"), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n ),\n )\n .mutate(({ uow, retrieveResult: [session, expiredSession] }) => {\n if (expiredSession) {\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n if (!session || !sessionId) {\n return undefined;\n }\n if (!session.sessionOwner) {\n return undefined;\n }\n\n return {\n userId: session.sessionOwner.id.valueOf(),\n email: session.sessionOwner.email,\n };\n })\n .build();\n },\n };\n return services;\n}\n\nexport const sessionRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ services, config }) => {\n return [\n defineRoute({\n method: \"POST\",\n path: \"/sign-out\",\n inputSchema: z\n .object({\n sessionId: z.string().optional(),\n })\n .optional(),\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"session_not_found\"],\n handler: async function ({ input, headers }, { json, error }) {\n const body = await input.valid();\n\n // Extract session ID from cookies first, then body\n const sessionId = extractSessionId(headers, null, body?.sessionId);\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_not_found\" }, 400);\n }\n\n const [success] = await this.handlerTx()\n .withServiceCalls(() => [services.invalidateSession(sessionId)])\n .execute();\n\n // Build response with clear cookie header\n const clearCookieHeader = buildClearCookieHeader(config.cookieOptions ?? {});\n\n if (!success) {\n // Still clear the cookie even if session not found in DB\n return json(\n { success: false },\n {\n headers: {\n \"Set-Cookie\": clearCookieHeader,\n },\n },\n );\n }\n\n return json(\n { success: true },\n {\n headers: {\n \"Set-Cookie\": clearCookieHeader,\n },\n },\n );\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/me\",\n queryParameters: [\"sessionId\"],\n outputSchema: z.object({\n user: z.object({\n id: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n }),\n organizations: z.array(\n z.object({\n organization: organizationSchema,\n member: memberSchema,\n }),\n ),\n activeOrganization: z\n .object({\n organization: organizationSchema,\n member: memberSchema,\n })\n .nullable(),\n invitations: z.array(\n z.object({\n invitation: invitationSummarySchema,\n organization: organizationSchema,\n }),\n ),\n }),\n errorCodes: [\"session_invalid\"],\n handler: async function ({ query, headers }, { json, error }) {\n // Extract session ID from cookies first, then query params\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n if (config.organizations !== false) {\n assertOrganizationServices(services);\n }\n\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) => {\n const uow = forSchema(authSchema);\n const scheduleExpiredLookup = () => {\n uow.findFirst(\"session\", (b) =>\n b.whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \"<=\", eb.now())),\n ),\n );\n };\n\n if (config.organizations === false) {\n uow.find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((jb) => jb.sessionOwner((ub) => ub.select([\"id\", \"email\", \"role\"]))),\n );\n scheduleExpiredLookup();\n return uow;\n }\n\n uow.find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((jb) =>\n jb\n .sessionOwner((ub) => ub.select([\"id\", \"email\", \"role\"]))\n .sessionActiveOrganization((ob) => ob.select([\"id\"]))\n .sessionMembers((mb) =>\n mb.join((jb2) =>\n jb2[\"organization\"]((ob) => ob.select(organizationSelect))[\"roles\"](\n (rb) => rb.select([\"role\"]),\n ),\n ),\n ),\n ),\n );\n\n uow.find(\"session\", (b) =>\n b\n .whereIndex(\"idx_session_id_expiresAt\", (eb) =>\n eb.and(eb(\"id\", \"=\", sessionId), eb(\"expiresAt\", \">\", eb.now())),\n )\n .join((jb) =>\n jb.sessionOwner((ub) =>\n ub\n .select([\"id\", \"email\", \"role\"])\n .join((jb2) =>\n jb2[\"invitations\"]((ib) =>\n ib.join((jb3) =>\n jb3[\"organization\"]((ob) => ob.select(organizationSelect)),\n ),\n ),\n ),\n ),\n ),\n );\n\n scheduleExpiredLookup();\n return uow;\n })\n .transformRetrieve((retrieveResult) => {\n if (config.organizations === false) {\n const [sessions, expiredSession] = retrieveResult as unknown as [\n SessionMemberRow[],\n SessionExpiryRow | null,\n ];\n return {\n session: sessions[0] ?? null,\n organizations: [],\n invitations: [],\n activeOrganizationId: null,\n expiredSession,\n };\n }\n\n const [memberRows, invitationRows, expiredSession] = retrieveResult as unknown as [\n SessionMemberRow[],\n SessionInvitationRow[],\n SessionExpiryRow | null,\n ];\n const session = memberRows[0] ?? invitationRows[0] ?? null;\n const activeOrganizationId =\n session?.sessionActiveOrganization && session.sessionActiveOrganization.id\n ? toExternalId(session.sessionActiveOrganization.id)\n : null;\n\n return {\n session,\n organizations: buildOrganizationsFromRows(memberRows),\n invitations: buildInvitationsFromRows(invitationRows),\n activeOrganizationId,\n expiredSession,\n };\n })\n .mutate(({ forSchema, retrieveResult }) => {\n const { session, expiredSession } = retrieveResult;\n if (expiredSession) {\n const uow = forSchema(authSchema);\n uow.delete(\"session\", expiredSession.id, (b) => b.check());\n }\n if (!session) {\n return { invalid: true as const };\n }\n if (!session.sessionOwner) {\n return { invalid: true as const };\n }\n return { invalid: false as const };\n })\n .transform(({ retrieveResult, mutateResult }) => {\n const { session, organizations, invitations, activeOrganizationId } = retrieveResult;\n if (mutateResult.invalid || !session || !session.sessionOwner) {\n return { ok: false as const };\n }\n\n const user = session.sessionOwner;\n const userId = toExternalId(user.id);\n const activeOrganization = activeOrganizationId\n ? (organizations.find((entry) => entry.organization.id === activeOrganizationId) ??\n null)\n : null;\n\n return {\n ok: true as const,\n data: {\n user: {\n id: userId,\n email: user.email,\n role: user.role as Role,\n },\n organizations,\n activeOrganization,\n invitations,\n },\n };\n })\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json(result.data);\n },\n }),\n ];\n },\n);\n","// Password hashing utilities using WebCrypto\nexport async function hashPassword(password: string): Promise<string> {\n const encoder = new TextEncoder();\n const salt = crypto.getRandomValues(new Uint8Array(16));\n const iterations = 100000;\n\n const keyMaterial = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(password),\n \"PBKDF2\",\n false,\n [\"deriveBits\"],\n );\n\n const hashBuffer = await crypto.subtle.deriveBits(\n {\n name: \"PBKDF2\",\n salt: salt,\n iterations: iterations,\n hash: \"SHA-256\",\n },\n keyMaterial,\n 256,\n );\n\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const saltArray = Array.from(salt);\n\n return `${saltArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\")}:${iterations}:${hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\nexport async function verifyPassword(password: string, storedHash: string): Promise<boolean> {\n const parts = storedHash.split(\":\");\n if (parts.length !== 3) {\n return false;\n }\n\n const [saltHex, iterationsStr, hashHex] = parts;\n const iterations = Number.parseInt(iterationsStr, 10);\n const isHex = (value: string) => /^[0-9a-f]+$/i.test(value) && value.length % 2 === 0;\n\n if (!saltHex || !hashHex || !isHex(saltHex) || !isHex(hashHex)) {\n return false;\n }\n\n if (!Number.isFinite(iterations) || iterations <= 0) {\n return false;\n }\n\n const saltPairs = saltHex.match(/.{1,2}/g);\n const hashPairs = hashHex.match(/.{1,2}/g);\n\n if (!saltPairs || !hashPairs) {\n return false;\n }\n\n const salt = new Uint8Array(saltPairs.map((byte) => Number.parseInt(byte, 16)));\n const storedHashBytes = new Uint8Array(hashPairs.map((byte) => Number.parseInt(byte, 16)));\n\n const encoder = new TextEncoder();\n const keyMaterial = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(password),\n \"PBKDF2\",\n false,\n [\"deriveBits\"],\n );\n\n const hashBuffer = await crypto.subtle.deriveBits(\n {\n name: \"PBKDF2\",\n salt: salt,\n iterations: iterations,\n hash: \"SHA-256\",\n },\n keyMaterial,\n 256,\n );\n\n const hashArray = new Uint8Array(hashBuffer);\n\n if (hashArray.length !== storedHashBytes.length) {\n return false;\n }\n\n let isEqual = true;\n for (let i = 0; i < hashArray.length; i++) {\n if (hashArray[i] !== storedHashBytes[i]) {\n isEqual = false;\n }\n }\n return isEqual;\n}\n","import { z } from \"zod\";\n\nimport { defineRoute, defineRoutes } from \"@fragno-dev/core\";\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport type { authFragmentDefinition } from \"..\";\nimport type { AuthHooksMap, BeforeCreateUserHook } from \"../hooks\";\nimport { authSchema } from \"../schema\";\nimport { resolveSessionSeedFromMembers, sessionSeedSchema } from \"../session/session-seed\";\nimport { buildSetCookieHeader, extractSessionId } from \"../utils/cookie\";\nimport { createAutoOrganization, type AutoCreateOrganizationOptions } from \"./auto-organization\";\nimport { hashPassword, verifyPassword } from \"./password\";\nimport { mapUserSummary } from \"./summary\";\n\ntype AuthServiceContext = DatabaseServiceContext<AuthHooksMap>;\ntype SessionSeedMemberRow = {\n createdAt: Date;\n organizationMemberOrganization?: {\n id: unknown;\n deletedAt: Date | null;\n } | null;\n};\n\nconst normalizeMany = <T>(value: T | T[] | null | undefined): T[] => {\n if (!value) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n};\n\nconst collectSessionSeedMembers = <\n TUser extends {\n userOrganizationMembers?: SessionSeedMemberRow | SessionSeedMemberRow[] | null;\n },\n>(\n rows: TUser[],\n) => {\n return rows.flatMap((user) =>\n normalizeMany(user.userOrganizationMembers).map((member) => ({\n createdAt: member.createdAt,\n organization: member.organizationMemberOrganization ?? null,\n })),\n );\n};\n\nexport function createUserServices(\n options?: AutoCreateOrganizationOptions,\n beforeCreateUser?: BeforeCreateUserHook,\n) {\n const runBeforeCreateUser = (email: string, role: \"user\" | \"admin\") => {\n beforeCreateUser?.({ email, role });\n };\n\n const createUserUnvalidated = function (\n this: AuthServiceContext,\n email: string,\n passwordHash: string,\n role: \"user\" | \"admin\" = \"user\",\n autoCreateOptions?: AutoCreateOrganizationOptions,\n ) {\n return this.serviceTx(authSchema)\n .mutate(({ uow }) => {\n runBeforeCreateUser(email, role);\n const now = new Date();\n const id = uow.create(\"user\", {\n email,\n passwordHash,\n role,\n });\n const userSummary = mapUserSummary({\n id: id.valueOf(),\n email,\n role,\n bannedAt: null,\n });\n\n const autoOrganization = createAutoOrganization(uow, {\n userId: id.valueOf(),\n email,\n now,\n options: autoCreateOptions ?? options,\n });\n\n uow.triggerHook(\"onUserCreated\", {\n user: userSummary,\n actor: null,\n });\n\n if (autoOrganization) {\n uow.triggerHook(\"onOrganizationCreated\", {\n organization: autoOrganization.organization,\n actor: userSummary,\n });\n uow.triggerHook(\"onMemberAdded\", {\n organization: autoOrganization.organization,\n member: autoOrganization.member,\n actor: userSummary,\n });\n }\n\n return {\n id: id.valueOf(),\n email,\n role,\n };\n })\n .build();\n };\n\n return {\n /**\n * Create a user without email uniqueness checks or session creation.\n */\n createUserUnvalidated,\n /**\n * Fetch a user by email with password hash metadata.\n */\n getUserByEmail: function (this: AuthServiceContext, email: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"user\", (b) =>\n b.whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"=\", email)),\n ),\n )\n .transformRetrieve(([user]) =>\n user\n ? {\n id: user.id.valueOf(),\n email: user.email,\n passwordHash: user.passwordHash ?? null,\n role: user.role as \"user\" | \"admin\",\n }\n : null,\n )\n .build();\n },\n /**\n * Update a user's role without session enforcement.\n */\n updateUserRole: function (this: AuthServiceContext, userId: string, role: \"user\" | \"admin\") {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"user\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", userId))),\n )\n .mutate(({ uow, retrieveResult: [user] }) => {\n uow.update(\"user\", userId, (b) => b.set({ role }));\n\n if (user) {\n uow.triggerHook(\"onUserRoleUpdated\", {\n user: mapUserSummary({\n id: userId,\n email: user.email,\n role,\n bannedAt: user.bannedAt ?? null,\n }),\n actor: null,\n });\n }\n return { success: true };\n })\n .build();\n },\n /**\n * Update a user's password hash without session enforcement.\n */\n updateUserPassword: function (this: AuthServiceContext, userId: string, passwordHash: string) {\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"user\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", userId))),\n )\n .mutate(({ uow, retrieveResult: [user] }) => {\n uow.update(\"user\", userId, (b) => b.set({ passwordHash }));\n\n if (user) {\n uow.triggerHook(\"onUserPasswordChanged\", {\n user: mapUserSummary({\n id: userId,\n email: user.email,\n role: user.role,\n bannedAt: user.bannedAt ?? null,\n }),\n actor: null,\n });\n }\n return { success: true };\n })\n .build();\n },\n /**\n * Create a user and session for email/password sign-up.\n */\n signUpWithSession: function (\n this: AuthServiceContext,\n email: string,\n passwordHash: string,\n autoCreateOptions?: AutoCreateOrganizationOptions,\n ) {\n const expiresAt = new Date();\n expiresAt.setDate(expiresAt.getDate() + 30); // 30 days from now\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"user\", (b) =>\n b.whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"=\", email)),\n ),\n )\n .mutate(({ uow, retrieveResult: [existingUser] }) => {\n if (existingUser) {\n return { ok: false as const, code: \"email_already_exists\" as const };\n }\n\n const now = new Date();\n runBeforeCreateUser(email, \"user\");\n\n const userId = uow.create(\"user\", {\n email,\n passwordHash,\n role: \"user\",\n });\n\n const autoOrganization = createAutoOrganization(uow, {\n userId: userId.valueOf(),\n email,\n now,\n options: autoCreateOptions ?? options,\n });\n\n const sessionId = uow.create(\"session\", {\n userId,\n activeOrganizationId: autoOrganization?.organization.id ?? null,\n expiresAt,\n });\n const userSummary = mapUserSummary({\n id: userId.valueOf(),\n email,\n role: \"user\",\n bannedAt: null,\n });\n\n uow.triggerHook(\"onUserCreated\", {\n user: userSummary,\n actor: userSummary,\n });\n uow.triggerHook(\"onSessionCreated\", {\n session: {\n id: sessionId.valueOf(),\n user: userSummary,\n expiresAt,\n activeOrganizationId: autoOrganization?.organization.id ?? null,\n },\n actor: userSummary,\n });\n\n if (autoOrganization) {\n uow.triggerHook(\"onOrganizationCreated\", {\n organization: autoOrganization.organization,\n actor: userSummary,\n });\n uow.triggerHook(\"onMemberAdded\", {\n organization: autoOrganization.organization,\n member: autoOrganization.member,\n actor: userSummary,\n });\n }\n\n return {\n ok: true as const,\n sessionId: sessionId.valueOf(),\n userId: userId.valueOf(),\n email,\n role: \"user\" as const,\n };\n })\n .build();\n },\n /**\n * Update a user's role with admin session enforcement.\n */\n updateUserRoleWithSession: function (\n this: AuthServiceContext,\n sessionId: string,\n userId: string,\n role: \"user\" | \"admin\",\n ) {\n const now = new Date();\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId))\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))),\n )\n .findFirst(\"user\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", userId))),\n )\n .mutate(({ uow, retrieveResult: [session, user] }) => {\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (session.expiresAt < now) {\n uow.delete(\"session\", session.id, (b) => b.check());\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (session.sessionOwner.role !== \"admin\") {\n return { ok: false as const, code: \"permission_denied\" as const };\n }\n\n uow.update(\"user\", userId, (b) => b.set({ role }));\n\n if (user) {\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n uow.triggerHook(\"onUserRoleUpdated\", {\n user: mapUserSummary({\n id: userId,\n email: user.email,\n role,\n bannedAt: user.bannedAt ?? null,\n }),\n actor: actorSummary,\n });\n }\n return { ok: true as const };\n })\n .build();\n },\n /**\n * Change the current session user's password.\n */\n changePasswordWithSession: function (\n this: AuthServiceContext,\n sessionId: string,\n passwordHash: string,\n ) {\n const now = new Date();\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findFirst(\"session\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", sessionId))\n .join((j) => j.sessionOwner((b) => b.select([\"id\", \"email\", \"role\", \"bannedAt\"]))),\n ),\n )\n .mutate(({ uow, retrieveResult: [session] }) => {\n if (!session || !session.sessionOwner) {\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n if (session.expiresAt < now) {\n uow.delete(\"session\", session.id, (b) => b.check());\n return { ok: false as const, code: \"session_invalid\" as const };\n }\n\n uow.update(\"user\", session.sessionOwner.id, (b) => b.set({ passwordHash }).check());\n const actorSummary = mapUserSummary({\n id: session.sessionOwner.id,\n email: session.sessionOwner.email,\n role: session.sessionOwner.role,\n bannedAt: session.sessionOwner.bannedAt ?? null,\n });\n uow.triggerHook(\"onUserPasswordChanged\", {\n user: actorSummary,\n actor: actorSummary,\n });\n return { ok: true as const };\n })\n .build();\n },\n };\n}\n\nexport const userActionsRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ services, config }) => {\n const emailAndPasswordEnabled = config.emailAndPassword?.enabled !== false;\n\n return [\n defineRoute({\n method: \"PATCH\",\n path: \"/users/:userId/role\",\n inputSchema: z.object({\n role: z.enum([\"user\", \"admin\"]),\n }),\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"invalid_input\", \"session_invalid\", \"permission_denied\"],\n handler: async function ({ input, pathParams, headers, query }, { json, error }) {\n const { role } = await input.valid();\n const { userId } = pathParams;\n\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.updateUserRoleWithSession(sessionId, userId, role)])\n .execute();\n\n if (!result.ok) {\n if (result.code === \"permission_denied\") {\n return error({ message: \"Unauthorized\", code: \"permission_denied\" }, 401);\n }\n\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({ success: true });\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/sign-up\",\n inputSchema: z.object({\n email: z.email(),\n password: z.string().min(8).max(100),\n }),\n outputSchema: z.object({\n sessionId: z.string(),\n userId: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n }),\n errorCodes: [\"email_already_exists\", \"invalid_input\", \"email_password_disabled\"],\n handler: async function ({ input }, { json, error }) {\n if (!emailAndPasswordEnabled) {\n return error(\n { message: \"Email/password auth is disabled\", code: \"email_password_disabled\" },\n 403,\n );\n }\n\n const { email, password } = await input.valid();\n\n const passwordHash = await hashPassword(password);\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.signUpWithSession(email, passwordHash)])\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Email already exists\", code: \"email_already_exists\" }, 400);\n }\n\n // Build response with Set-Cookie header\n const setCookieHeader = buildSetCookieHeader(result.sessionId, config.cookieOptions);\n\n return json(\n {\n sessionId: result.sessionId,\n userId: result.userId,\n email: result.email,\n role: result.role,\n },\n {\n headers: {\n \"Set-Cookie\": setCookieHeader,\n },\n },\n );\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/sign-in\",\n inputSchema: z.object({\n email: z.email(),\n password: z.string().min(8).max(100),\n session: sessionSeedSchema.optional(),\n }),\n outputSchema: z.object({\n sessionId: z.string(),\n userId: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n }),\n errorCodes: [\"invalid_credentials\", \"user_banned\", \"email_password_disabled\"],\n handler: async function ({ input }, { json, error }) {\n if (!emailAndPasswordEnabled) {\n return error(\n { message: \"Email/password auth is disabled\", code: \"email_password_disabled\" },\n 403,\n );\n }\n\n const { email, password, session } = await input.valid();\n let passwordCheck:\n | { ok: true }\n | { ok: false; code: \"invalid_credentials\" | \"user_banned\" }\n | null = null;\n\n const result = await this.handlerTx({\n onAfterRetrieve: async (_uow, results) => {\n const firstResult = Array.isArray(results[0]) ? results[0] : [];\n const user = (firstResult[0] ?? null) as {\n passwordHash?: string | null;\n bannedAt?: Date | null;\n } | null;\n\n if (!user?.passwordHash) {\n passwordCheck = { ok: false, code: \"invalid_credentials\" };\n return;\n }\n\n const isValid = await verifyPassword(password, user.passwordHash);\n if (!isValid) {\n passwordCheck = { ok: false, code: \"invalid_credentials\" };\n return;\n }\n\n if (user.bannedAt) {\n passwordCheck = { ok: false, code: \"user_banned\" };\n return;\n }\n\n passwordCheck = { ok: true };\n },\n })\n .retrieve(({ forSchema }) =>\n forSchema(authSchema).find(\"user\", (b) =>\n b\n .whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"=\", email))\n .join((j) =>\n j[\"userOrganizationMembers\"]((member) =>\n member\n .select([\"createdAt\"])\n .join((j) =>\n j[\"organizationMemberOrganization\"]((organization) =>\n organization.select([\"id\", \"deletedAt\"]),\n ),\n ),\n ),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [users] }) => {\n const user = users[0] ?? null;\n if (!user || !passwordCheck) {\n return { ok: false as const, code: \"invalid_credentials\" as const };\n }\n\n if (!passwordCheck.ok) {\n return { ok: false as const, code: passwordCheck.code };\n }\n\n const uow = forSchema(authSchema);\n // TODO: Use services.createSession instead of inline session creation (sign-up and\n // handleOAuthCallback also duplicate this logic)\n const expiresAt = uow.now().plus({ days: 30 });\n const resolvedSessionSeed = resolveSessionSeedFromMembers(\n collectSessionSeedMembers(users),\n session,\n );\n const activeOrganizationId = resolvedSessionSeed.activeOrganizationId;\n const sessionId = uow.create(\"session\", {\n userId: user.id,\n activeOrganizationId,\n expiresAt,\n });\n const userSummary = mapUserSummary({\n id: user.id.valueOf(),\n email: user.email,\n role: user.role,\n bannedAt: user.bannedAt ?? null,\n });\n\n uow.triggerHook(\"onSessionCreated\", {\n session: {\n id: sessionId.valueOf(),\n user: userSummary,\n expiresAt,\n activeOrganizationId,\n },\n actor: userSummary,\n });\n\n return {\n ok: true as const,\n sessionId: sessionId.valueOf(),\n user: userSummary,\n };\n })\n .execute();\n\n if (!result.ok) {\n if (result.code === \"user_banned\") {\n return error({ message: \"User is banned\", code: \"user_banned\" }, 403);\n }\n return error({ message: \"Invalid credentials\", code: \"invalid_credentials\" }, 401);\n }\n\n const sessionId = result.sessionId;\n const setCookieHeader = buildSetCookieHeader(sessionId, config.cookieOptions);\n\n return json(\n {\n sessionId,\n userId: result.user.id,\n email: result.user.email,\n role: result.user.role,\n },\n {\n headers: {\n \"Set-Cookie\": setCookieHeader,\n },\n },\n );\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/change-password\",\n inputSchema: z.object({\n newPassword: z.string().min(8).max(100),\n }),\n outputSchema: z.object({\n success: z.boolean(),\n }),\n errorCodes: [\"session_invalid\"],\n handler: async function ({ input, headers, query }, { json, error }) {\n const { newPassword } = await input.valid();\n\n const sessionId = extractSessionId(headers, query.get(\"sessionId\"));\n\n if (!sessionId) {\n return error({ message: \"Session ID required\", code: \"session_invalid\" }, 400);\n }\n\n const passwordHash = await hashPassword(newPassword);\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.changePasswordWithSession(sessionId, passwordHash)])\n .execute();\n\n if (!result.ok) {\n return error({ message: \"Invalid session\", code: \"session_invalid\" }, 401);\n }\n\n return json({ success: true });\n },\n }),\n ];\n },\n);\n","import { type Cursor, decodeCursor } from \"@fragno-dev/db/cursor\";\nimport { z } from \"zod\";\n\nimport { defineRoute, defineRoutes } from \"@fragno-dev/core\";\nimport type { DatabaseServiceContext } from \"@fragno-dev/db\";\n\nimport type { authFragmentDefinition } from \"..\";\nimport { authSchema } from \"../schema\";\n\nexport type SortField = \"email\" | \"createdAt\";\nexport type SortOrder = \"asc\" | \"desc\";\n\nexport interface GetUsersParams {\n search?: string;\n sortBy: SortField;\n sortOrder: SortOrder;\n pageSize: number;\n cursor?: Cursor;\n}\n\nexport interface UserResult {\n id: string;\n email: string;\n role: \"user\" | \"admin\";\n createdAt: Date;\n}\n\ntype AuthServiceContext = DatabaseServiceContext<{}>;\n\nexport function createUserOverviewServices() {\n const mapUser = (user: {\n id: unknown;\n email: string;\n role: string;\n createdAt: Date;\n }): UserResult => ({\n id: String(user.id),\n email: user.email,\n role: user.role as \"user\" | \"admin\",\n createdAt: user.createdAt,\n });\n\n return {\n /**\n * List users with cursor-based pagination, optional search, and sorting.\n */\n getUsersWithCursor: function (this: AuthServiceContext, params: GetUsersParams) {\n const { search, sortBy, sortOrder, pageSize, cursor } = params;\n\n // Determine which index to use based on search and sortBy\n // When searching, only email sorting is allowed (search uses email index)\n const effectiveSortBy: SortField = search ? \"email\" : sortBy;\n const indexName = effectiveSortBy === \"email\" ? \"idx_user_email\" : \"idx_user_createdAt\";\n\n // If cursor is provided, extract its metadata to ensure consistency\n const effectiveSortOrder = cursor ? cursor.orderDirection : sortOrder;\n const effectivePageSize = cursor ? cursor.pageSize : pageSize;\n\n return this.serviceTx(authSchema)\n .retrieve((uow) =>\n uow.findWithCursor(\"user\", (b) => {\n // When searching, we must filter by email and can only use the email index\n if (search) {\n const query = b\n .whereIndex(\"idx_user_email\", (eb) => eb(\"email\", \"contains\", search))\n .orderByIndex(\"idx_user_email\", effectiveSortOrder)\n .pageSize(effectivePageSize);\n\n // Add cursor for pagination continuation\n return cursor ? query.after(cursor) : query;\n }\n\n // When not searching, use the appropriate index for sorting\n const query = b\n .whereIndex(indexName)\n .orderByIndex(indexName, effectiveSortOrder)\n .pageSize(effectivePageSize);\n\n // Add cursor for pagination continuation\n return cursor ? query.after(cursor) : query;\n }),\n )\n .transformRetrieve(([result]) => ({\n users: result.items.map(mapUser),\n cursor: result.cursor,\n hasNextPage: result.hasNextPage,\n }))\n .build();\n },\n };\n}\n\nconst sortBySchema = z.enum([\"email\", \"createdAt\"]);\nconst sortOrderSchema = z.enum([\"asc\", \"desc\"]);\n\nexport const userOverviewRoutesFactory = defineRoutes<typeof authFragmentDefinition>().create(\n ({ services }) => {\n const querySchema = z.object({\n search: z.string().optional(),\n sortBy: sortBySchema.default(\"createdAt\"),\n sortOrder: sortOrderSchema.default(\"desc\"),\n pageSize: z.coerce.number().int().min(1).max(100).default(20),\n });\n\n const parseCursor = (cursorParam: string | null): Cursor | undefined => {\n if (!cursorParam) {\n return undefined;\n }\n try {\n return decodeCursor(cursorParam);\n } catch {\n return undefined;\n }\n };\n\n return [\n defineRoute({\n method: \"GET\",\n path: \"/users\",\n queryParameters: [\"search\", \"sortBy\", \"sortOrder\", \"pageSize\", \"cursor\"],\n outputSchema: z.object({\n users: z.array(\n z.object({\n id: z.string(),\n email: z.string(),\n role: z.enum([\"user\", \"admin\"]),\n createdAt: z.string(),\n }),\n ),\n cursor: z.string().optional(),\n hasNextPage: z.boolean(),\n sortBy: sortBySchema,\n }),\n errorCodes: [\"invalid_input\"],\n handler: async function ({ query }, { json, error }) {\n const parsed = querySchema.safeParse(Object.fromEntries(query.entries()));\n if (!parsed.success) {\n return error({ message: \"Invalid query parameters\", code: \"invalid_input\" }, 400);\n }\n\n const rawSearch = parsed.data.search?.trim();\n const search = rawSearch ? rawSearch : undefined;\n const sortBy: SortField = search ? \"email\" : parsed.data.sortBy;\n const params = {\n search,\n sortBy,\n sortOrder: parsed.data.sortOrder as SortOrder,\n pageSize: parsed.data.pageSize,\n };\n const cursor = parseCursor(query.get(\"cursor\"));\n\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.getUsersWithCursor({ ...params, cursor })])\n .execute();\n\n return json({\n users: result.users.map((user) => ({\n id: user.id,\n email: user.email,\n role: user.role,\n createdAt: user.createdAt.toISOString(),\n })),\n cursor: result.cursor?.encode(),\n hasNextPage: result.hasNextPage,\n sortBy: params.sortBy, // Return the actual sortBy used (may differ from requested)\n });\n },\n }),\n ];\n },\n);\n","import type { OAuthProvider, ProviderOptions, OAuth2Tokens } from \"../../types\";\nimport { createAuthorizationURL, normalizeOAuthTokens, parseOAuthTokenResponse } from \"../../utils\";\nimport type { GithubOAuthClient } from \"./client\";\n\nexport interface GithubProfile {\n login: string;\n id: string;\n node_id: string;\n avatar_url: string;\n gravatar_id: string;\n url: string;\n html_url: string;\n followers_url: string;\n following_url: string;\n gists_url: string;\n starred_url: string;\n subscriptions_url: string;\n organizations_url: string;\n repos_url: string;\n events_url: string;\n received_events_url: string;\n type: string;\n site_admin: boolean;\n name: string;\n company: string;\n blog: string;\n location: string;\n email: string;\n hireable: boolean;\n bio: string;\n twitter_username: string;\n public_repos: string;\n public_gists: string;\n followers: string;\n following: string;\n created_at: string;\n updated_at: string;\n private_gists: string;\n total_private_repos: string;\n owned_private_repos: string;\n disk_usage: string;\n collaborators: string;\n two_factor_authentication: boolean;\n plan: {\n name: string;\n space: string;\n private_repos: string;\n collaborators: string;\n };\n}\n\nexport type GithubEmail = {\n email: string;\n primary: boolean;\n verified: boolean;\n visibility: \"public\" | \"private\";\n};\n\nexport interface GithubOptions extends ProviderOptions<GithubProfile> {\n clientId: string;\n clientSecret: string;\n client?: GithubOAuthClient;\n}\n\nconst defaultScopes = [\"read:user\", \"user:email\"];\nconst defaultUserAgent = \"fragno-auth\";\nconst tokenEndpoint = \"https://github.com/login/oauth/access_token\";\nconst profileEndpoint = \"https://api.github.com/user\";\nconst emailsEndpoint = \"https://api.github.com/user/emails\";\n\nexport const createGithubOAuthClient = (options?: {\n fetcher?: typeof fetch;\n userAgent?: string;\n}): GithubOAuthClient => {\n const fetcher = options?.fetcher ?? fetch;\n const userAgent = options?.userAgent ?? defaultUserAgent;\n\n return {\n exchangeCode: async ({ code, redirectURI, clientId, clientSecret, codeVerifier }) => {\n const body = new URLSearchParams({\n client_id: clientId,\n client_secret: clientSecret,\n code,\n redirect_uri: redirectURI,\n });\n if (codeVerifier) {\n body.set(\"code_verifier\", codeVerifier);\n }\n\n const response = await fetcher(tokenEndpoint, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/x-www-form-urlencoded\",\n },\n body,\n });\n\n const parsed = await parseOAuthTokenResponse(response);\n if (!parsed.ok) {\n return null;\n }\n\n return normalizeOAuthTokens(parsed.data);\n },\n fetchProfile: async (accessToken: string) => {\n const response = await fetcher(profileEndpoint, {\n headers: {\n \"User-Agent\": userAgent,\n authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n return null;\n }\n\n return (await response.json()) as GithubProfile;\n },\n fetchEmails: async (accessToken: string) => {\n const response = await fetcher(emailsEndpoint, {\n headers: {\n \"User-Agent\": userAgent,\n authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n return [];\n }\n\n return (await response.json()) as GithubEmail[];\n },\n };\n};\n\nexport const github = (options: GithubOptions) => {\n const client = options.client ?? createGithubOAuthClient();\n const authorizationEndpoint =\n options.authorizationEndpoint ?? \"https://github.com/login/oauth/authorize\";\n\n return {\n id: \"github\",\n name: \"GitHub\",\n options,\n createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {\n const resolvedScopes = options.disableDefaultScope ? [] : [...defaultScopes];\n if (options.scope) {\n resolvedScopes.push(...options.scope);\n }\n if (scopes) {\n resolvedScopes.push(...scopes);\n }\n\n return createAuthorizationURL({\n authorizationEndpoint,\n clientId: options.clientId,\n redirectURI,\n state,\n scopes: resolvedScopes,\n prompt: options.prompt,\n loginHint: loginHint ?? undefined,\n extraParams: loginHint ? { login: loginHint } : undefined,\n });\n },\n validateAuthorizationCode: async ({ code, redirectURI, codeVerifier }) => {\n return client.exchangeCode({\n code,\n redirectURI: redirectURI,\n clientId: options.clientId,\n clientSecret: options.clientSecret,\n codeVerifier,\n });\n },\n refreshAccessToken: options.refreshAccessToken,\n async getUserInfo(token: OAuth2Tokens) {\n if (options.getUserInfo) {\n return options.getUserInfo(token);\n }\n\n if (!token.accessToken) {\n return null;\n }\n\n const profile = await client.fetchProfile(token.accessToken);\n if (!profile) {\n return null;\n }\n\n const emails = await client.fetchEmails(token.accessToken);\n\n if (!profile.email && emails.length > 0) {\n profile.email = (emails.find((entry) => entry.primary) ?? emails[0])?.email as string;\n }\n\n const emailVerified =\n emails.find((entry) => entry.email === profile.email)?.verified ?? false;\n\n const mapped = await options.mapProfileToUser?.(profile);\n\n return {\n user: {\n id: profile.id,\n name: profile.name || profile.login,\n email: profile.email ?? null,\n image: profile.avatar_url,\n emailVerified,\n ...mapped,\n },\n data: profile,\n };\n },\n } satisfies OAuthProvider<GithubProfile>;\n};\n","import { createClientBuilder, type FragnoPublicClientConfig } from \"@fragno-dev/core/client\";\n\nimport { defineFragment, instantiate } from \"@fragno-dev/core\";\nimport { withDatabase, type FragnoPublicConfigWithDatabase } from \"@fragno-dev/db\";\n\nimport {\n clearDefaultOrganizationId,\n createDefaultOrganizationPreferenceState,\n DEFAULT_ORGANIZATION_CHANGE_EVENT,\n DEFAULT_ORGANIZATION_STORAGE_KEY,\n findOrganizationEntry,\n getDefaultOrganizationChangeEventName,\n getDefaultOrganizationStorageKey,\n NO_ORGANIZATIONS_ERROR_MESSAGE,\n readDefaultOrganizationId,\n resolveDefaultOrganization,\n setDefaultOrganizationForMe,\n subscribeToDefaultOrganizationPreference,\n syncDefaultOrganizationPreference,\n writeDefaultOrganizationId,\n type AuthMeLike as AuthDefaultOrganizationMeLike,\n type DefaultOrganizationEntry as AuthDefaultOrganizationEntry,\n type DefaultOrganizationResolution as AuthDefaultOrganizationResolution,\n type DefaultOrganizationResolutionStatus,\n} from \"./client/default-organization\";\nimport type {\n AuthHooks,\n AuthHooksMap,\n BeforeCreateUserHook,\n InvitationExpiredHookPayload,\n SessionHookPayload,\n UserHookPayload,\n} from \"./hooks\";\nimport { createOAuthServices } from \"./oauth/oauth-services\";\nimport { oauthRoutesFactory } from \"./oauth/routes\";\nimport type { AuthOAuthConfig } from \"./oauth/types\";\nimport { createActiveOrganizationServices } from \"./organization/active-organization\";\nimport { createOrganizationInvitationServices } from \"./organization/invitation-services\";\nimport { createOrganizationMemberServices } from \"./organization/member-services\";\nimport { createOrganizationServices } from \"./organization/organization-services\";\nimport { organizationRoutesFactory } from \"./organization/routes\";\nimport type {\n DefaultOrganizationRole,\n OrganizationConfig,\n OrganizationHookPayload,\n OrganizationHooks,\n OrganizationInvitationHookPayload,\n OrganizationMemberHookPayload,\n OrganizationInvitationStatus,\n} from \"./organization/types\";\nimport { toExternalId } from \"./organization/utils\";\nimport { authSchema } from \"./schema\";\nimport { createSessionServices, sessionRoutesFactory } from \"./session/session\";\nimport { serializeSessionSeedForQuery } from \"./session/session-seed\";\nimport type { Role } from \"./types\";\nimport { createUserServices, userActionsRoutesFactory } from \"./user/user-actions\";\nimport {\n createUserOverviewServices,\n userOverviewRoutesFactory,\n type GetUsersParams,\n type UserResult,\n type SortField,\n type SortOrder,\n} from \"./user/user-overview\";\nimport type { CookieOptions } from \"./utils/cookie\";\n\nexport interface AuthConfig<TRole extends string = DefaultOrganizationRole> {\n cookieOptions?: CookieOptions;\n hooks?: AuthHooks;\n beforeCreateUser?: BeforeCreateUserHook;\n organizations?: OrganizationConfig<TRole> | false;\n emailAndPassword?: {\n enabled?: boolean;\n };\n oauth?: AuthOAuthConfig;\n}\n\nexport const authFragmentDefinition = defineFragment<AuthConfig>(\"auth\")\n .extend(withDatabase(authSchema))\n .provideHooks<AuthHooksMap>(({ defineHook, config }) => {\n const authHooks = config.hooks;\n const organizationConfig = config.organizations === false ? undefined : config.organizations;\n const organizationHooks = organizationConfig?.hooks as OrganizationHooks<string> | undefined;\n\n const mapOrganization = (organization: {\n id: unknown;\n name: string;\n slug: string;\n logoUrl: string | null;\n metadata: unknown;\n createdBy: unknown;\n organizationCreator?: { id?: unknown } | null;\n createdAt: Date;\n updatedAt: Date;\n deletedAt: Date | null;\n }) => ({\n id: toExternalId(organization.id),\n name: organization.name,\n slug: organization.slug,\n logoUrl: organization.logoUrl ?? null,\n metadata: (organization.metadata ?? null) as Record<string, unknown> | null,\n createdBy: toExternalId(organization.organizationCreator?.id ?? organization.createdBy),\n createdAt: organization.createdAt,\n updatedAt: organization.updatedAt,\n deletedAt: organization.deletedAt ?? null,\n });\n\n const mapInvitation = (invitation: {\n id: unknown;\n organizationId: unknown;\n email: string;\n roles: unknown;\n status: string;\n token: string;\n inviterId: unknown;\n expiresAt: Date;\n createdAt: Date;\n respondedAt: Date | null;\n }) => ({\n id: toExternalId(invitation.id),\n organizationId: toExternalId(invitation.organizationId),\n email: invitation.email,\n roles: Array.isArray(invitation.roles) ? (invitation.roles as string[]) : [],\n status: invitation.status as OrganizationInvitationStatus,\n token: invitation.token,\n inviterId: toExternalId(invitation.inviterId),\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: invitation.respondedAt ?? null,\n });\n\n const baseHooks = {\n onUserCreated: defineHook<UserHookPayload>(async function (payload) {\n await authHooks?.onUserCreated?.(payload);\n }),\n onUserRoleUpdated: defineHook<UserHookPayload>(async function (payload) {\n await authHooks?.onUserRoleUpdated?.(payload);\n }),\n onUserPasswordChanged: defineHook<UserHookPayload>(async function (payload) {\n await authHooks?.onUserPasswordChanged?.(payload);\n }),\n onSessionCreated: defineHook<SessionHookPayload>(async function (payload) {\n await authHooks?.onSessionCreated?.(payload);\n }),\n onSessionInvalidated: defineHook<SessionHookPayload>(async function (payload) {\n await authHooks?.onSessionInvalidated?.(payload);\n }),\n };\n\n return {\n ...baseHooks,\n onOrganizationCreated: defineHook<OrganizationHookPayload>(async function (payload) {\n await organizationHooks?.onOrganizationCreated?.(payload);\n }),\n onOrganizationUpdated: defineHook<OrganizationHookPayload>(async function (payload) {\n await organizationHooks?.onOrganizationUpdated?.(payload);\n }),\n onOrganizationDeleted: defineHook<OrganizationHookPayload>(async function (payload) {\n await organizationHooks?.onOrganizationDeleted?.(payload);\n }),\n onMemberAdded: defineHook<OrganizationMemberHookPayload<string>>(async function (payload) {\n await organizationHooks?.onMemberAdded?.(payload);\n }),\n onMemberRemoved: defineHook<OrganizationMemberHookPayload<string>>(async function (payload) {\n await organizationHooks?.onMemberRemoved?.(payload);\n }),\n onMemberRolesUpdated: defineHook<OrganizationMemberHookPayload<string>>(\n async function (payload) {\n await organizationHooks?.onMemberRolesUpdated?.(payload);\n },\n ),\n onInvitationCreated: defineHook<OrganizationInvitationHookPayload<string>>(\n async function (payload) {\n await organizationHooks?.onInvitationCreated?.(payload);\n },\n ),\n onInvitationAccepted: defineHook<OrganizationInvitationHookPayload<string>>(\n async function (payload) {\n await organizationHooks?.onInvitationAccepted?.(payload);\n },\n ),\n onInvitationRejected: defineHook<OrganizationInvitationHookPayload<string>>(\n async function (payload) {\n await organizationHooks?.onInvitationRejected?.(payload);\n },\n ),\n onInvitationCanceled: defineHook<OrganizationInvitationHookPayload<string>>(\n async function (payload) {\n await organizationHooks?.onInvitationCanceled?.(payload);\n },\n ),\n onInvitationExpired: defineHook<InvitationExpiredHookPayload>(async function (payload) {\n if (!payload.invitationId) {\n return;\n }\n\n const now = new Date();\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(authSchema).findFirst(\"organizationInvitation\", (b) =>\n b\n .whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", payload.invitationId))\n .join((j) =>\n j.organizationInvitationOrganization((org) =>\n org.join((j) => j.organizationCreator()),\n ),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [invitation] }) => {\n if (!invitation) {\n return { shouldNotify: false as const };\n }\n\n const status = invitation.status as OrganizationInvitationStatus;\n if (status !== \"pending\") {\n return { shouldNotify: false as const };\n }\n\n if (invitation.expiresAt.getTime() > now.getTime()) {\n return { shouldNotify: false as const };\n }\n\n const uow = forSchema(authSchema);\n uow.update(\"organizationInvitation\", invitation.id, (b) =>\n b.set({ status: \"expired\", respondedAt: now }).check(),\n );\n\n if (!invitation.organizationInvitationOrganization) {\n return { shouldNotify: false as const };\n }\n\n return {\n shouldNotify: true as const,\n organization: mapOrganization(invitation.organizationInvitationOrganization),\n invitation: mapInvitation({\n id: invitation.id,\n organizationId: invitation.organizationId,\n email: invitation.email,\n roles: invitation.roles,\n status: \"expired\",\n token: invitation.token,\n inviterId: invitation.inviterId,\n expiresAt: invitation.expiresAt,\n createdAt: invitation.createdAt,\n respondedAt: now,\n }),\n };\n })\n .transform(({ mutateResult }) => mutateResult)\n .execute();\n\n if (result.shouldNotify) {\n await organizationHooks?.onInvitationExpired?.({\n organization: result.organization,\n invitation: result.invitation,\n actor: null,\n });\n }\n }),\n };\n })\n .providesBaseService(({ defineService, config }) => {\n const organizationsEnabled = config.organizations !== false;\n const organizationConfig = config.organizations === false ? undefined : config.organizations;\n\n const organizationConfigResolved = organizationConfig as OrganizationConfig<string> | undefined;\n const autoCreateOptions = organizationsEnabled\n ? {\n autoCreateOrganization:\n organizationConfig && organizationConfig.autoCreateOrganization !== false\n ? organizationConfig.autoCreateOrganization\n : undefined,\n creatorRoles: organizationConfig?.creatorRoles,\n }\n : undefined;\n\n return defineService({\n ...createUserServices(autoCreateOptions, config.beforeCreateUser),\n ...createSessionServices(config.cookieOptions),\n ...createUserOverviewServices(),\n ...createOrganizationServices({\n organizationConfig: organizationConfigResolved,\n }),\n ...createOrganizationMemberServices({\n organizationConfig: organizationConfigResolved,\n }),\n ...createOrganizationInvitationServices({\n organizationConfig: organizationConfigResolved,\n }),\n ...createActiveOrganizationServices(),\n ...createOAuthServices({\n oauth: config.oauth,\n autoCreateOptions,\n beforeCreateUser: config.beforeCreateUser,\n }),\n });\n })\n .build();\n\nexport type AuthFragment = typeof authFragmentDefinition;\n\nexport function createAuthFragment(\n config: AuthConfig = {},\n fragnoConfig: FragnoPublicConfigWithDatabase,\n) {\n const options = {\n ...fragnoConfig,\n // Preserve legacy namespace to avoid changing physical table names.\n databaseNamespace:\n fragnoConfig.databaseNamespace !== undefined\n ? fragnoConfig.databaseNamespace\n : \"simple-auth-db\",\n };\n\n return instantiate(authFragmentDefinition)\n .withConfig(config)\n .withOptions(options)\n .withRoutes([\n userActionsRoutesFactory,\n sessionRoutesFactory,\n userOverviewRoutesFactory,\n organizationRoutesFactory,\n oauthRoutesFactory,\n ])\n .build();\n}\n\nexport function createAuthFragmentClients(fragnoConfig?: FragnoPublicClientConfig) {\n // Note: Cookies are automatically sent for same-origin requests by the browser.\n // For cross-origin requests, you may need to configure CORS headers on the server.\n const config = { ...fragnoConfig };\n\n const b = createClientBuilder(\n authFragmentDefinition,\n config,\n [\n userActionsRoutesFactory,\n sessionRoutesFactory,\n userOverviewRoutesFactory,\n organizationRoutesFactory,\n oauthRoutesFactory,\n ],\n {\n type: \"options\",\n options: {\n credentials: \"include\",\n },\n },\n );\n\n const useMe = b.createHook(\"/me\");\n const useSignUp = b.createMutator(\"POST\", \"/sign-up\");\n const useSignIn = b.createMutator(\"POST\", \"/sign-in\");\n const useSignOut = b.createMutator(\"POST\", \"/sign-out\", (invalidate) => {\n invalidate(\"GET\", \"/me\", {});\n invalidate(\"GET\", \"/users\", {});\n });\n const useUsers = b.createHook(\"/users\");\n const useUpdateUserRole = b.createMutator(\"PATCH\", \"/users/:userId/role\", (invalidate) => {\n invalidate(\"GET\", \"/users\", {});\n invalidate(\"GET\", \"/me\", {});\n });\n const useChangePassword = b.createMutator(\"POST\", \"/change-password\");\n const useOrganizations = b.createHook(\"/organizations\");\n const useOrganization = b.createHook(\"/organizations/:organizationId\");\n const useCreateOrganization = b.createMutator(\"POST\", \"/organizations\", (invalidate) => {\n invalidate(\"GET\", \"/organizations\", {});\n invalidate(\"GET\", \"/organizations/active\", {});\n invalidate(\"GET\", \"/me\", {});\n });\n const useUpdateOrganization = b.createMutator(\n \"PATCH\",\n \"/organizations/:organizationId\",\n (invalidate, params) => {\n const organizationId = params.pathParams.organizationId;\n if (organizationId) {\n invalidate(\"GET\", \"/organizations/:organizationId\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations/:organizationId/members\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations/:organizationId/invitations\", {\n pathParams: { organizationId },\n });\n }\n invalidate(\"GET\", \"/organizations\", {});\n invalidate(\"GET\", \"/organizations/active\", {});\n invalidate(\"GET\", \"/me\", {});\n },\n );\n const useDeleteOrganization = b.createMutator(\n \"DELETE\",\n \"/organizations/:organizationId\",\n (invalidate, params) => {\n const organizationId = params.pathParams.organizationId;\n if (organizationId) {\n invalidate(\"GET\", \"/organizations/:organizationId\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations/:organizationId/members\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations/:organizationId/invitations\", {\n pathParams: { organizationId },\n });\n }\n invalidate(\"GET\", \"/organizations\", {});\n invalidate(\"GET\", \"/organizations/active\", {});\n invalidate(\"GET\", \"/me\", {});\n },\n );\n const useActiveOrganization = b.createHook(\"/organizations/active\");\n const useSetActiveOrganization = b.createMutator(\n \"POST\",\n \"/organizations/active\",\n (invalidate) => {\n invalidate(\"GET\", \"/organizations/active\", {});\n invalidate(\"GET\", \"/me\", {});\n },\n );\n const useOrganizationMembers = b.createHook(\"/organizations/:organizationId/members\");\n const useAddOrganizationMember = b.createMutator(\n \"POST\",\n \"/organizations/:organizationId/members\",\n (invalidate, params) => {\n const organizationId = params.pathParams.organizationId;\n if (!organizationId) {\n return;\n }\n invalidate(\"GET\", \"/organizations/:organizationId/members\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations/:organizationId\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations\", {});\n invalidate(\"GET\", \"/me\", {});\n },\n );\n const useUpdateOrganizationMemberRoles = b.createMutator(\n \"PATCH\",\n \"/organizations/:organizationId/members/:memberId\",\n (invalidate, params) => {\n const organizationId = params.pathParams.organizationId;\n if (!organizationId) {\n return;\n }\n invalidate(\"GET\", \"/organizations/:organizationId/members\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations/:organizationId\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations\", {});\n invalidate(\"GET\", \"/me\", {});\n },\n );\n const useRemoveOrganizationMember = b.createMutator(\n \"DELETE\",\n \"/organizations/:organizationId/members/:memberId\",\n (invalidate, params) => {\n const organizationId = params.pathParams.organizationId;\n if (!organizationId) {\n return;\n }\n invalidate(\"GET\", \"/organizations/:organizationId/members\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations/:organizationId\", {\n pathParams: { organizationId },\n });\n invalidate(\"GET\", \"/organizations\", {});\n invalidate(\"GET\", \"/me\", {});\n },\n );\n const useOrganizationInvitations = b.createHook(\"/organizations/:organizationId/invitations\");\n const useInviteOrganizationMember = b.createMutator(\n \"POST\",\n \"/organizations/:organizationId/invitations\",\n (invalidate, params) => {\n const organizationId = params.pathParams.organizationId;\n if (!organizationId) {\n return;\n }\n invalidate(\"GET\", \"/organizations/:organizationId/invitations\", {\n pathParams: { organizationId },\n });\n },\n );\n const useRespondOrganizationInvitation = b.createMutator(\n \"PATCH\",\n \"/organizations/invitations/:invitationId\",\n (invalidate) => {\n invalidate(\"GET\", \"/organizations/invitations\", {});\n invalidate(\"GET\", \"/organizations\", {});\n invalidate(\"GET\", \"/organizations/active\", {});\n invalidate(\"GET\", \"/me\", {});\n },\n );\n const useUserInvitations = b.createHook(\"/organizations/invitations\");\n const useOAuthAuthorize = b.createHook(\"/oauth/:provider/authorize\");\n const useOAuthCallback = b.createHook(\"/oauth/:provider/callback\");\n const readRawMe = async (params?: { sessionId?: string }) => {\n if (params?.sessionId) {\n return useMe.query({ query: { sessionId: params.sessionId } });\n }\n\n return useMe.query();\n };\n const defaultOrganizationPreference = createDefaultOrganizationPreferenceState({\n meStore: useMe.store(),\n readMe: readRawMe,\n getAccountId: (me) => me.user.id,\n });\n\n return {\n // Reactive hooks - Auth\n useSignUp,\n useSignIn,\n useSignOut,\n useMe,\n useDefaultOrganizationPreference: b.createStore(defaultOrganizationPreference.store),\n useUsers,\n useUpdateUserRole,\n useChangePassword,\n useOrganizations,\n useOrganization,\n useCreateOrganization,\n useUpdateOrganization,\n useDeleteOrganization,\n useActiveOrganization,\n useSetActiveOrganization,\n useOrganizationMembers,\n useAddOrganizationMember,\n useUpdateOrganizationMemberRoles,\n useRemoveOrganizationMember,\n useOrganizationInvitations,\n useInviteOrganizationMember,\n useRespondOrganizationInvitation,\n useUserInvitations,\n useOAuthAuthorize,\n useOAuthCallback,\n\n // Non-reactive methods\n signIn: {\n email: async ({\n email,\n password,\n session,\n rememberMe: _rememberMe,\n }: {\n email: string;\n password: string;\n session?: {\n activeOrganizationId?: string;\n };\n rememberMe?: boolean;\n }) => {\n // Note: rememberMe is accepted but not yet implemented on the backend\n return useSignIn.mutateQuery({\n body: {\n email,\n password,\n session,\n },\n });\n },\n },\n\n signUp: {\n email: async ({ email, password }: { email: string; password: string }) => {\n return useSignUp.mutateQuery({\n body: {\n email,\n password,\n },\n });\n },\n },\n\n signOut: (params?: { sessionId?: string }) => {\n return useSignOut.mutateQuery({\n body: params?.sessionId ? { sessionId: params.sessionId } : {},\n });\n },\n\n me: defaultOrganizationPreference.me,\n\n defaultOrganization: defaultOrganizationPreference.defaultOrganization,\n\n oauth: {\n getAuthorizationUrl: async (params: {\n provider: string;\n returnTo?: string;\n link?: boolean;\n sessionId?: string;\n session?: {\n activeOrganizationId?: string;\n };\n redirectUri?: string;\n scope?: string;\n loginHint?: string;\n }) => {\n return useOAuthAuthorize.query({\n path: { provider: params.provider },\n query: {\n redirectUri: params.redirectUri,\n returnTo: params.returnTo,\n link: params.link ? \"true\" : undefined,\n sessionId: params.sessionId,\n session: serializeSessionSeedForQuery(params.session),\n scope: params.scope,\n loginHint: params.loginHint,\n },\n });\n },\n callback: async (params: {\n provider: string;\n code: string;\n state: string;\n requestSignUp?: boolean;\n }) => {\n return useOAuthCallback.query({\n path: { provider: params.provider },\n query: {\n code: params.code,\n state: params.state,\n requestSignUp: params.requestSignUp ? \"true\" : undefined,\n },\n });\n },\n },\n };\n}\n\nexport type { FragnoRouteConfig } from \"@fragno-dev/core/api\";\nexport type { GetUsersParams, UserResult, SortField, SortOrder };\nexport type AuthMeData = Awaited<ReturnType<ReturnType<typeof createAuthFragmentClients>[\"me\"]>>;\nexport type {\n AuthHooks,\n BeforeCreateUserHook,\n BeforeCreateUserPayload,\n InvitationExpiredHookPayload,\n SessionHookPayload,\n UserHookPayload,\n SessionSummary,\n} from \"./hooks\";\nexport type { UserSummary } from \"./types\";\nexport type {\n AnyOAuthProvider,\n AuthOAuthConfig,\n OAuthProvider,\n OAuth2Tokens,\n OAuth2UserInfo,\n} from \"./oauth/types\";\nexport type { GithubOAuthClient } from \"./oauth/providers/github/client\";\nexport type { GithubEmail, GithubProfile } from \"./oauth/providers/github/github\";\nexport { createGithubOAuthClient, github } from \"./oauth/providers/github/github\";\nexport type {\n AuthMeResponse,\n AutoCreateOrganizationConfig,\n DefaultOrganizationRole,\n Organization,\n OrganizationConfig,\n OrganizationHookPayload,\n OrganizationHooks,\n OrganizationInvitation,\n OrganizationInvitationSummary,\n OrganizationInvitationHookPayload,\n OrganizationInvitationStatus,\n OrganizationMember,\n OrganizationMemberSummary,\n OrganizationMemberHookPayload,\n OrganizationRoleName,\n} from \"./organization/types\";\nexport type { AuthDefaultOrganizationMeLike as AuthMeLike, DefaultOrganizationResolutionStatus };\nexport type DefaultOrganizationEntry<TMe extends AuthDefaultOrganizationMeLike = AuthMeData> =\n AuthDefaultOrganizationEntry<TMe>;\nexport type DefaultOrganizationResolution<TMe extends AuthDefaultOrganizationMeLike = AuthMeData> =\n AuthDefaultOrganizationResolution<TMe>;\nexport type DefaultOrganizationPreferenceStore<\n TMe extends AuthDefaultOrganizationMeLike = AuthMeData,\n> = import(\"./client/default-organization\").DefaultOrganizationPreferenceStore<TMe>;\nexport {\n clearDefaultOrganizationId,\n DEFAULT_ORGANIZATION_CHANGE_EVENT,\n DEFAULT_ORGANIZATION_STORAGE_KEY,\n findOrganizationEntry,\n getDefaultOrganizationChangeEventName,\n getDefaultOrganizationStorageKey,\n NO_ORGANIZATIONS_ERROR_MESSAGE,\n readDefaultOrganizationId,\n resolveDefaultOrganization,\n setDefaultOrganizationForMe,\n subscribeToDefaultOrganizationPreference,\n syncDefaultOrganizationPreference,\n writeDefaultOrganizationId,\n};\n\nexport type { Role };\n"],"mappings":"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"}