@shipfox/api-auth 19.0.0 → 20.0.0
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.
- package/.turbo/turbo-build.log +17 -2
- package/CHANGELOG.md +13 -0
- package/dist/core/cimd.d.ts +39 -0
- package/dist/core/cimd.d.ts.map +1 -0
- package/dist/core/cimd.js +392 -0
- package/dist/core/cimd.js.map +1 -0
- package/dist/core/errors.d.ts +14 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +26 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/oauth-client-resolver.d.ts +54 -0
- package/dist/core/oauth-client-resolver.d.ts.map +1 -0
- package/dist/core/oauth-client-resolver.js +154 -0
- package/dist/core/oauth-client-resolver.js.map +1 -0
- package/dist/core/oauth-client.d.ts +39 -0
- package/dist/core/oauth-client.d.ts.map +1 -0
- package/dist/core/oauth-client.js +236 -0
- package/dist/core/oauth-client.js.map +1 -0
- package/dist/db/agent-access-retention.d.ts +10 -0
- package/dist/db/agent-access-retention.d.ts.map +1 -0
- package/dist/db/agent-access-retention.js +11 -0
- package/dist/db/agent-access-retention.js.map +1 -0
- package/dist/db/agent-access.d.ts +100 -4
- package/dist/db/agent-access.d.ts.map +1 -1
- package/dist/db/agent-access.js +483 -45
- package/dist/db/agent-access.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/instance.d.ts +1 -1
- package/dist/metrics/instance.d.ts.map +1 -1
- package/dist/metrics/instance.js.map +1 -1
- package/dist/presentation/routes/oauth.d.ts +9 -0
- package/dist/presentation/routes/oauth.d.ts.map +1 -0
- package/dist/presentation/routes/oauth.js +150 -0
- package/dist/presentation/routes/oauth.js.map +1 -0
- package/dist/presentation/routes/rate-limit.d.ts.map +1 -1
- package/dist/presentation/routes/rate-limit.js +24 -0
- package/dist/presentation/routes/rate-limit.js.map +1 -1
- package/dist/temporal/activities/agent-access-retention.d.ts +13 -0
- package/dist/temporal/activities/agent-access-retention.d.ts.map +1 -0
- package/dist/temporal/activities/agent-access-retention.js +58 -0
- package/dist/temporal/activities/agent-access-retention.js.map +1 -0
- package/dist/temporal/activities/index.d.ts +5 -0
- package/dist/temporal/activities/index.d.ts.map +1 -0
- package/dist/temporal/activities/index.js +8 -0
- package/dist/temporal/activities/index.js.map +1 -0
- package/dist/temporal/constants.d.ts +2 -0
- package/dist/temporal/constants.d.ts.map +1 -0
- package/dist/temporal/constants.js +3 -0
- package/dist/temporal/constants.js.map +1 -0
- package/dist/temporal/workflows/agent-access-retention-cron.d.ts +2 -0
- package/dist/temporal/workflows/agent-access-retention-cron.d.ts.map +1 -0
- package/dist/temporal/workflows/agent-access-retention-cron.js +22 -0
- package/dist/temporal/workflows/agent-access-retention-cron.js.map +1 -0
- package/dist/temporal/workflows/index.bundle.js +25227 -0
- package/dist/temporal/workflows/index.bundle.meta.json +1 -0
- package/dist/temporal/workflows/index.d.ts +2 -0
- package/dist/temporal/workflows/index.d.ts.map +1 -0
- package/dist/temporal/workflows/index.js +3 -0
- package/dist/temporal/workflows/index.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +7 -4
- package/src/core/cimd.test.ts +213 -0
- package/src/core/cimd.ts +532 -0
- package/src/core/errors.ts +41 -0
- package/src/core/oauth-client-resolver.test.ts +198 -0
- package/src/core/oauth-client-resolver.ts +253 -0
- package/src/core/oauth-client.test.ts +157 -0
- package/src/core/oauth-client.ts +331 -0
- package/src/db/agent-access-retention.ts +10 -0
- package/src/db/agent-access.test.ts +697 -3
- package/src/db/agent-access.ts +953 -91
- package/src/index.test.ts +27 -0
- package/src/index.ts +76 -0
- package/src/metrics/instance.ts +5 -1
- package/src/presentation/routes/oauth.test.ts +133 -0
- package/src/presentation/routes/oauth.ts +144 -0
- package/src/presentation/routes/rate-limit.ts +12 -0
- package/src/temporal/activities/agent-access-retention.ts +76 -0
- package/src/temporal/activities/index.ts +5 -0
- package/src/temporal/constants.ts +1 -0
- package/src/temporal/workflows/agent-access-retention-cron.ts +23 -0
- package/src/temporal/workflows/index.ts +1 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/agent-access.ts"],"sourcesContent":["import {and, asc, eq, gt, inArray, isNull, lt, or, sql} from 'drizzle-orm';\nimport type {\n AgentAuthorizationCode,\n AgentAuthorizationRequest,\n AgentClient,\n AgentGrant,\n AgentPersonalAccessToken,\n AgentRefreshToken,\n} from '#core/entities/agent-access.js';\nimport {db} from './db.js';\nimport {\n agentAuthorizationCodes,\n agentAuthorizationRequests,\n agentClients,\n agentGrants,\n agentPersonalAccessTokens,\n agentRefreshTokens,\n toAgentAuthorizationCode,\n toAgentAuthorizationRequest,\n toAgentClient,\n toAgentGrant,\n toAgentPersonalAccessToken,\n toAgentRefreshToken,\n} from './schema/agent-access.js';\n\nexport type AgentAccessTx = Parameters<Parameters<ReturnType<typeof db>['transaction']>[0]>[0];\n\ntype AgentAccessExecutor = ReturnType<typeof db> | AgentAccessTx;\n\nexport interface CreateAgentClientParams {\n clientId: string;\n name: string;\n redirectUris: string[];\n kind: 'registered' | 'cimd';\n}\n\nexport async function createAgentClient(params: CreateAgentClientParams): Promise<AgentClient> {\n return await db().transaction((tx) => createAgentClientTx(tx, params));\n}\n\nexport async function createAgentClientTx(\n tx: AgentAccessTx,\n params: CreateAgentClientParams,\n): Promise<AgentClient> {\n const rows = await tx\n .insert(agentClients)\n .values(params)\n .onConflictDoUpdate({\n target: agentClients.clientId,\n set: {\n lastSeenAt: sql`now()`,\n unreferencedAt: null,\n updatedAt: sql`now()`,\n },\n })\n .returning();\n const row = rows[0];\n if (!row) throw new Error('Upsert returned no rows');\n return toAgentClient(row);\n}\n\nexport async function findAgentClientByClientId(params: {\n clientId: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentClient | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentClients)\n .where(eq(agentClients.clientId, params.clientId))\n .limit(1);\n const row = rows[0];\n return row ? toAgentClient(row) : undefined;\n}\n\nexport async function markAgentClientReferenced(\n tx: AgentAccessTx,\n params: {clientUuid: string},\n): Promise<void> {\n await tx\n .update(agentClients)\n .set({unreferencedAt: null, lastSeenAt: sql`now()`, updatedAt: sql`now()`})\n .where(eq(agentClients.id, params.clientUuid));\n}\n\nexport async function markAgentClientUnreferenced(\n tx: AgentAccessTx,\n params: {clientUuid: string},\n): Promise<void> {\n await tx\n .update(agentClients)\n .set({unreferencedAt: sql`now()`, updatedAt: sql`now()`})\n .where(eq(agentClients.id, params.clientUuid));\n}\n\nexport interface CreateAgentAuthorizationRequestParams {\n /** Internal `auth_agent_clients.id`, not the public OAuth `client_id`. */\n clientId: string;\n redirectUri: string;\n resource: string;\n scopes: string[];\n codeChallenge: string;\n state: string | null;\n expiresAt: Date;\n}\n\nexport async function createAgentAuthorizationRequest(\n params: CreateAgentAuthorizationRequestParams,\n): Promise<AgentAuthorizationRequest> {\n return await db().transaction((tx) => createAgentAuthorizationRequestTx(tx, params));\n}\n\nexport async function createAgentAuthorizationRequestTx(\n tx: AgentAccessTx,\n params: CreateAgentAuthorizationRequestParams,\n): Promise<AgentAuthorizationRequest> {\n const rows = await tx.insert(agentAuthorizationRequests).values(params).returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentAuthorizationRequest(row);\n}\n\nexport async function findPendingAgentAuthorizationRequest(params: {\n id: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentAuthorizationRequest | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentAuthorizationRequests)\n .where(\n and(\n eq(agentAuthorizationRequests.id, params.id),\n isNull(agentAuthorizationRequests.consumedAt),\n gt(agentAuthorizationRequests.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentAuthorizationRequest(row) : undefined;\n}\n\nexport async function consumeAgentAuthorizationRequest(params: {\n id: string;\n}): Promise<AgentAuthorizationRequest | undefined> {\n return await db().transaction((tx) => consumeAgentAuthorizationRequestTx(tx, params));\n}\n\n/**\n * Claims a pending request in the caller's transaction. The expiry and\n * consumed-at predicates are part of the update so concurrent approval and\n * denial can have only one winner.\n */\nexport async function consumeAgentAuthorizationRequestTx(\n tx: AgentAccessTx,\n params: {id: string},\n): Promise<AgentAuthorizationRequest | undefined> {\n const rows = await tx\n .update(agentAuthorizationRequests)\n .set({consumedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentAuthorizationRequests.id, params.id),\n isNull(agentAuthorizationRequests.consumedAt),\n gt(agentAuthorizationRequests.expiresAt, sql`now()`),\n ),\n )\n .returning();\n const row = rows[0];\n return row ? toAgentAuthorizationRequest(row) : undefined;\n}\n\nexport interface CreateAgentGrantParams {\n userId: string;\n workspaceId: string;\n /** Internal `auth_agent_clients.id`, not the public OAuth `client_id`. */\n clientId: string;\n scopes: string[];\n}\n\nexport async function createAgentGrant(params: CreateAgentGrantParams): Promise<AgentGrant> {\n return await db().transaction((tx) => createAgentGrantTx(tx, params));\n}\n\nexport async function createAgentGrantTx(\n tx: AgentAccessTx,\n params: CreateAgentGrantParams,\n): Promise<AgentGrant> {\n const rows = await tx\n .insert(agentGrants)\n .values(params)\n .onConflictDoUpdate({\n target: [agentGrants.userId, agentGrants.workspaceId, agentGrants.clientId],\n targetWhere: sql`${agentGrants.revokedAt} IS NULL AND ${agentGrants.terminalAt} IS NULL`,\n set: {\n scopes: params.scopes,\n updatedAt: sql`now()`,\n },\n })\n .returning();\n const row = rows[0];\n if (!row) throw new Error('Upsert returned no rows');\n\n // Refresh tokens derive their scopes from the grant. Reauthorization must\n // invalidate existing tokens before the grant's scopes can be widened.\n await tx\n .update(agentRefreshTokens)\n .set({revokedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentRefreshTokens.grantId, row.id),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n ),\n );\n\n await markAgentClientReferenced(tx, {clientUuid: params.clientId});\n return toAgentGrant(row);\n}\n\nexport async function findAgentGrant(params: {\n id: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentGrant | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentGrants)\n .where(eq(agentGrants.id, params.id))\n .limit(1);\n const row = rows[0];\n return row ? toAgentGrant(row) : undefined;\n}\n\n/**\n * Locks one grant row until the surrounding transaction ends. Code exchange\n * and lifecycle transitions must use this same primitive before inspecting or\n * changing grant state. Callers must keep the transaction database-only while\n * this lock is held; external I/O must happen after commit.\n */\nexport async function lockAgentGrant(\n tx: AgentAccessTx,\n params: {grantId: string},\n): Promise<AgentGrant | undefined> {\n const rows = await tx\n .select()\n .from(agentGrants)\n .where(eq(agentGrants.id, params.grantId))\n .for('update')\n .limit(1);\n const row = rows[0];\n return row ? toAgentGrant(row) : undefined;\n}\n\nexport interface CreateAgentAuthorizationCodeParams {\n grantId: string;\n hashedCode: string;\n codeChallenge: string;\n redirectUri: string;\n resource: string;\n expiresAt: Date;\n}\n\nexport async function createAgentAuthorizationCode(\n params: CreateAgentAuthorizationCodeParams,\n): Promise<AgentAuthorizationCode> {\n return await db().transaction((tx) => createAgentAuthorizationCodeTx(tx, params));\n}\n\nexport async function createAgentAuthorizationCodeTx(\n tx: AgentAccessTx,\n params: CreateAgentAuthorizationCodeParams,\n): Promise<AgentAuthorizationCode> {\n const rows = await tx.insert(agentAuthorizationCodes).values(params).returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentAuthorizationCode(row);\n}\n\nexport async function findAgentAuthorizationCodeByHash(params: {\n hashedCode: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentAuthorizationCode | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentAuthorizationCodes)\n .where(eq(agentAuthorizationCodes.hashedCode, params.hashedCode))\n .limit(1);\n const row = rows[0];\n return row ? toAgentAuthorizationCode(row) : undefined;\n}\n\nexport async function findActiveAgentAuthorizationCodeByHash(params: {\n hashedCode: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentAuthorizationCode | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentAuthorizationCodes)\n .where(\n and(\n eq(agentAuthorizationCodes.hashedCode, params.hashedCode),\n isNull(agentAuthorizationCodes.consumedAt),\n gt(agentAuthorizationCodes.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentAuthorizationCode(row) : undefined;\n}\n\nexport async function consumeAgentAuthorizationCode(params: {\n hashedCode: string;\n}): Promise<AgentAuthorizationCode | undefined> {\n return await db().transaction((tx) => consumeAgentAuthorizationCodeTx(tx, params));\n}\n\n/** Claims an authorization code exactly once, including its 60-second TTL. */\nexport async function consumeAgentAuthorizationCodeTx(\n tx: AgentAccessTx,\n params: {hashedCode: string},\n): Promise<AgentAuthorizationCode | undefined> {\n const rows = await tx\n .update(agentAuthorizationCodes)\n .set({consumedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentAuthorizationCodes.hashedCode, params.hashedCode),\n isNull(agentAuthorizationCodes.consumedAt),\n gt(agentAuthorizationCodes.expiresAt, sql`now()`),\n ),\n )\n .returning();\n const row = rows[0];\n return row ? toAgentAuthorizationCode(row) : undefined;\n}\n\nexport interface CreateAgentRefreshTokenParams {\n grantId: string;\n hashedToken: string;\n expiresAt: Date;\n}\n\nexport async function createAgentRefreshToken(\n params: CreateAgentRefreshTokenParams,\n): Promise<AgentRefreshToken> {\n return await db().transaction((tx) => createAgentRefreshTokenTx(tx, params));\n}\n\nexport async function createAgentRefreshTokenTx(\n tx: AgentAccessTx,\n params: CreateAgentRefreshTokenParams,\n): Promise<AgentRefreshToken> {\n const rows = await tx.insert(agentRefreshTokens).values(params).returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentRefreshToken(row);\n}\n\nexport async function findAgentRefreshTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentRefreshToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentRefreshTokens)\n .where(eq(agentRefreshTokens.hashedToken, params.hashedToken))\n .limit(1);\n const row = rows[0];\n return row ? toAgentRefreshToken(row) : undefined;\n}\n\nexport async function findActiveAgentRefreshTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentRefreshToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.hashedToken, params.hashedToken),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentRefreshToken(row) : undefined;\n}\n\n/** Rotates a refresh token atomically; a concurrent rotation cannot win twice. */\nexport async function rotateAgentRefreshToken(params: {\n hashedToken: string;\n replacementHashedToken: string;\n replacementExpiresAt: Date;\n}): Promise<AgentRefreshToken | undefined> {\n return await db().transaction((tx) => rotateAgentRefreshTokenTx(tx, params));\n}\n\nexport async function rotateAgentRefreshTokenTx(\n tx: AgentAccessTx,\n params: {\n hashedToken: string;\n replacementHashedToken: string;\n replacementExpiresAt: Date;\n },\n): Promise<AgentRefreshToken | undefined> {\n const rows = await tx\n .update(agentRefreshTokens)\n .set({rotatedAt: sql`now()`, lastUsedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentRefreshTokens.hashedToken, params.hashedToken),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, sql`now()`),\n ),\n )\n .returning();\n const row = rows[0];\n if (!row) return undefined;\n\n return await createAgentRefreshTokenTx(tx, {\n grantId: row.grantId,\n hashedToken: params.replacementHashedToken,\n expiresAt: params.replacementExpiresAt,\n });\n}\n\nexport async function revokeAgentRefreshToken(params: {\n id: string;\n}): Promise<AgentRefreshToken | undefined> {\n return await db().transaction(async (tx) => {\n const rows = await tx\n .update(agentRefreshTokens)\n .set({revokedAt: sql`now()`, updatedAt: sql`now()`})\n .where(and(eq(agentRefreshTokens.id, params.id), isNull(agentRefreshTokens.revokedAt)))\n .returning();\n const row = rows[0];\n return row ? toAgentRefreshToken(row) : undefined;\n });\n}\n\nexport interface CreateAgentPersonalAccessTokenParams {\n userId: string;\n workspaceId: string;\n hashedToken: string;\n prefix: string;\n name: string;\n scopes: string[];\n expiresAt: Date;\n}\n\nexport async function createAgentPersonalAccessToken(\n params: CreateAgentPersonalAccessTokenParams,\n): Promise<AgentPersonalAccessToken> {\n return await db().transaction((tx) => createAgentPersonalAccessTokenTx(tx, params));\n}\n\nexport async function createAgentPersonalAccessTokenTx(\n tx: AgentAccessTx,\n params: CreateAgentPersonalAccessTokenParams,\n): Promise<AgentPersonalAccessToken> {\n const rows = await tx.insert(agentPersonalAccessTokens).values(params).returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentPersonalAccessToken(row);\n}\n\nexport async function findAgentPersonalAccessTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentPersonalAccessTokens)\n .where(eq(agentPersonalAccessTokens.hashedToken, params.hashedToken))\n .limit(1);\n const row = rows[0];\n return row ? toAgentPersonalAccessToken(row) : undefined;\n}\n\nexport async function findActiveAgentPersonalAccessTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentPersonalAccessTokens)\n .where(\n and(\n eq(agentPersonalAccessTokens.hashedToken, params.hashedToken),\n isNull(agentPersonalAccessTokens.revokedAt),\n gt(agentPersonalAccessTokens.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentPersonalAccessToken(row) : undefined;\n}\n\nexport async function markAgentPersonalAccessTokenUsed(params: {\n id: string;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const rows = await db()\n .update(agentPersonalAccessTokens)\n .set({lastUsedAt: sql`now()`, updatedAt: sql`now()`})\n .where(eq(agentPersonalAccessTokens.id, params.id))\n .returning();\n const row = rows[0];\n return row ? toAgentPersonalAccessToken(row) : undefined;\n}\n\nexport async function revokeAgentPersonalAccessToken(params: {\n id: string;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const rows = await db()\n .update(agentPersonalAccessTokens)\n .set({revokedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(eq(agentPersonalAccessTokens.id, params.id), isNull(agentPersonalAccessTokens.revokedAt)),\n )\n .returning();\n const row = rows[0];\n return row ? toAgentPersonalAccessToken(row) : undefined;\n}\n\nexport interface PruneAgentAccessParams {\n retentionDays?: number;\n limit?: number;\n now?: Date;\n}\n\n/** Deletes terminal credentials and ephemeral authorization rows in bounded batches. */\nexport async function pruneAgentAccess(params: PruneAgentAccessParams = {}): Promise<number> {\n const now = params.now ?? new Date();\n const retentionDays = params.retentionDays ?? 7;\n const limit = params.limit ?? 1000;\n const cutoff = new Date(now.getTime() - retentionDays * 24 * 60 * 60 * 1000);\n\n return await db().transaction(async (tx) => {\n const requestIds = tx\n .select({id: agentAuthorizationRequests.id})\n .from(agentAuthorizationRequests)\n .where(\n or(\n lt(agentAuthorizationRequests.consumedAt, cutoff),\n and(\n isNull(agentAuthorizationRequests.consumedAt),\n lt(agentAuthorizationRequests.expiresAt, cutoff),\n ),\n ),\n )\n .orderBy(asc(agentAuthorizationRequests.expiresAt), asc(agentAuthorizationRequests.id))\n .limit(limit);\n const codeIds = tx\n .select({id: agentAuthorizationCodes.id})\n .from(agentAuthorizationCodes)\n .where(\n or(\n lt(agentAuthorizationCodes.consumedAt, cutoff),\n and(\n isNull(agentAuthorizationCodes.consumedAt),\n lt(agentAuthorizationCodes.expiresAt, cutoff),\n ),\n ),\n )\n .orderBy(asc(agentAuthorizationCodes.expiresAt), asc(agentAuthorizationCodes.id))\n .limit(limit);\n const refreshTokenIds = tx\n .select({id: agentRefreshTokens.id})\n .from(agentRefreshTokens)\n .where(\n or(\n lt(agentRefreshTokens.rotatedAt, cutoff),\n and(isNull(agentRefreshTokens.rotatedAt), lt(agentRefreshTokens.revokedAt, cutoff)),\n and(\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n lt(agentRefreshTokens.expiresAt, cutoff),\n ),\n ),\n )\n .orderBy(asc(agentRefreshTokens.expiresAt), asc(agentRefreshTokens.id))\n .limit(limit);\n const patIds = tx\n .select({id: agentPersonalAccessTokens.id})\n .from(agentPersonalAccessTokens)\n .where(\n or(\n lt(agentPersonalAccessTokens.revokedAt, cutoff),\n and(\n isNull(agentPersonalAccessTokens.revokedAt),\n lt(agentPersonalAccessTokens.expiresAt, cutoff),\n ),\n ),\n )\n .orderBy(asc(agentPersonalAccessTokens.expiresAt), asc(agentPersonalAccessTokens.id))\n .limit(limit);\n\n const [requests, codes, refreshTokens, pats] = await Promise.all([\n tx\n .delete(agentAuthorizationRequests)\n .where(inArray(agentAuthorizationRequests.id, requestIds))\n .returning({id: agentAuthorizationRequests.id}),\n tx\n .delete(agentAuthorizationCodes)\n .where(inArray(agentAuthorizationCodes.id, codeIds))\n .returning({id: agentAuthorizationCodes.id}),\n tx\n .delete(agentRefreshTokens)\n .where(inArray(agentRefreshTokens.id, refreshTokenIds))\n .returning({id: agentRefreshTokens.id}),\n tx\n .delete(agentPersonalAccessTokens)\n .where(inArray(agentPersonalAccessTokens.id, patIds))\n .returning({id: agentPersonalAccessTokens.id}),\n ]);\n return requests.length + codes.length + refreshTokens.length + pats.length;\n });\n}\n"],"names":["and","asc","eq","gt","inArray","isNull","lt","or","sql","db","agentAuthorizationCodes","agentAuthorizationRequests","agentClients","agentGrants","agentPersonalAccessTokens","agentRefreshTokens","toAgentAuthorizationCode","toAgentAuthorizationRequest","toAgentClient","toAgentGrant","toAgentPersonalAccessToken","toAgentRefreshToken","createAgentClient","params","transaction","tx","createAgentClientTx","rows","insert","values","onConflictDoUpdate","target","clientId","set","lastSeenAt","unreferencedAt","updatedAt","returning","row","Error","findAgentClientByClientId","executor","select","from","where","limit","undefined","markAgentClientReferenced","update","id","clientUuid","markAgentClientUnreferenced","createAgentAuthorizationRequest","createAgentAuthorizationRequestTx","findPendingAgentAuthorizationRequest","consumedAt","expiresAt","consumeAgentAuthorizationRequest","consumeAgentAuthorizationRequestTx","createAgentGrant","createAgentGrantTx","userId","workspaceId","targetWhere","revokedAt","terminalAt","scopes","grantId","rotatedAt","findAgentGrant","lockAgentGrant","for","createAgentAuthorizationCode","createAgentAuthorizationCodeTx","findAgentAuthorizationCodeByHash","hashedCode","findActiveAgentAuthorizationCodeByHash","consumeAgentAuthorizationCode","consumeAgentAuthorizationCodeTx","createAgentRefreshToken","createAgentRefreshTokenTx","findAgentRefreshTokenByHash","hashedToken","findActiveAgentRefreshTokenByHash","rotateAgentRefreshToken","rotateAgentRefreshTokenTx","lastUsedAt","replacementHashedToken","replacementExpiresAt","revokeAgentRefreshToken","createAgentPersonalAccessToken","createAgentPersonalAccessTokenTx","findAgentPersonalAccessTokenByHash","findActiveAgentPersonalAccessTokenByHash","markAgentPersonalAccessTokenUsed","revokeAgentPersonalAccessToken","pruneAgentAccess","now","Date","retentionDays","cutoff","getTime","requestIds","orderBy","codeIds","refreshTokenIds","patIds","requests","codes","refreshTokens","pats","Promise","all","delete","length"],"mappings":"AAAA,SAAQA,GAAG,EAAEC,GAAG,EAAEC,EAAE,EAAEC,EAAE,EAAEC,OAAO,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,EAAEC,GAAG,QAAO,cAAc;AAS3E,SAAQC,EAAE,QAAO,UAAU;AAC3B,SACEC,uBAAuB,EACvBC,0BAA0B,EAC1BC,YAAY,EACZC,WAAW,EACXC,yBAAyB,EACzBC,kBAAkB,EAClBC,wBAAwB,EACxBC,2BAA2B,EAC3BC,aAAa,EACbC,YAAY,EACZC,0BAA0B,EAC1BC,mBAAmB,QACd,2BAA2B;AAalC,OAAO,eAAeC,kBAAkBC,MAA+B;IACrE,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAOC,oBAAoBD,IAAIF;AAChE;AAEA,OAAO,eAAeG,oBACpBD,EAAiB,EACjBF,MAA+B;IAE/B,MAAMI,OAAO,MAAMF,GAChBG,MAAM,CAAChB,cACPiB,MAAM,CAACN,QACPO,kBAAkB,CAAC;QAClBC,QAAQnB,aAAaoB,QAAQ;QAC7BC,KAAK;YACHC,YAAY1B,GAAG,CAAC,KAAK,CAAC;YACtB2B,gBAAgB;YAChBC,WAAW5B,GAAG,CAAC,KAAK,CAAC;QACvB;IACF,GACC6B,SAAS;IACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,IAAI,CAACW,KAAK,MAAM,IAAIC,MAAM;IAC1B,OAAOrB,cAAcoB;AACvB;AAEA,OAAO,eAAeE,0BAA0BjB,MAG/C;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAAC/B,cACLgC,KAAK,CAAC1C,GAAGU,aAAaoB,QAAQ,EAAET,OAAOS,QAAQ,GAC/Ca,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMpB,cAAcoB,OAAOQ;AACpC;AAEA,OAAO,eAAeC,0BACpBtB,EAAiB,EACjBF,MAA4B;IAE5B,MAAME,GACHuB,MAAM,CAACpC,cACPqB,GAAG,CAAC;QAACE,gBAAgB;QAAMD,YAAY1B,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GACxEoC,KAAK,CAAC1C,GAAGU,aAAaqC,EAAE,EAAE1B,OAAO2B,UAAU;AAChD;AAEA,OAAO,eAAeC,4BACpB1B,EAAiB,EACjBF,MAA4B;IAE5B,MAAME,GACHuB,MAAM,CAACpC,cACPqB,GAAG,CAAC;QAACE,gBAAgB3B,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GACtDoC,KAAK,CAAC1C,GAAGU,aAAaqC,EAAE,EAAE1B,OAAO2B,UAAU;AAChD;AAaA,OAAO,eAAeE,gCACpB7B,MAA6C;IAE7C,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAO4B,kCAAkC5B,IAAIF;AAC9E;AAEA,OAAO,eAAe8B,kCACpB5B,EAAiB,EACjBF,MAA6C;IAE7C,MAAMI,OAAO,MAAMF,GAAGG,MAAM,CAACjB,4BAA4BkB,MAAM,CAACN,QAAQc,SAAS;IACjF,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,IAAI,CAACW,KAAK,MAAM,IAAIC,MAAM;IAC1B,OAAOtB,4BAA4BqB;AACrC;AAEA,OAAO,eAAegB,qCAAqC/B,MAG1D;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAAChC,4BACLiC,KAAK,CACJ5C,IACEE,GAAGS,2BAA2BsC,EAAE,EAAE1B,OAAO0B,EAAE,GAC3C5C,OAAOM,2BAA2B4C,UAAU,GAC5CpD,GAAGQ,2BAA2B6C,SAAS,EAAEhD,GAAG,CAAC,KAAK,CAAC,IAGtDqC,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMrB,4BAA4BqB,OAAOQ;AAClD;AAEA,OAAO,eAAeW,iCAAiClC,MAEtD;IACC,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAOiC,mCAAmCjC,IAAIF;AAC/E;AAEA;;;;CAIC,GACD,OAAO,eAAemC,mCACpBjC,EAAiB,EACjBF,MAAoB;IAEpB,MAAMI,OAAO,MAAMF,GAChBuB,MAAM,CAACrC,4BACPsB,GAAG,CAAC;QAACsB,YAAY/C,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GAClDoC,KAAK,CACJ5C,IACEE,GAAGS,2BAA2BsC,EAAE,EAAE1B,OAAO0B,EAAE,GAC3C5C,OAAOM,2BAA2B4C,UAAU,GAC5CpD,GAAGQ,2BAA2B6C,SAAS,EAAEhD,GAAG,CAAC,KAAK,CAAC,IAGtD6B,SAAS;IACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMrB,4BAA4BqB,OAAOQ;AAClD;AAUA,OAAO,eAAea,iBAAiBpC,MAA8B;IACnE,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAOmC,mBAAmBnC,IAAIF;AAC/D;AAEA,OAAO,eAAeqC,mBACpBnC,EAAiB,EACjBF,MAA8B;IAE9B,MAAMI,OAAO,MAAMF,GAChBG,MAAM,CAACf,aACPgB,MAAM,CAACN,QACPO,kBAAkB,CAAC;QAClBC,QAAQ;YAAClB,YAAYgD,MAAM;YAAEhD,YAAYiD,WAAW;YAAEjD,YAAYmB,QAAQ;SAAC;QAC3E+B,aAAavD,GAAG,CAAC,EAAEK,YAAYmD,SAAS,CAAC,aAAa,EAAEnD,YAAYoD,UAAU,CAAC,QAAQ,CAAC;QACxFhC,KAAK;YACHiC,QAAQ3C,OAAO2C,MAAM;YACrB9B,WAAW5B,GAAG,CAAC,KAAK,CAAC;QACvB;IACF,GACC6B,SAAS;IACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,IAAI,CAACW,KAAK,MAAM,IAAIC,MAAM;IAE1B,0EAA0E;IAC1E,uEAAuE;IACvE,MAAMd,GACHuB,MAAM,CAACjC,oBACPkB,GAAG,CAAC;QAAC+B,WAAWxD,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GACjDoC,KAAK,CACJ5C,IACEE,GAAGa,mBAAmBoD,OAAO,EAAE7B,IAAIW,EAAE,GACrC5C,OAAOU,mBAAmBqD,SAAS,GACnC/D,OAAOU,mBAAmBiD,SAAS;IAIzC,MAAMjB,0BAA0BtB,IAAI;QAACyB,YAAY3B,OAAOS,QAAQ;IAAA;IAChE,OAAOb,aAAamB;AACtB;AAEA,OAAO,eAAe+B,eAAe9C,MAGpC;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAAC9B,aACL+B,KAAK,CAAC1C,GAAGW,YAAYoC,EAAE,EAAE1B,OAAO0B,EAAE,GAClCJ,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMnB,aAAamB,OAAOQ;AACnC;AAEA;;;;;CAKC,GACD,OAAO,eAAewB,eACpB7C,EAAiB,EACjBF,MAAyB;IAEzB,MAAMI,OAAO,MAAMF,GAChBiB,MAAM,GACNC,IAAI,CAAC9B,aACL+B,KAAK,CAAC1C,GAAGW,YAAYoC,EAAE,EAAE1B,OAAO4C,OAAO,GACvCI,GAAG,CAAC,UACJ1B,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMnB,aAAamB,OAAOQ;AACnC;AAWA,OAAO,eAAe0B,6BACpBjD,MAA0C;IAE1C,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAOgD,+BAA+BhD,IAAIF;AAC3E;AAEA,OAAO,eAAekD,+BACpBhD,EAAiB,EACjBF,MAA0C;IAE1C,MAAMI,OAAO,MAAMF,GAAGG,MAAM,CAAClB,yBAAyBmB,MAAM,CAACN,QAAQc,SAAS;IAC9E,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,IAAI,CAACW,KAAK,MAAM,IAAIC,MAAM;IAC1B,OAAOvB,yBAAyBsB;AAClC;AAEA,OAAO,eAAeoC,iCAAiCnD,MAGtD;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAACjC,yBACLkC,KAAK,CAAC1C,GAAGQ,wBAAwBiE,UAAU,EAAEpD,OAAOoD,UAAU,GAC9D9B,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMtB,yBAAyBsB,OAAOQ;AAC/C;AAEA,OAAO,eAAe8B,uCAAuCrD,MAG5D;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAACjC,yBACLkC,KAAK,CACJ5C,IACEE,GAAGQ,wBAAwBiE,UAAU,EAAEpD,OAAOoD,UAAU,GACxDtE,OAAOK,wBAAwB6C,UAAU,GACzCpD,GAAGO,wBAAwB8C,SAAS,EAAEhD,GAAG,CAAC,KAAK,CAAC,IAGnDqC,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMtB,yBAAyBsB,OAAOQ;AAC/C;AAEA,OAAO,eAAe+B,8BAA8BtD,MAEnD;IACC,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAOqD,gCAAgCrD,IAAIF;AAC5E;AAEA,4EAA4E,GAC5E,OAAO,eAAeuD,gCACpBrD,EAAiB,EACjBF,MAA4B;IAE5B,MAAMI,OAAO,MAAMF,GAChBuB,MAAM,CAACtC,yBACPuB,GAAG,CAAC;QAACsB,YAAY/C,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GAClDoC,KAAK,CACJ5C,IACEE,GAAGQ,wBAAwBiE,UAAU,EAAEpD,OAAOoD,UAAU,GACxDtE,OAAOK,wBAAwB6C,UAAU,GACzCpD,GAAGO,wBAAwB8C,SAAS,EAAEhD,GAAG,CAAC,KAAK,CAAC,IAGnD6B,SAAS;IACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMtB,yBAAyBsB,OAAOQ;AAC/C;AAQA,OAAO,eAAeiC,wBACpBxD,MAAqC;IAErC,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAOuD,0BAA0BvD,IAAIF;AACtE;AAEA,OAAO,eAAeyD,0BACpBvD,EAAiB,EACjBF,MAAqC;IAErC,MAAMI,OAAO,MAAMF,GAAGG,MAAM,CAACb,oBAAoBc,MAAM,CAACN,QAAQc,SAAS;IACzE,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,IAAI,CAACW,KAAK,MAAM,IAAIC,MAAM;IAC1B,OAAOlB,oBAAoBiB;AAC7B;AAEA,OAAO,eAAe2C,4BAA4B1D,MAGjD;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAAC5B,oBACL6B,KAAK,CAAC1C,GAAGa,mBAAmBmE,WAAW,EAAE3D,OAAO2D,WAAW,GAC3DrC,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMjB,oBAAoBiB,OAAOQ;AAC1C;AAEA,OAAO,eAAeqC,kCAAkC5D,MAGvD;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAAC5B,oBACL6B,KAAK,CACJ5C,IACEE,GAAGa,mBAAmBmE,WAAW,EAAE3D,OAAO2D,WAAW,GACrD7E,OAAOU,mBAAmBqD,SAAS,GACnC/D,OAAOU,mBAAmBiD,SAAS,GACnC7D,GAAGY,mBAAmByC,SAAS,EAAEhD,GAAG,CAAC,KAAK,CAAC,IAG9CqC,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMjB,oBAAoBiB,OAAOQ;AAC1C;AAEA,gFAAgF,GAChF,OAAO,eAAesC,wBAAwB7D,MAI7C;IACC,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAO4D,0BAA0B5D,IAAIF;AACtE;AAEA,OAAO,eAAe8D,0BACpB5D,EAAiB,EACjBF,MAIC;IAED,MAAMI,OAAO,MAAMF,GAChBuB,MAAM,CAACjC,oBACPkB,GAAG,CAAC;QAACmC,WAAW5D,GAAG,CAAC,KAAK,CAAC;QAAE8E,YAAY9E,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GACzEoC,KAAK,CACJ5C,IACEE,GAAGa,mBAAmBmE,WAAW,EAAE3D,OAAO2D,WAAW,GACrD7E,OAAOU,mBAAmBqD,SAAS,GACnC/D,OAAOU,mBAAmBiD,SAAS,GACnC7D,GAAGY,mBAAmByC,SAAS,EAAEhD,GAAG,CAAC,KAAK,CAAC,IAG9C6B,SAAS;IACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,IAAI,CAACW,KAAK,OAAOQ;IAEjB,OAAO,MAAMkC,0BAA0BvD,IAAI;QACzC0C,SAAS7B,IAAI6B,OAAO;QACpBe,aAAa3D,OAAOgE,sBAAsB;QAC1C/B,WAAWjC,OAAOiE,oBAAoB;IACxC;AACF;AAEA,OAAO,eAAeC,wBAAwBlE,MAE7C;IACC,OAAO,MAAMd,KAAKe,WAAW,CAAC,OAAOC;QACnC,MAAME,OAAO,MAAMF,GAChBuB,MAAM,CAACjC,oBACPkB,GAAG,CAAC;YAAC+B,WAAWxD,GAAG,CAAC,KAAK,CAAC;YAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;QAAA,GACjDoC,KAAK,CAAC5C,IAAIE,GAAGa,mBAAmBkC,EAAE,EAAE1B,OAAO0B,EAAE,GAAG5C,OAAOU,mBAAmBiD,SAAS,IACnF3B,SAAS;QACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;QACnB,OAAOW,MAAMjB,oBAAoBiB,OAAOQ;IAC1C;AACF;AAYA,OAAO,eAAe4C,+BACpBnE,MAA4C;IAE5C,OAAO,MAAMd,KAAKe,WAAW,CAAC,CAACC,KAAOkE,iCAAiClE,IAAIF;AAC7E;AAEA,OAAO,eAAeoE,iCACpBlE,EAAiB,EACjBF,MAA4C;IAE5C,MAAMI,OAAO,MAAMF,GAAGG,MAAM,CAACd,2BAA2Be,MAAM,CAACN,QAAQc,SAAS;IAChF,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,IAAI,CAACW,KAAK,MAAM,IAAIC,MAAM;IAC1B,OAAOnB,2BAA2BkB;AACpC;AAEA,OAAO,eAAesD,mCAAmCrE,MAGxD;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAAC7B,2BACL8B,KAAK,CAAC1C,GAAGY,0BAA0BoE,WAAW,EAAE3D,OAAO2D,WAAW,GAClErC,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMlB,2BAA2BkB,OAAOQ;AACjD;AAEA,OAAO,eAAe+C,yCAAyCtE,MAG9D;IACC,MAAMkB,WAAWlB,OAAOkB,QAAQ,IAAIhC;IACpC,MAAMkB,OAAO,MAAMc,SAChBC,MAAM,GACNC,IAAI,CAAC7B,2BACL8B,KAAK,CACJ5C,IACEE,GAAGY,0BAA0BoE,WAAW,EAAE3D,OAAO2D,WAAW,GAC5D7E,OAAOS,0BAA0BkD,SAAS,GAC1C7D,GAAGW,0BAA0B0C,SAAS,EAAEhD,GAAG,CAAC,KAAK,CAAC,IAGrDqC,KAAK,CAAC;IACT,MAAMP,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMlB,2BAA2BkB,OAAOQ;AACjD;AAEA,OAAO,eAAegD,iCAAiCvE,MAEtD;IACC,MAAMI,OAAO,MAAMlB,KAChBuC,MAAM,CAAClC,2BACPmB,GAAG,CAAC;QAACqD,YAAY9E,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GAClDoC,KAAK,CAAC1C,GAAGY,0BAA0BmC,EAAE,EAAE1B,OAAO0B,EAAE,GAChDZ,SAAS;IACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMlB,2BAA2BkB,OAAOQ;AACjD;AAEA,OAAO,eAAeiD,+BAA+BxE,MAEpD;IACC,MAAMI,OAAO,MAAMlB,KAChBuC,MAAM,CAAClC,2BACPmB,GAAG,CAAC;QAAC+B,WAAWxD,GAAG,CAAC,KAAK,CAAC;QAAE4B,WAAW5B,GAAG,CAAC,KAAK,CAAC;IAAA,GACjDoC,KAAK,CACJ5C,IAAIE,GAAGY,0BAA0BmC,EAAE,EAAE1B,OAAO0B,EAAE,GAAG5C,OAAOS,0BAA0BkD,SAAS,IAE5F3B,SAAS;IACZ,MAAMC,MAAMX,IAAI,CAAC,EAAE;IACnB,OAAOW,MAAMlB,2BAA2BkB,OAAOQ;AACjD;AAQA,sFAAsF,GACtF,OAAO,eAAekD,iBAAiBzE,SAAiC,CAAC,CAAC;IACxE,MAAM0E,MAAM1E,OAAO0E,GAAG,IAAI,IAAIC;IAC9B,MAAMC,gBAAgB5E,OAAO4E,aAAa,IAAI;IAC9C,MAAMtD,QAAQtB,OAAOsB,KAAK,IAAI;IAC9B,MAAMuD,SAAS,IAAIF,KAAKD,IAAII,OAAO,KAAKF,gBAAgB,KAAK,KAAK,KAAK;IAEvE,OAAO,MAAM1F,KAAKe,WAAW,CAAC,OAAOC;QACnC,MAAM6E,aAAa7E,GAChBiB,MAAM,CAAC;YAACO,IAAItC,2BAA2BsC,EAAE;QAAA,GACzCN,IAAI,CAAChC,4BACLiC,KAAK,CACJrC,GACED,GAAGK,2BAA2B4C,UAAU,EAAE6C,SAC1CpG,IACEK,OAAOM,2BAA2B4C,UAAU,GAC5CjD,GAAGK,2BAA2B6C,SAAS,EAAE4C,WAI9CG,OAAO,CAACtG,IAAIU,2BAA2B6C,SAAS,GAAGvD,IAAIU,2BAA2BsC,EAAE,GACpFJ,KAAK,CAACA;QACT,MAAM2D,UAAU/E,GACbiB,MAAM,CAAC;YAACO,IAAIvC,wBAAwBuC,EAAE;QAAA,GACtCN,IAAI,CAACjC,yBACLkC,KAAK,CACJrC,GACED,GAAGI,wBAAwB6C,UAAU,EAAE6C,SACvCpG,IACEK,OAAOK,wBAAwB6C,UAAU,GACzCjD,GAAGI,wBAAwB8C,SAAS,EAAE4C,WAI3CG,OAAO,CAACtG,IAAIS,wBAAwB8C,SAAS,GAAGvD,IAAIS,wBAAwBuC,EAAE,GAC9EJ,KAAK,CAACA;QACT,MAAM4D,kBAAkBhF,GACrBiB,MAAM,CAAC;YAACO,IAAIlC,mBAAmBkC,EAAE;QAAA,GACjCN,IAAI,CAAC5B,oBACL6B,KAAK,CACJrC,GACED,GAAGS,mBAAmBqD,SAAS,EAAEgC,SACjCpG,IAAIK,OAAOU,mBAAmBqD,SAAS,GAAG9D,GAAGS,mBAAmBiD,SAAS,EAAEoC,UAC3EpG,IACEK,OAAOU,mBAAmBqD,SAAS,GACnC/D,OAAOU,mBAAmBiD,SAAS,GACnC1D,GAAGS,mBAAmByC,SAAS,EAAE4C,WAItCG,OAAO,CAACtG,IAAIc,mBAAmByC,SAAS,GAAGvD,IAAIc,mBAAmBkC,EAAE,GACpEJ,KAAK,CAACA;QACT,MAAM6D,SAASjF,GACZiB,MAAM,CAAC;YAACO,IAAInC,0BAA0BmC,EAAE;QAAA,GACxCN,IAAI,CAAC7B,2BACL8B,KAAK,CACJrC,GACED,GAAGQ,0BAA0BkD,SAAS,EAAEoC,SACxCpG,IACEK,OAAOS,0BAA0BkD,SAAS,GAC1C1D,GAAGQ,0BAA0B0C,SAAS,EAAE4C,WAI7CG,OAAO,CAACtG,IAAIa,0BAA0B0C,SAAS,GAAGvD,IAAIa,0BAA0BmC,EAAE,GAClFJ,KAAK,CAACA;QAET,MAAM,CAAC8D,UAAUC,OAAOC,eAAeC,KAAK,GAAG,MAAMC,QAAQC,GAAG,CAAC;YAC/DvF,GACGwF,MAAM,CAACtG,4BACPiC,KAAK,CAACxC,QAAQO,2BAA2BsC,EAAE,EAAEqD,aAC7CjE,SAAS,CAAC;gBAACY,IAAItC,2BAA2BsC,EAAE;YAAA;YAC/CxB,GACGwF,MAAM,CAACvG,yBACPkC,KAAK,CAACxC,QAAQM,wBAAwBuC,EAAE,EAAEuD,UAC1CnE,SAAS,CAAC;gBAACY,IAAIvC,wBAAwBuC,EAAE;YAAA;YAC5CxB,GACGwF,MAAM,CAAClG,oBACP6B,KAAK,CAACxC,QAAQW,mBAAmBkC,EAAE,EAAEwD,kBACrCpE,SAAS,CAAC;gBAACY,IAAIlC,mBAAmBkC,EAAE;YAAA;YACvCxB,GACGwF,MAAM,CAACnG,2BACP8B,KAAK,CAACxC,QAAQU,0BAA0BmC,EAAE,EAAEyD,SAC5CrE,SAAS,CAAC;gBAACY,IAAInC,0BAA0BmC,EAAE;YAAA;SAC/C;QACD,OAAO0D,SAASO,MAAM,GAAGN,MAAMM,MAAM,GAAGL,cAAcK,MAAM,GAAGJ,KAAKI,MAAM;IAC5E;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/db/agent-access.ts"],"sourcesContent":["import {and, asc, eq, gt, inArray, isNotNull, isNull, lte, notExists, or, sql} from 'drizzle-orm';\nimport {config} from '#config.js';\nimport type {\n AgentAuthorizationCode,\n AgentAuthorizationRequest,\n AgentClient,\n AgentGrant,\n AgentPersonalAccessToken,\n AgentRefreshToken,\n} from '#core/entities/agent-access.js';\nimport {\n AGENT_ACCESS_RETENTION_TIMEOUT_MARGIN_MS,\n AGENT_AUTHORIZATION_RETENTION_DAYS,\n AGENT_CLIENT_RETENTION_DAYS,\n AGENT_GRANT_RETENTION_DAYS,\n AGENT_PAT_RETENTION_DAYS,\n AGENT_REFRESH_TOKEN_RETENTION_DAYS,\n} from './agent-access-retention.js';\nimport {db} from './db.js';\nimport {\n agentAuthorizationCodes,\n agentAuthorizationRequests,\n agentClients,\n agentGrants,\n agentPersonalAccessTokens,\n agentRefreshTokens,\n toAgentAuthorizationCode,\n toAgentAuthorizationRequest,\n toAgentClient,\n toAgentGrant,\n toAgentPersonalAccessToken,\n toAgentRefreshToken,\n} from './schema/agent-access.js';\nimport {users} from './schema/users.js';\n\nexport type AgentAccessTx = Parameters<Parameters<ReturnType<typeof db>['transaction']>[0]>[0];\n\ntype AgentAccessExecutor = ReturnType<typeof db> | AgentAccessTx;\n\nconst MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;\nconst MILLISECONDS_PER_SECOND = 1000;\n\nfunction retentionCutoff(now: Date, days: number): Date {\n if (!Number.isFinite(days) || days < 0) {\n throw new Error('Agent-access retention must be a non-negative finite number of days');\n }\n return new Date(now.getTime() - days * MILLISECONDS_PER_DAY);\n}\n\nfunction batchLimit(limit: number | undefined): number {\n const value = limit ?? 1000;\n if (!Number.isInteger(value) || value < 1) {\n throw new Error('Agent-access batch limit must be a positive integer');\n }\n return value;\n}\n\nclass AgentAccessRetentionDeadlineExceededError extends Error {\n readonly code = '57014';\n\n constructor() {\n super('Agent-access retention deadline exceeded');\n this.name = 'AgentAccessRetentionDeadlineExceededError';\n }\n}\n\nfunction retentionStatementTimeoutMs(deadlineMs: number): number {\n if (!Number.isFinite(deadlineMs)) {\n throw new Error('Agent-access retention deadline must be a finite timestamp');\n }\n const remainingMs = Math.floor(\n deadlineMs - Date.now() - AGENT_ACCESS_RETENTION_TIMEOUT_MARGIN_MS,\n );\n if (remainingMs < 1) throw new AgentAccessRetentionDeadlineExceededError();\n return remainingMs;\n}\n\nasync function prepareAgentAccessRetentionStatement(\n tx: AgentAccessTx,\n deadlineMs: number | undefined,\n): Promise<void> {\n if (deadlineMs === undefined) return;\n const timeout = `${retentionStatementTimeoutMs(deadlineMs)}ms`;\n await tx.execute(\n sql`select set_config('statement_timeout', ${timeout}, true), set_config('lock_timeout', ${timeout}, true)`,\n );\n}\n\nasync function requireActiveAgentGrant(tx: AgentAccessTx, grantId: string): Promise<AgentGrant> {\n const grant = await lockAgentGrant(tx, {grantId});\n if (!grant) throw new Error(`Agent grant ${grantId} was not found`);\n if (grant.revokedAt || grant.terminalAt) {\n throw new Error(`Agent grant ${grantId} is no longer active`);\n }\n return grant;\n}\n\nasync function isActiveUser(tx: AgentAccessTx, userId: string): Promise<boolean> {\n const rows = await tx\n .select({id: users.id})\n .from(users)\n .where(and(eq(users.id, userId), eq(users.status, 'active')))\n .limit(1);\n return rows.length > 0;\n}\n\nasync function lockAgentClient(\n tx: AgentAccessTx,\n clientId: string,\n): Promise<AgentClient | undefined> {\n const rows = await tx\n .select()\n .from(agentClients)\n .where(eq(agentClients.id, clientId))\n .for('update')\n .limit(1);\n const row = rows[0];\n return row ? toAgentClient(row) : undefined;\n}\n\nfunction validateRotationGraceSeconds(graceSeconds: number): number {\n if (!Number.isFinite(graceSeconds) || graceSeconds < 0) {\n throw new Error('Agent refresh rotation grace must be a non-negative finite number of seconds');\n }\n return graceSeconds;\n}\n\n/** Returns the default sliding lifetime for a newly issued agent refresh token. */\nexport function agentRefreshTokenExpiresAt(now: Date = new Date()): Date {\n return new Date(now.getTime() + config.AUTH_REFRESH_TOKEN_EXPIRES_IN_DAYS * MILLISECONDS_PER_DAY);\n}\n\n/**\n * A rotated token remains usable for an access-token-only grace response. The\n * row must still exist; pruning deliberately turns later replays into plain\n * unknown-token responses.\n */\nexport function isWithinAgentRefreshRotationGrace(params: {\n rotatedAt: Date | null;\n now?: Date;\n graceSeconds?: number | undefined;\n}): boolean {\n if (!params.rotatedAt) return false;\n const now = params.now ?? new Date();\n const graceSeconds = validateRotationGraceSeconds(\n params.graceSeconds ?? config.AUTH_REFRESH_ROTATION_GRACE_SECONDS,\n );\n const elapsedMs = now.getTime() - params.rotatedAt.getTime();\n return elapsedMs >= 0 && elapsedMs <= graceSeconds * MILLISECONDS_PER_SECOND;\n}\n\nexport interface CreateAgentClientParams {\n clientId: string;\n name: string;\n redirectUris: string[];\n kind: 'registered' | 'cimd';\n}\n\nexport async function createAgentClient(params: CreateAgentClientParams): Promise<AgentClient> {\n return await db().transaction((tx) => createAgentClientTx(tx, params));\n}\n\nexport async function createAgentClientTx(\n tx: AgentAccessTx,\n params: CreateAgentClientParams,\n): Promise<AgentClient> {\n const rows = await tx\n .insert(agentClients)\n .values(params)\n .onConflictDoUpdate({\n target: agentClients.clientId,\n set: {\n lastSeenAt: sql`now()`,\n unreferencedAt: null,\n updatedAt: sql`now()`,\n },\n })\n .returning();\n const row = rows[0];\n if (!row) throw new Error('Upsert returned no rows');\n return toAgentClient(row);\n}\n\nexport interface UpsertCimdAgentClientParams {\n clientId: string;\n name: string;\n redirectUris: string[];\n}\n\n/**\n * Stores the latest validated CIMD identity. The generic client upsert above\n * intentionally preserves registration metadata; CIMD documents are the\n * source of truth and therefore use this explicit update path.\n */\nexport async function upsertCimdAgentClient(\n params: UpsertCimdAgentClientParams,\n): Promise<AgentClient> {\n return await db().transaction(async (tx) => {\n const rows = await tx\n .insert(agentClients)\n .values({...params, kind: 'cimd'})\n .onConflictDoUpdate({\n target: agentClients.clientId,\n set: {\n name: params.name,\n redirectUris: params.redirectUris,\n kind: 'cimd',\n lastSeenAt: sql`now()`,\n unreferencedAt: null,\n updatedAt: sql`now()`,\n },\n })\n .returning();\n const row = rows[0];\n if (!row) throw new Error('CIMD client upsert returned no row');\n return toAgentClient(row);\n });\n}\n\nexport async function findAgentClientByClientId(params: {\n clientId: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentClient | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentClients)\n .where(eq(agentClients.clientId, params.clientId))\n .limit(1);\n const row = rows[0];\n return row ? toAgentClient(row) : undefined;\n}\n\nexport async function markAgentClientReferenced(\n tx: AgentAccessTx,\n params: {clientUuid: string},\n): Promise<void> {\n await tx\n .update(agentClients)\n .set({unreferencedAt: null, lastSeenAt: sql`now()`, updatedAt: sql`now()`})\n .where(eq(agentClients.id, params.clientUuid));\n}\n\nexport async function markAgentClientUnreferenced(\n tx: AgentAccessTx,\n params: {clientUuid: string},\n): Promise<void> {\n await tx\n .update(agentClients)\n .set({unreferencedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentClients.id, params.clientUuid),\n notExists(\n tx\n .select({id: agentGrants.id})\n .from(agentGrants)\n .where(eq(agentGrants.clientId, params.clientUuid)),\n ),\n ),\n );\n}\n\nexport interface CreateAgentAuthorizationRequestParams {\n /** Internal `auth_agent_clients.id`, not the public OAuth `client_id`. */\n clientId: string;\n redirectUri: string;\n resource: string;\n scopes: string[];\n codeChallenge: string;\n state: string | null;\n expiresAt: Date;\n}\n\nexport async function createAgentAuthorizationRequest(\n params: CreateAgentAuthorizationRequestParams,\n): Promise<AgentAuthorizationRequest> {\n return await db().transaction((tx) => createAgentAuthorizationRequestTx(tx, params));\n}\n\nexport async function createAgentAuthorizationRequestTx(\n tx: AgentAccessTx,\n params: CreateAgentAuthorizationRequestParams,\n): Promise<AgentAuthorizationRequest> {\n if (!(await lockAgentClient(tx, params.clientId))) {\n throw new Error(`Agent client ${params.clientId} was not found`);\n }\n const rows = await tx.insert(agentAuthorizationRequests).values(params).returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentAuthorizationRequest(row);\n}\n\nexport async function findPendingAgentAuthorizationRequest(params: {\n id: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentAuthorizationRequest | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentAuthorizationRequests)\n .where(\n and(\n eq(agentAuthorizationRequests.id, params.id),\n isNull(agentAuthorizationRequests.consumedAt),\n gt(agentAuthorizationRequests.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentAuthorizationRequest(row) : undefined;\n}\n\nexport async function consumeAgentAuthorizationRequest(params: {\n id: string;\n}): Promise<AgentAuthorizationRequest | undefined> {\n return await db().transaction((tx) => consumeAgentAuthorizationRequestTx(tx, params));\n}\n\n/**\n * Claims a pending request in the caller's transaction. The expiry and\n * consumed-at predicates are part of the update so concurrent approval and\n * denial can have only one winner.\n */\nexport async function consumeAgentAuthorizationRequestTx(\n tx: AgentAccessTx,\n params: {id: string},\n): Promise<AgentAuthorizationRequest | undefined> {\n const rows = await tx\n .update(agentAuthorizationRequests)\n .set({consumedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentAuthorizationRequests.id, params.id),\n isNull(agentAuthorizationRequests.consumedAt),\n gt(agentAuthorizationRequests.expiresAt, sql`now()`),\n ),\n )\n .returning();\n const row = rows[0];\n return row ? toAgentAuthorizationRequest(row) : undefined;\n}\n\nexport interface CreateAgentGrantParams {\n userId: string;\n workspaceId: string;\n /** Internal `auth_agent_clients.id`, not the public OAuth `client_id`. */\n clientId: string;\n scopes: string[];\n}\n\nexport async function createAgentGrant(params: CreateAgentGrantParams): Promise<AgentGrant> {\n return await db().transaction((tx) => createAgentGrantTx(tx, params));\n}\n\n/**\n * Creates or reauthorizes a grant while holding its client row lock. A newly\n * created grant has no live child until its first authorization code or refresh\n * token is issued, so approval callers must compose that first child creation\n * with this Tx helper in one database transaction.\n */\nexport async function createAgentGrantTx(\n tx: AgentAccessTx,\n params: CreateAgentGrantParams,\n): Promise<AgentGrant> {\n if (!(await lockAgentClient(tx, params.clientId))) {\n throw new Error(`Agent client ${params.clientId} was not found`);\n }\n const rows = await tx\n .insert(agentGrants)\n .values(params)\n .onConflictDoUpdate({\n target: [agentGrants.userId, agentGrants.workspaceId, agentGrants.clientId],\n targetWhere: sql`${agentGrants.revokedAt} IS NULL AND ${agentGrants.terminalAt} IS NULL`,\n set: {\n scopes: params.scopes,\n updatedAt: sql`now()`,\n },\n })\n .returning();\n const row = rows[0];\n if (!row) throw new Error('Upsert returned no rows');\n\n // Refresh tokens derive their scopes from the grant. Reauthorization must\n // invalidate existing tokens before the grant's scopes can be widened.\n await tx\n .update(agentRefreshTokens)\n .set({revokedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentRefreshTokens.grantId, row.id),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n ),\n );\n\n await markAgentClientReferenced(tx, {clientUuid: params.clientId});\n return toAgentGrant(row);\n}\n\nexport async function findAgentGrant(params: {\n id: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentGrant | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentGrants)\n .where(eq(agentGrants.id, params.id))\n .limit(1);\n const row = rows[0];\n return row ? toAgentGrant(row) : undefined;\n}\n\n/**\n * Locks one grant row until the surrounding transaction ends. Code exchange\n * and lifecycle transitions must use this same primitive before inspecting or\n * changing grant state. Callers must keep the transaction database-only while\n * this lock is held; external I/O must happen after commit.\n */\nexport async function lockAgentGrant(\n tx: AgentAccessTx,\n params: {grantId: string},\n): Promise<AgentGrant | undefined> {\n const rows = await tx\n .select()\n .from(agentGrants)\n .where(eq(agentGrants.id, params.grantId))\n .for('update')\n .limit(1);\n const row = rows[0];\n return row ? toAgentGrant(row) : undefined;\n}\n\nexport interface CreateAgentAuthorizationCodeParams {\n grantId: string;\n hashedCode: string;\n codeChallenge: string;\n redirectUri: string;\n resource: string;\n expiresAt: Date;\n}\n\nexport async function createAgentAuthorizationCode(\n params: CreateAgentAuthorizationCodeParams,\n): Promise<AgentAuthorizationCode> {\n return await db().transaction((tx) => createAgentAuthorizationCodeTx(tx, params));\n}\n\nexport async function createAgentAuthorizationCodeTx(\n tx: AgentAccessTx,\n params: CreateAgentAuthorizationCodeParams,\n): Promise<AgentAuthorizationCode> {\n await requireActiveAgentGrant(tx, params.grantId);\n const rows = await tx.insert(agentAuthorizationCodes).values(params).returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentAuthorizationCode(row);\n}\n\nexport async function findAgentAuthorizationCodeByHash(params: {\n hashedCode: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentAuthorizationCode | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentAuthorizationCodes)\n .where(eq(agentAuthorizationCodes.hashedCode, params.hashedCode))\n .limit(1);\n const row = rows[0];\n return row ? toAgentAuthorizationCode(row) : undefined;\n}\n\nexport async function findActiveAgentAuthorizationCodeByHash(params: {\n hashedCode: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentAuthorizationCode | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentAuthorizationCodes)\n .where(\n and(\n eq(agentAuthorizationCodes.hashedCode, params.hashedCode),\n isNull(agentAuthorizationCodes.consumedAt),\n gt(agentAuthorizationCodes.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentAuthorizationCode(row) : undefined;\n}\n\nexport async function consumeAgentAuthorizationCode(params: {\n hashedCode: string;\n}): Promise<AgentAuthorizationCode | undefined> {\n return await db().transaction((tx) => consumeAgentAuthorizationCodeTx(tx, params));\n}\n\n/** Claims an authorization code exactly once, including its 60-second TTL. */\nexport async function consumeAgentAuthorizationCodeTx(\n tx: AgentAccessTx,\n params: {hashedCode: string},\n): Promise<AgentAuthorizationCode | undefined> {\n // Read the binding before taking the grant lock. The conditional update below\n // re-checks consumed_at and expiry after the lock, so concurrent exchanges\n // still have exactly one winner even when both read the code first.\n const existingRows = await tx\n .select()\n .from(agentAuthorizationCodes)\n .where(eq(agentAuthorizationCodes.hashedCode, params.hashedCode))\n .limit(1);\n const existing = existingRows[0];\n if (!existing) return undefined;\n\n const grant = await lockAgentGrant(tx, {grantId: existing.grantId});\n if (!grant || grant.revokedAt || grant.terminalAt) return undefined;\n if (!(await isActiveUser(tx, grant.userId))) return undefined;\n\n const rows = await tx\n .update(agentAuthorizationCodes)\n .set({consumedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentAuthorizationCodes.id, existing.id),\n eq(agentAuthorizationCodes.hashedCode, params.hashedCode),\n isNull(agentAuthorizationCodes.consumedAt),\n gt(agentAuthorizationCodes.expiresAt, sql`now()`),\n ),\n )\n .returning();\n const row = rows[0];\n return row ? toAgentAuthorizationCode(row) : undefined;\n}\n\nexport interface CreateAgentRefreshTokenParams {\n grantId: string;\n hashedToken: string;\n /** Defaults to the configured 14-day lifetime. */\n expiresAt?: Date;\n}\n\nexport async function createAgentRefreshToken(\n params: CreateAgentRefreshTokenParams,\n): Promise<AgentRefreshToken> {\n return await db().transaction((tx) => createAgentRefreshTokenTx(tx, params));\n}\n\nexport async function createAgentRefreshTokenTx(\n tx: AgentAccessTx,\n params: CreateAgentRefreshTokenParams,\n): Promise<AgentRefreshToken> {\n await requireActiveAgentGrant(tx, params.grantId);\n const rows = await tx\n .insert(agentRefreshTokens)\n .values({...params, expiresAt: params.expiresAt ?? agentRefreshTokenExpiresAt()})\n .returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentRefreshToken(row);\n}\n\nexport async function findAgentRefreshTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentRefreshToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.hashedToken, params.hashedToken),\n isNull(agentRefreshTokens.revokedAt),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentRefreshToken(row) : undefined;\n}\n\nexport async function findActiveAgentRefreshTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentRefreshToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.hashedToken, params.hashedToken),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentRefreshToken(row) : undefined;\n}\n\n/** Finds the one live refresh token currently attached to a grant. */\nexport async function findActiveAgentRefreshTokenByGrantId(params: {\n grantId: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentRefreshToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.grantId, params.grantId),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toAgentRefreshToken(row) : undefined;\n}\n\nexport type AgentRefreshTokenReplayResult =\n | {\n kind: 'grace';\n grant: AgentGrant;\n predecessor: AgentRefreshToken;\n successor: AgentRefreshToken;\n }\n | {\n kind: 'reused';\n grant: AgentGrant;\n predecessor: AgentRefreshToken;\n };\n\n/**\n * Resolves a replay of a retained, rotated token. A grace hit returns the one\n * live successor so the caller can mint an access token without issuing a new\n * refresh cookie. A replay after grace revokes the complete grant family.\n * Missing or pruned rows return undefined and therefore remain plain 401s.\n */\nexport async function resolveAgentRefreshTokenReplay(params: {\n hashedToken: string;\n now?: Date;\n graceSeconds?: number;\n}): Promise<AgentRefreshTokenReplayResult | undefined> {\n return await db().transaction((tx) => resolveAgentRefreshTokenReplayTx(tx, params));\n}\n\nexport async function resolveAgentRefreshTokenReplayTx(\n tx: AgentAccessTx,\n params: {\n hashedToken: string;\n now?: Date;\n graceSeconds?: number;\n },\n): Promise<AgentRefreshTokenReplayResult | undefined> {\n const rows = await tx\n .select()\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.hashedToken, params.hashedToken),\n isNull(agentRefreshTokens.revokedAt),\n ),\n )\n .limit(1);\n const existing = rows[0];\n if (!existing) return undefined;\n\n const grant = await lockAgentGrant(tx, {grantId: existing.grantId});\n if (!grant || grant.revokedAt || grant.terminalAt) return undefined;\n if (!(await isActiveUser(tx, grant.userId))) return undefined;\n\n const currentRows = await tx\n .select()\n .from(agentRefreshTokens)\n .where(and(eq(agentRefreshTokens.id, existing.id), isNull(agentRefreshTokens.revokedAt)))\n .limit(1);\n const current = currentRows[0];\n if (!current?.rotatedAt) return undefined;\n\n const now = params.now ?? new Date();\n if (\n isWithinAgentRefreshRotationGrace({\n rotatedAt: current.rotatedAt,\n now,\n graceSeconds: params.graceSeconds,\n })\n ) {\n const successorRows = await tx\n .select()\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.grantId, current.grantId),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, now),\n ),\n )\n .limit(1);\n const successor = successorRows[0];\n if (!successor) return undefined;\n return {\n kind: 'grace',\n grant,\n predecessor: toAgentRefreshToken(current),\n successor: toAgentRefreshToken(successor),\n };\n }\n\n const revokedGrant = await revokeAgentGrantTx(tx, {grantId: current.grantId});\n if (!revokedGrant) return undefined;\n return {\n kind: 'reused',\n grant: revokedGrant,\n predecessor: toAgentRefreshToken(current),\n };\n}\n\n/** Rotates a refresh token atomically; a concurrent rotation cannot win twice. */\nexport async function rotateAgentRefreshToken(params: {\n hashedToken: string;\n replacementHashedToken: string;\n /** Defaults to the configured 14-day sliding lifetime. */\n replacementExpiresAt?: Date;\n}): Promise<AgentRefreshToken | undefined> {\n return await db().transaction((tx) => rotateAgentRefreshTokenTx(tx, params));\n}\n\nexport async function rotateAgentRefreshTokenTx(\n tx: AgentAccessTx,\n params: {\n hashedToken: string;\n replacementHashedToken: string;\n replacementExpiresAt?: Date;\n },\n): Promise<AgentRefreshToken | undefined> {\n const replacementExpiresAt = params.replacementExpiresAt ?? agentRefreshTokenExpiresAt();\n const existingRows = await tx\n .select()\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.hashedToken, params.hashedToken),\n isNull(agentRefreshTokens.revokedAt),\n ),\n )\n .limit(1);\n const existing = existingRows[0];\n if (!existing) return undefined;\n\n const grant = await lockAgentGrant(tx, {grantId: existing.grantId});\n if (!grant || grant.revokedAt || grant.terminalAt) return undefined;\n if (!(await isActiveUser(tx, grant.userId))) return undefined;\n\n const rows = await tx\n .update(agentRefreshTokens)\n .set({rotatedAt: sql`now()`, lastUsedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentRefreshTokens.id, existing.id),\n eq(agentRefreshTokens.hashedToken, params.hashedToken),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, sql`now()`),\n ),\n )\n .returning();\n const row = rows[0];\n if (!row) return undefined;\n\n await tx\n .update(agentGrants)\n .set({lastUsedAt: sql`now()`, updatedAt: sql`now()`})\n .where(eq(agentGrants.id, row.grantId));\n\n const successorRows = await tx\n .insert(agentRefreshTokens)\n .values({\n grantId: row.grantId,\n hashedToken: params.replacementHashedToken,\n expiresAt: replacementExpiresAt,\n })\n .returning();\n const successor = successorRows[0];\n if (!successor) throw new Error('Insert returned no rows');\n return toAgentRefreshToken(successor);\n}\n\nexport async function revokeAgentRefreshToken(params: {\n id: string;\n}): Promise<AgentRefreshToken | undefined> {\n return await db().transaction(async (tx) => {\n const existingRows = await tx\n .select()\n .from(agentRefreshTokens)\n .where(eq(agentRefreshTokens.id, params.id))\n .limit(1);\n const existing = existingRows[0];\n if (!existing) return undefined;\n const grant = await lockAgentGrant(tx, {grantId: existing.grantId});\n if (!grant) return undefined;\n\n const rows = await tx\n .update(agentRefreshTokens)\n .set({revokedAt: sql`now()`, updatedAt: sql`now()`})\n .where(and(eq(agentRefreshTokens.id, params.id), isNull(agentRefreshTokens.revokedAt)))\n .returning();\n const row = rows[0];\n return row ? toAgentRefreshToken(row) : undefined;\n });\n}\n\n/** Revokes a grant and every refresh-token generation in its family. */\nexport async function revokeAgentGrant(params: {grantId: string}): Promise<AgentGrant | undefined> {\n return await db().transaction((tx) => revokeAgentGrantTx(tx, params));\n}\n\nexport async function revokeAgentGrantTx(\n tx: AgentAccessTx,\n params: {grantId: string},\n): Promise<AgentGrant | undefined> {\n const grant = await lockAgentGrant(tx, params);\n if (!grant) return undefined;\n\n const rows = await tx\n .update(agentGrants)\n .set({\n revokedAt: grant.revokedAt ?? sql`now()`,\n terminalAt: grant.terminalAt ?? sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(eq(agentGrants.id, grant.id))\n .returning();\n const updatedGrant = rows[0];\n if (!updatedGrant) return undefined;\n\n await tx\n .update(agentRefreshTokens)\n .set({revokedAt: sql`now()`, updatedAt: sql`now()`})\n .where(and(eq(agentRefreshTokens.grantId, grant.id), isNull(agentRefreshTokens.revokedAt)));\n\n return toAgentGrant(updatedGrant);\n}\n\nexport interface TransitionAgentGrantsToTerminalParams {\n limit?: number;\n now?: Date;\n deadlineMs?: number | undefined;\n}\n\n/**\n * Marks grants terminal once they have no usable refresh token or authorization\n * code left. Each candidate is locked before its children are inspected so a\n * concurrent code exchange or token rotation cannot create a live child after\n * the decision.\n */\nexport async function transitionAgentGrantsToTerminal(\n params: TransitionAgentGrantsToTerminalParams = {},\n): Promise<number> {\n return await db().transaction((tx) => transitionAgentGrantsToTerminalTx(tx, params));\n}\n\nexport async function transitionAgentGrantsToTerminalTx(\n tx: AgentAccessTx,\n params: TransitionAgentGrantsToTerminalParams = {},\n): Promise<number> {\n const limit = batchLimit(params.limit);\n const now = params.now ?? new Date();\n const liveRefreshTokens = tx\n .select({id: agentRefreshTokens.id})\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.grantId, agentGrants.id),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, now),\n ),\n );\n const liveAuthorizationCodes = tx\n .select({id: agentAuthorizationCodes.id})\n .from(agentAuthorizationCodes)\n .where(\n and(\n eq(agentAuthorizationCodes.grantId, agentGrants.id),\n isNull(agentAuthorizationCodes.consumedAt),\n gt(agentAuthorizationCodes.expiresAt, now),\n ),\n );\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const candidates = await tx\n .select({id: agentGrants.id})\n .from(agentGrants)\n .where(\n and(\n isNull(agentGrants.terminalAt),\n or(\n isNotNull(agentGrants.revokedAt),\n and(notExists(liveRefreshTokens), notExists(liveAuthorizationCodes)),\n ),\n ),\n )\n .orderBy(asc(agentGrants.createdAt), asc(agentGrants.id))\n .limit(limit);\n\n let transitioned = 0;\n for (const candidate of candidates) {\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const grant = await lockAgentGrant(tx, {grantId: candidate.id});\n if (!grant || grant.terminalAt) continue;\n\n if (!grant.revokedAt) {\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const liveRefreshTokens = await tx\n .select({id: agentRefreshTokens.id})\n .from(agentRefreshTokens)\n .where(\n and(\n eq(agentRefreshTokens.grantId, grant.id),\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n gt(agentRefreshTokens.expiresAt, now),\n ),\n )\n .limit(1);\n if (liveRefreshTokens.length > 0) continue;\n\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const liveAuthorizationCodes = await tx\n .select({id: agentAuthorizationCodes.id})\n .from(agentAuthorizationCodes)\n .where(\n and(\n eq(agentAuthorizationCodes.grantId, grant.id),\n isNull(agentAuthorizationCodes.consumedAt),\n gt(agentAuthorizationCodes.expiresAt, now),\n ),\n )\n .limit(1);\n if (liveAuthorizationCodes.length > 0) continue;\n }\n\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const rows = await tx\n .update(agentGrants)\n .set({terminalAt: now, updatedAt: now})\n .where(and(eq(agentGrants.id, grant.id), isNull(agentGrants.terminalAt)))\n .returning({id: agentGrants.id});\n if (rows.length > 0) transitioned += 1;\n }\n\n return transitioned;\n}\n\nexport interface CreateAgentPersonalAccessTokenParams {\n userId: string;\n workspaceId: string;\n hashedToken: string;\n prefix: string;\n name: string;\n scopes: string[];\n expiresAt: Date;\n}\n\nexport async function createAgentPersonalAccessToken(\n params: CreateAgentPersonalAccessTokenParams,\n): Promise<AgentPersonalAccessToken> {\n return await db().transaction((tx) => createAgentPersonalAccessTokenTx(tx, params));\n}\n\nexport async function createAgentPersonalAccessTokenTx(\n tx: AgentAccessTx,\n params: CreateAgentPersonalAccessTokenParams,\n): Promise<AgentPersonalAccessToken> {\n const rows = await tx.insert(agentPersonalAccessTokens).values(params).returning();\n const row = rows[0];\n if (!row) throw new Error('Insert returned no rows');\n return toAgentPersonalAccessToken(row);\n}\n\nexport async function findAgentPersonalAccessTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select()\n .from(agentPersonalAccessTokens)\n .where(eq(agentPersonalAccessTokens.hashedToken, params.hashedToken))\n .limit(1);\n const row = rows[0];\n return row ? toAgentPersonalAccessToken(row) : undefined;\n}\n\nexport async function findActiveAgentPersonalAccessTokenByHash(params: {\n hashedToken: string;\n executor?: AgentAccessExecutor;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const executor = params.executor ?? db();\n const rows = await executor\n .select({token: agentPersonalAccessTokens})\n .from(agentPersonalAccessTokens)\n .innerJoin(users, eq(agentPersonalAccessTokens.userId, users.id))\n .where(\n and(\n eq(agentPersonalAccessTokens.hashedToken, params.hashedToken),\n isNull(agentPersonalAccessTokens.revokedAt),\n gt(agentPersonalAccessTokens.expiresAt, sql`now()`),\n eq(users.status, 'active'),\n ),\n )\n .limit(1);\n const row = rows[0]?.token;\n return row ? toAgentPersonalAccessToken(row) : undefined;\n}\n\nexport async function markAgentPersonalAccessTokenUsed(params: {\n id: string;\n throttleSeconds?: number;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const throttleSeconds = params.throttleSeconds ?? 60;\n if (!Number.isFinite(throttleSeconds) || throttleSeconds < 0) {\n throw new Error('PAT last-used throttle must be a non-negative finite number of seconds');\n }\n\n const rows = await db()\n .update(agentPersonalAccessTokens)\n .set({lastUsedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(agentPersonalAccessTokens.id, params.id),\n isNull(agentPersonalAccessTokens.revokedAt),\n gt(agentPersonalAccessTokens.expiresAt, sql`now()`),\n or(\n isNull(agentPersonalAccessTokens.lastUsedAt),\n lte(\n agentPersonalAccessTokens.lastUsedAt,\n sql`now() - (${throttleSeconds} || ' seconds')::interval`,\n ),\n ),\n ),\n )\n .returning();\n const row = rows[0];\n if (row) return toAgentPersonalAccessToken(row);\n\n // A valid token can intentionally skip the write inside the throttle\n // window. Return its current row so callers can distinguish that from an\n // invalid, expired, or revoked token.\n const existingRows = await db()\n .select()\n .from(agentPersonalAccessTokens)\n .where(\n and(\n eq(agentPersonalAccessTokens.id, params.id),\n isNull(agentPersonalAccessTokens.revokedAt),\n gt(agentPersonalAccessTokens.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n const existing = existingRows[0];\n return existing ? toAgentPersonalAccessToken(existing) : undefined;\n}\n\nexport async function revokeAgentPersonalAccessToken(params: {\n id: string;\n}): Promise<AgentPersonalAccessToken | undefined> {\n const rows = await db()\n .update(agentPersonalAccessTokens)\n .set({revokedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(eq(agentPersonalAccessTokens.id, params.id), isNull(agentPersonalAccessTokens.revokedAt)),\n )\n .returning();\n const row = rows[0];\n return row ? toAgentPersonalAccessToken(row) : undefined;\n}\n\nexport interface PruneAgentAccessParams {\n /** Overrides every retention horizon for deterministic maintenance tests. */\n retentionDays?: number;\n limit?: number;\n now?: Date;\n /** Absolute epoch deadline used to bound every PostgreSQL statement. */\n deadlineMs?: number;\n}\n\nexport interface PruneAgentAccessResult {\n deleted: number;\n transitioned: number;\n}\n\ninterface AgentAccessRetentionCutoffs {\n authorization: Date;\n refreshToken: Date;\n grant: Date;\n pat: Date;\n client: Date;\n}\n\nasync function deleteExpiredAgentAuthorizationRequests(\n tx: AgentAccessTx,\n cutoff: Date,\n limit: number,\n deadlineMs: number | undefined,\n): Promise<number> {\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const candidates = await tx\n .select({id: agentAuthorizationRequests.id})\n .from(agentAuthorizationRequests)\n .where(lte(agentAuthorizationRequests.expiresAt, cutoff))\n .orderBy(asc(agentAuthorizationRequests.expiresAt), asc(agentAuthorizationRequests.id))\n .limit(limit);\n if (candidates.length === 0) return 0;\n\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const rows = await tx\n .delete(agentAuthorizationRequests)\n .where(\n inArray(\n agentAuthorizationRequests.id,\n candidates.map(({id}) => id),\n ),\n )\n .returning({id: agentAuthorizationRequests.id});\n return rows.length;\n}\n\nasync function deleteExpiredAgentAuthorizationCodes(\n tx: AgentAccessTx,\n cutoff: Date,\n limit: number,\n deadlineMs: number | undefined,\n): Promise<number> {\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const candidates = await tx\n .select({id: agentAuthorizationCodes.id})\n .from(agentAuthorizationCodes)\n .where(lte(agentAuthorizationCodes.expiresAt, cutoff))\n .orderBy(asc(agentAuthorizationCodes.expiresAt), asc(agentAuthorizationCodes.id))\n .limit(limit);\n if (candidates.length === 0) return 0;\n\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const rows = await tx\n .delete(agentAuthorizationCodes)\n .where(\n inArray(\n agentAuthorizationCodes.id,\n candidates.map(({id}) => id),\n ),\n )\n .returning({id: agentAuthorizationCodes.id});\n return rows.length;\n}\n\nasync function deleteRetainedAgentRefreshTokens(\n tx: AgentAccessTx,\n cutoff: Date,\n limit: number,\n deadlineMs: number | undefined,\n): Promise<number> {\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const candidates = await tx\n .select({id: agentRefreshTokens.id})\n .from(agentRefreshTokens)\n .where(\n or(\n lte(agentRefreshTokens.rotatedAt, cutoff),\n lte(agentRefreshTokens.revokedAt, cutoff),\n and(\n isNull(agentRefreshTokens.rotatedAt),\n isNull(agentRefreshTokens.revokedAt),\n lte(agentRefreshTokens.expiresAt, cutoff),\n ),\n ),\n )\n .orderBy(asc(agentRefreshTokens.expiresAt), asc(agentRefreshTokens.id))\n .limit(limit);\n if (candidates.length === 0) return 0;\n\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const rows = await tx\n .delete(agentRefreshTokens)\n .where(\n inArray(\n agentRefreshTokens.id,\n candidates.map(({id}) => id),\n ),\n )\n .returning({id: agentRefreshTokens.id});\n return rows.length;\n}\n\nasync function deleteRetainedAgentPersonalAccessTokens(\n tx: AgentAccessTx,\n cutoff: Date,\n limit: number,\n deadlineMs: number | undefined,\n): Promise<number> {\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const candidates = await tx\n .select({id: agentPersonalAccessTokens.id})\n .from(agentPersonalAccessTokens)\n .where(\n or(\n lte(agentPersonalAccessTokens.revokedAt, cutoff),\n and(\n isNull(agentPersonalAccessTokens.revokedAt),\n lte(agentPersonalAccessTokens.expiresAt, cutoff),\n ),\n ),\n )\n .orderBy(asc(agentPersonalAccessTokens.expiresAt), asc(agentPersonalAccessTokens.id))\n .limit(limit);\n if (candidates.length === 0) return 0;\n\n await prepareAgentAccessRetentionStatement(tx, deadlineMs);\n const rows = await tx\n .delete(agentPersonalAccessTokens)\n .where(\n inArray(\n agentPersonalAccessTokens.id,\n candidates.map(({id}) => id),\n ),\n )\n .returning({id: agentPersonalAccessTokens.id});\n return rows.length;\n}\n\nasync function pruneTerminalAgentGrants(\n tx: AgentAccessTx,\n params: {cutoff: Date; now: Date; limit: number; deadlineMs: number | undefined},\n): Promise<number> {\n const remainingCodes = tx\n .select({id: agentAuthorizationCodes.id})\n .from(agentAuthorizationCodes)\n .where(eq(agentAuthorizationCodes.grantId, agentGrants.id));\n const remainingRefreshTokens = tx\n .select({id: agentRefreshTokens.id})\n .from(agentRefreshTokens)\n .where(eq(agentRefreshTokens.grantId, agentGrants.id));\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const candidates = await tx\n .select({id: agentGrants.id, clientId: agentGrants.clientId})\n .from(agentGrants)\n .where(\n and(\n lte(agentGrants.terminalAt, params.cutoff),\n notExists(remainingCodes),\n notExists(remainingRefreshTokens),\n ),\n )\n .orderBy(asc(agentGrants.terminalAt), asc(agentGrants.id))\n .limit(params.limit)\n .for('update');\n if (candidates.length === 0) return 0;\n\n const grantIds = candidates.map(({id}) => id);\n // Child retention runs before this function. Do not delete a child merely\n // because its grant reached the 90-day horizon: a child can have been\n // revoked after the grant became terminal and still needs its own 30-day\n // replay/forensics window. Such a grant waits for the next sweep.\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const remainingCodeGrants = await tx\n .select({grantId: agentAuthorizationCodes.grantId})\n .from(agentAuthorizationCodes)\n .where(inArray(agentAuthorizationCodes.grantId, grantIds));\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const remainingRefreshTokenGrants = await tx\n .select({grantId: agentRefreshTokens.grantId})\n .from(agentRefreshTokens)\n .where(inArray(agentRefreshTokens.grantId, grantIds));\n const grantsWithChildren = new Set([\n ...remainingCodeGrants.map(({grantId}) => grantId),\n ...remainingRefreshTokenGrants.map(({grantId}) => grantId),\n ]);\n const deletableGrantIds = grantIds.filter((grantId) => !grantsWithChildren.has(grantId));\n if (deletableGrantIds.length === 0) return 0;\n\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const deletedGrants = await tx\n .delete(agentGrants)\n .where(inArray(agentGrants.id, deletableGrantIds))\n .returning({id: agentGrants.id, clientId: agentGrants.clientId});\n\n const clientIds = new Set(deletedGrants.map(({clientId}) => clientId));\n if (clientIds.size > 0) {\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n await tx\n .update(agentClients)\n .set({\n unreferencedAt: sql`coalesce(${agentClients.unreferencedAt}, ${params.now})`,\n updatedAt: params.now,\n })\n .where(\n and(\n inArray(agentClients.id, [...clientIds]),\n notExists(\n tx\n .select({id: agentGrants.id})\n .from(agentGrants)\n .where(eq(agentGrants.clientId, agentClients.id)),\n ),\n ),\n );\n }\n\n return deletedGrants.length;\n}\n\nasync function pruneUnreferencedAgentClients(\n tx: AgentAccessTx,\n params: {cutoff: Date; now: Date; limit: number; deadlineMs: number | undefined},\n): Promise<number> {\n const liveAuthorizationRequests = tx\n .select({id: agentAuthorizationRequests.id})\n .from(agentAuthorizationRequests)\n .where(\n and(\n eq(agentAuthorizationRequests.clientId, agentClients.id),\n isNull(agentAuthorizationRequests.consumedAt),\n gt(agentAuthorizationRequests.expiresAt, params.now),\n ),\n );\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const candidates = await tx\n .select({id: agentClients.id})\n .from(agentClients)\n .where(\n and(\n or(\n lte(agentClients.unreferencedAt, params.cutoff),\n and(\n isNull(agentClients.unreferencedAt),\n lte(agentClients.createdAt, params.cutoff),\n notExists(\n tx\n .select({id: agentGrants.id})\n .from(agentGrants)\n .where(eq(agentGrants.clientId, agentClients.id)),\n ),\n ),\n ),\n notExists(liveAuthorizationRequests),\n ),\n )\n .orderBy(asc(agentClients.unreferencedAt), asc(agentClients.createdAt), asc(agentClients.id))\n .limit(params.limit)\n .for('update');\n\n if (candidates.length === 0) return 0;\n\n const candidateIds = candidates.map(({id}) => id);\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const grantsForCandidates = await tx\n .select({clientId: agentGrants.clientId})\n .from(agentGrants)\n .where(inArray(agentGrants.clientId, candidateIds));\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const liveRequestsForCandidates = await tx\n .select({clientId: agentAuthorizationRequests.clientId})\n .from(agentAuthorizationRequests)\n .where(\n and(\n inArray(agentAuthorizationRequests.clientId, candidateIds),\n isNull(agentAuthorizationRequests.consumedAt),\n gt(agentAuthorizationRequests.expiresAt, params.now),\n ),\n );\n const protectedClientIds = new Set([\n ...grantsForCandidates.map(({clientId}) => clientId),\n ...liveRequestsForCandidates.map(({clientId}) => clientId),\n ]);\n const deletableClientIds = candidateIds.filter((id) => !protectedClientIds.has(id));\n if (deletableClientIds.length === 0) return 0;\n\n await prepareAgentAccessRetentionStatement(tx, params.deadlineMs);\n const rows = await tx\n .delete(agentClients)\n .where(\n and(\n inArray(agentClients.id, deletableClientIds),\n or(\n lte(agentClients.unreferencedAt, params.cutoff),\n and(isNull(agentClients.unreferencedAt), lte(agentClients.createdAt, params.cutoff)),\n ),\n notExists(\n tx\n .select({id: agentGrants.id})\n .from(agentGrants)\n .where(eq(agentGrants.clientId, agentClients.id)),\n ),\n notExists(\n tx\n .select({id: agentAuthorizationRequests.id})\n .from(agentAuthorizationRequests)\n .where(\n and(\n eq(agentAuthorizationRequests.clientId, agentClients.id),\n isNull(agentAuthorizationRequests.consumedAt),\n gt(agentAuthorizationRequests.expiresAt, params.now),\n ),\n ),\n ),\n ),\n )\n .returning({id: agentClients.id});\n return rows.length;\n}\n\n/**\n * Transitions inactive grants and deletes retained agent-access rows in bounded\n * batches. The caller can override the common horizon in tests; production uses\n * the per-row windows from the agent-access retention policy.\n */\nexport async function pruneAgentAccess(params: PruneAgentAccessParams = {}): Promise<number> {\n return (await pruneAgentAccessBatch(params)).deleted;\n}\n\n/** Runs one bounded retention transaction and reports terminal transitions separately. */\nexport async function pruneAgentAccessBatch(\n params: PruneAgentAccessParams = {},\n): Promise<PruneAgentAccessResult> {\n const now = params.now ?? new Date();\n const limit = batchLimit(params.limit);\n const retentionDays = params.retentionDays;\n const authorizationCutoff = retentionCutoff(\n now,\n retentionDays ?? AGENT_AUTHORIZATION_RETENTION_DAYS,\n );\n const refreshTokenCutoff = retentionCutoff(\n now,\n retentionDays ?? AGENT_REFRESH_TOKEN_RETENTION_DAYS,\n );\n const grantCutoff = retentionCutoff(now, retentionDays ?? AGENT_GRANT_RETENTION_DAYS);\n const patCutoff = retentionCutoff(now, retentionDays ?? AGENT_PAT_RETENTION_DAYS);\n const clientCutoff = retentionCutoff(now, retentionDays ?? AGENT_CLIENT_RETENTION_DAYS);\n const cutoffs: AgentAccessRetentionCutoffs = {\n authorization: authorizationCutoff,\n refreshToken: refreshTokenCutoff,\n grant: grantCutoff,\n pat: patCutoff,\n client: clientCutoff,\n };\n\n return await db().transaction(async (tx) => {\n // This runs first so grants whose last child expired can be terminalized in\n // the same maintenance tick. It takes the same grant row lock as code\n // exchange and refresh rotation.\n const transitioned = await transitionAgentGrantsToTerminalTx(tx, {\n limit,\n now,\n deadlineMs: params.deadlineMs,\n });\n const deleted =\n (await deleteExpiredAgentAuthorizationRequests(\n tx,\n cutoffs.authorization,\n limit,\n params.deadlineMs,\n )) +\n (await deleteExpiredAgentAuthorizationCodes(\n tx,\n cutoffs.authorization,\n limit,\n params.deadlineMs,\n )) +\n (await deleteRetainedAgentRefreshTokens(tx, cutoffs.refreshToken, limit, params.deadlineMs)) +\n (await deleteRetainedAgentPersonalAccessTokens(tx, cutoffs.pat, limit, params.deadlineMs)) +\n (await pruneTerminalAgentGrants(tx, {\n cutoff: cutoffs.grant,\n now,\n limit,\n deadlineMs: params.deadlineMs,\n })) +\n (await pruneUnreferencedAgentClients(tx, {\n cutoff: cutoffs.client,\n now,\n limit,\n deadlineMs: params.deadlineMs,\n }));\n return {deleted, transitioned};\n });\n}\n"],"names":["and","asc","eq","gt","inArray","isNotNull","isNull","lte","notExists","or","sql","config","AGENT_ACCESS_RETENTION_TIMEOUT_MARGIN_MS","AGENT_AUTHORIZATION_RETENTION_DAYS","AGENT_CLIENT_RETENTION_DAYS","AGENT_GRANT_RETENTION_DAYS","AGENT_PAT_RETENTION_DAYS","AGENT_REFRESH_TOKEN_RETENTION_DAYS","db","agentAuthorizationCodes","agentAuthorizationRequests","agentClients","agentGrants","agentPersonalAccessTokens","agentRefreshTokens","toAgentAuthorizationCode","toAgentAuthorizationRequest","toAgentClient","toAgentGrant","toAgentPersonalAccessToken","toAgentRefreshToken","users","MILLISECONDS_PER_DAY","MILLISECONDS_PER_SECOND","retentionCutoff","now","days","Number","isFinite","Error","Date","getTime","batchLimit","limit","value","isInteger","AgentAccessRetentionDeadlineExceededError","code","name","retentionStatementTimeoutMs","deadlineMs","remainingMs","Math","floor","prepareAgentAccessRetentionStatement","tx","undefined","timeout","execute","requireActiveAgentGrant","grantId","grant","lockAgentGrant","revokedAt","terminalAt","isActiveUser","userId","rows","select","id","from","where","status","length","lockAgentClient","clientId","for","row","validateRotationGraceSeconds","graceSeconds","agentRefreshTokenExpiresAt","AUTH_REFRESH_TOKEN_EXPIRES_IN_DAYS","isWithinAgentRefreshRotationGrace","params","rotatedAt","AUTH_REFRESH_ROTATION_GRACE_SECONDS","elapsedMs","createAgentClient","transaction","createAgentClientTx","insert","values","onConflictDoUpdate","target","set","lastSeenAt","unreferencedAt","updatedAt","returning","upsertCimdAgentClient","kind","redirectUris","findAgentClientByClientId","executor","markAgentClientReferenced","update","clientUuid","markAgentClientUnreferenced","createAgentAuthorizationRequest","createAgentAuthorizationRequestTx","findPendingAgentAuthorizationRequest","consumedAt","expiresAt","consumeAgentAuthorizationRequest","consumeAgentAuthorizationRequestTx","createAgentGrant","createAgentGrantTx","workspaceId","targetWhere","scopes","findAgentGrant","createAgentAuthorizationCode","createAgentAuthorizationCodeTx","findAgentAuthorizationCodeByHash","hashedCode","findActiveAgentAuthorizationCodeByHash","consumeAgentAuthorizationCode","consumeAgentAuthorizationCodeTx","existingRows","existing","createAgentRefreshToken","createAgentRefreshTokenTx","findAgentRefreshTokenByHash","hashedToken","findActiveAgentRefreshTokenByHash","findActiveAgentRefreshTokenByGrantId","resolveAgentRefreshTokenReplay","resolveAgentRefreshTokenReplayTx","currentRows","current","successorRows","successor","predecessor","revokedGrant","revokeAgentGrantTx","rotateAgentRefreshToken","rotateAgentRefreshTokenTx","replacementExpiresAt","lastUsedAt","replacementHashedToken","revokeAgentRefreshToken","revokeAgentGrant","updatedGrant","transitionAgentGrantsToTerminal","transitionAgentGrantsToTerminalTx","liveRefreshTokens","liveAuthorizationCodes","candidates","orderBy","createdAt","transitioned","candidate","createAgentPersonalAccessToken","createAgentPersonalAccessTokenTx","findAgentPersonalAccessTokenByHash","findActiveAgentPersonalAccessTokenByHash","token","innerJoin","markAgentPersonalAccessTokenUsed","throttleSeconds","revokeAgentPersonalAccessToken","deleteExpiredAgentAuthorizationRequests","cutoff","delete","map","deleteExpiredAgentAuthorizationCodes","deleteRetainedAgentRefreshTokens","deleteRetainedAgentPersonalAccessTokens","pruneTerminalAgentGrants","remainingCodes","remainingRefreshTokens","grantIds","remainingCodeGrants","remainingRefreshTokenGrants","grantsWithChildren","Set","deletableGrantIds","filter","has","deletedGrants","clientIds","size","pruneUnreferencedAgentClients","liveAuthorizationRequests","candidateIds","grantsForCandidates","liveRequestsForCandidates","protectedClientIds","deletableClientIds","pruneAgentAccess","pruneAgentAccessBatch","deleted","retentionDays","authorizationCutoff","refreshTokenCutoff","grantCutoff","patCutoff","clientCutoff","cutoffs","authorization","refreshToken","pat","client"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,12 +6,18 @@ export type { ListAdministratorUsersParams, ListAdministratorUsersResult, } from
|
|
|
6
6
|
export { bootstrapFirstAdminOwner, grantAdministratorRole, impersonateUser, listAdministratorUsers, reactivateAdministratorUser, revokeAdministratorGrant, revokeAdministratorUserSessions, suspendAdministratorUser, } from '#core/administration.js';
|
|
7
7
|
export type { CreateImpersonatedSessionTokenParams, CreateImpersonatedSessionTokenResult, CreateSessionForUserError, CreateSessionForUserParams, CreateSessionForUserResult, ProvisionUserParams, } from '#core/auth.js';
|
|
8
8
|
export { createImpersonatedSessionToken, createSessionForUser, provisionUser } from '#core/auth.js';
|
|
9
|
+
export type { CimdAddress, CimdAddressResolver, CimdHttpRequester, CimdHttpResponse, FetchCimdMetadataOptions, FetchedCimdMetadata, } from '#core/cimd.js';
|
|
10
|
+
export { fetchClientIdMetadata, isPublicUnicastAddress, OAUTH_CIMD_FETCH_TIMEOUT_MS, OAUTH_CIMD_MAX_BODY_BYTES, } from '#core/cimd.js';
|
|
9
11
|
export type { EmailOwner, FindUserByEmailParams } from '#core/email-owner.js';
|
|
10
12
|
export { findUserByEmail } from '#core/email-owner.js';
|
|
11
13
|
export type { AdminGrant } from '#core/entities/admin-grant.js';
|
|
12
14
|
export type { User, UserStatus } from '#core/entities/user.js';
|
|
13
|
-
export { AdminBootstrapClosedError, AdminGrantAlreadyExistsError, AdminGrantNotFoundError, AdminIdempotencyKeyReuseError, AdminRoleRequiredError, AuthDependencyUnavailableError, CannotImpersonateAdministratorError, CannotImpersonateSelfError, EmailNotVerifiedError, ImpersonationDisabledError, ImpersonationExpiredError, ImpersonationTargetNotActiveError, InvalidAdminBootstrapTokenError, InvalidAdministratorUserDirectoryFilterError, InvalidCredentialsError, LastAdminOwnerError, SignupNotAllowedError, UserNotFoundError, } from '#core/errors.js';
|
|
15
|
+
export { AdminBootstrapClosedError, AdminGrantAlreadyExistsError, AdminGrantNotFoundError, AdminIdempotencyKeyReuseError, AdminRoleRequiredError, AuthDependencyUnavailableError, CannotImpersonateAdministratorError, CannotImpersonateSelfError, EmailNotVerifiedError, ImpersonationDisabledError, ImpersonationExpiredError, ImpersonationTargetNotActiveError, InvalidAdminBootstrapTokenError, InvalidAdministratorUserDirectoryFilterError, InvalidCredentialsError, InvalidOAuthClientMetadataError, InvalidOAuthConfigurationError, LastAdminOwnerError, OAuthMetadataFetchError, OAuthRedirectUriNotRegisteredError, SignupNotAllowedError, UserNotFoundError, } from '#core/errors.js';
|
|
14
16
|
export { issueJobLeaseToken, jobLeaseParamsFrom, verifyJobLeaseToken, } from '#core/job-lease-token.js';
|
|
17
|
+
export type { OAuthGrantType, ValidatedOAuthClientMetadata } from '#core/oauth-client.js';
|
|
18
|
+
export { assertOAuthClientMetadataMatchesRequest, assertOAuthRedirectUriRegistered, isOAuthLoopbackRedirectUri, metadataForAgentClient, OAUTH_CIMD_CACHE_MAX_AGE_SECONDS, OAUTH_CLIENT_ID_MAX_BYTES, OAUTH_CLIENT_NAME_MAX_BYTES, OAUTH_REDIRECT_URI_MAX_BYTES, OAUTH_REDIRECT_URI_MAX_COUNT, oauthRedirectUriMatches, validateOAuthClientId, validateOAuthClientMetadataDocument, validateOAuthDynamicClientRegistration, validateOAuthPublicOrigin, validateOAuthRedirectUri, } from '#core/oauth-client.js';
|
|
19
|
+
export type { OAuthClientResolver, OAuthClientResolverOptions, RegisteredOAuthClient, RegisterOAuthClientParams, ResolvedOAuthClient, ResolveOAuthClientParams, } from '#core/oauth-client-resolver.js';
|
|
20
|
+
export { createOAuthClientResolver, OAUTH_CIMD_CACHE_MAX_ENTRIES, registerOAuthClient, resolveOAuthClient, } from '#core/oauth-client-resolver.js';
|
|
15
21
|
export type { SignupDenialMessageFormat, SignupPolicy } from '#core/ports.js';
|
|
16
22
|
export { issueRunnerSessionToken, verifyRunnerSessionToken, } from '#core/runner-session-token.js';
|
|
17
23
|
export { createEnvironmentSignupPolicy, DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE, } from '#core/signup-policy.js';
|
|
@@ -20,6 +26,8 @@ export { type AuthenticatedSessionContext, createJwtAuthMethod, getAuthenticated
|
|
|
20
26
|
export { createLeaseTokenAuthMethod } from '#presentation/auth/lease-token-auth.js';
|
|
21
27
|
export { authCookiePlugin, clearRefreshTokenCookie, getRefreshTokenCookie, setRefreshTokenCookie, } from '#presentation/auth/refresh-cookie.js';
|
|
22
28
|
export { createRunnerSessionAuthMethod } from '#presentation/auth/runner-session-auth.js';
|
|
29
|
+
export type { CreateOAuthRoutesOptions } from '#presentation/routes/oauth.js';
|
|
30
|
+
export { createOAuthClientIdentificationRoutes, createOAuthMetadataRoutes, createOAuthRoutes, } from '#presentation/routes/oauth.js';
|
|
23
31
|
export interface CreateAuthModuleOptions {
|
|
24
32
|
workspaces: import('@shipfox/api-workspaces-dto/inter-module').WorkspacesInterModuleClient;
|
|
25
33
|
signupPolicy?: SignupPolicy;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
1
3
|
import { AUTH_PASSWORD_RESET_SEND_REQUESTED, authEventSchemas } from '@shipfox/api-auth-dto';
|
|
2
4
|
import { administrationActionEventSchemas } from '@shipfox/api-common-dto';
|
|
3
5
|
import { subscriberFactory } from '@shipfox/node-module';
|
|
@@ -14,23 +16,31 @@ import { createAuthInterModulePresentation } from '#presentation/inter-module.js
|
|
|
14
16
|
import { administrationBootstrapRoutes, administrationRoutes, createAdministrationUserRoutes } from '#presentation/routes/administration.js';
|
|
15
17
|
import { buildAuthRoutes } from '#presentation/routes/index.js';
|
|
16
18
|
import { onPasswordResetSendRequested } from '#presentation/subscribers/index.js';
|
|
19
|
+
import { createAuthMaintenanceActivities } from '#temporal/activities/index.js';
|
|
20
|
+
import { AUTH_AGENT_ACCESS_MAINTENANCE_TASK_QUEUE } from '#temporal/constants.js';
|
|
17
21
|
import { passwordLoginMethods } from './login-methods.js';
|
|
18
22
|
const authPublisherEventSchemas = {
|
|
19
23
|
...authEventSchemas,
|
|
20
24
|
...administrationActionEventSchemas
|
|
21
25
|
};
|
|
26
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
27
|
+
const workflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');
|
|
22
28
|
export { ADMIN_ROLES, getCurrentAdminRole, hasMinimumAdminRole, highestAdminRole, requireAdminRole, revokeAdminGrant } from '#core/admin-role.js';
|
|
23
29
|
export { bootstrapFirstAdminOwner, grantAdministratorRole, impersonateUser, listAdministratorUsers, reactivateAdministratorUser, revokeAdministratorGrant, revokeAdministratorUserSessions, suspendAdministratorUser } from '#core/administration.js';
|
|
24
30
|
export { createImpersonatedSessionToken, createSessionForUser, provisionUser } from '#core/auth.js';
|
|
31
|
+
export { fetchClientIdMetadata, isPublicUnicastAddress, OAUTH_CIMD_FETCH_TIMEOUT_MS, OAUTH_CIMD_MAX_BODY_BYTES } from '#core/cimd.js';
|
|
25
32
|
export { findUserByEmail } from '#core/email-owner.js';
|
|
26
|
-
export { AdminBootstrapClosedError, AdminGrantAlreadyExistsError, AdminGrantNotFoundError, AdminIdempotencyKeyReuseError, AdminRoleRequiredError, AuthDependencyUnavailableError, CannotImpersonateAdministratorError, CannotImpersonateSelfError, EmailNotVerifiedError, ImpersonationDisabledError, ImpersonationExpiredError, ImpersonationTargetNotActiveError, InvalidAdminBootstrapTokenError, InvalidAdministratorUserDirectoryFilterError, InvalidCredentialsError, LastAdminOwnerError, SignupNotAllowedError, UserNotFoundError } from '#core/errors.js';
|
|
33
|
+
export { AdminBootstrapClosedError, AdminGrantAlreadyExistsError, AdminGrantNotFoundError, AdminIdempotencyKeyReuseError, AdminRoleRequiredError, AuthDependencyUnavailableError, CannotImpersonateAdministratorError, CannotImpersonateSelfError, EmailNotVerifiedError, ImpersonationDisabledError, ImpersonationExpiredError, ImpersonationTargetNotActiveError, InvalidAdminBootstrapTokenError, InvalidAdministratorUserDirectoryFilterError, InvalidCredentialsError, InvalidOAuthClientMetadataError, InvalidOAuthConfigurationError, LastAdminOwnerError, OAuthMetadataFetchError, OAuthRedirectUriNotRegisteredError, SignupNotAllowedError, UserNotFoundError } from '#core/errors.js';
|
|
27
34
|
export { issueJobLeaseToken, jobLeaseParamsFrom, verifyJobLeaseToken } from '#core/job-lease-token.js';
|
|
35
|
+
export { assertOAuthClientMetadataMatchesRequest, assertOAuthRedirectUriRegistered, isOAuthLoopbackRedirectUri, metadataForAgentClient, OAUTH_CIMD_CACHE_MAX_AGE_SECONDS, OAUTH_CLIENT_ID_MAX_BYTES, OAUTH_CLIENT_NAME_MAX_BYTES, OAUTH_REDIRECT_URI_MAX_BYTES, OAUTH_REDIRECT_URI_MAX_COUNT, oauthRedirectUriMatches, validateOAuthClientId, validateOAuthClientMetadataDocument, validateOAuthDynamicClientRegistration, validateOAuthPublicOrigin, validateOAuthRedirectUri } from '#core/oauth-client.js';
|
|
36
|
+
export { createOAuthClientResolver, OAUTH_CIMD_CACHE_MAX_ENTRIES, registerOAuthClient, resolveOAuthClient } from '#core/oauth-client-resolver.js';
|
|
28
37
|
export { issueRunnerSessionToken, verifyRunnerSessionToken } from '#core/runner-session-token.js';
|
|
29
38
|
export { createEnvironmentSignupPolicy, DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE } from '#core/signup-policy.js';
|
|
30
39
|
export { createJwtAuthMethod, getAuthenticatedSessionContext } from '#presentation/auth/jwt-auth.js';
|
|
31
40
|
export { createLeaseTokenAuthMethod } from '#presentation/auth/lease-token-auth.js';
|
|
32
41
|
export { authCookiePlugin, clearRefreshTokenCookie, getRefreshTokenCookie, setRefreshTokenCookie } from '#presentation/auth/refresh-cookie.js';
|
|
33
42
|
export { createRunnerSessionAuthMethod } from '#presentation/auth/runner-session-auth.js';
|
|
43
|
+
export { createOAuthClientIdentificationRoutes, createOAuthMetadataRoutes, createOAuthRoutes } from '#presentation/routes/oauth.js';
|
|
34
44
|
const subscriber = subscriberFactory();
|
|
35
45
|
export function createAuthModule({ workspaces, signupPolicy = createEnvironmentSignupPolicy() }) {
|
|
36
46
|
return {
|
|
@@ -66,6 +76,20 @@ export function createAuthModule({ workspaces, signupPolicy = createEnvironmentS
|
|
|
66
76
|
subscribers: [
|
|
67
77
|
subscriber(AUTH_PASSWORD_RESET_SEND_REQUESTED, onPasswordResetSendRequested)
|
|
68
78
|
],
|
|
79
|
+
workers: [
|
|
80
|
+
{
|
|
81
|
+
taskQueue: AUTH_AGENT_ACCESS_MAINTENANCE_TASK_QUEUE,
|
|
82
|
+
workflowsPath,
|
|
83
|
+
activities: createAuthMaintenanceActivities,
|
|
84
|
+
workflows: [
|
|
85
|
+
{
|
|
86
|
+
name: 'agentAccessRetentionCron',
|
|
87
|
+
id: 'auth-agent-access-retention',
|
|
88
|
+
cronSchedule: '10 * * * *'
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
],
|
|
69
93
|
interModulePresentations: [
|
|
70
94
|
createAuthInterModulePresentation()
|
|
71
95
|
]
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n AUTH_PASSWORD_RESET_SEND_REQUESTED,\n type AuthEventMap,\n authEventSchemas,\n} from '@shipfox/api-auth-dto';\nimport {administrationActionEventSchemas} from '@shipfox/api-common-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {subscriberFactory} from '@shipfox/node-module';\nimport {config} from '#config.js';\nimport type {SignupPolicy} from '#core/ports.js';\nimport {createEnvironmentSignupPolicy} from '#core/signup-policy.js';\nimport {db} from '#db/db.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {authOutbox} from '#db/schema/outbox.js';\nimport {createJwtAuthMethod} from '#presentation/auth/jwt-auth.js';\nimport {createLeaseTokenAuthMethod} from '#presentation/auth/lease-token-auth.js';\nimport {createRunnerSessionAuthMethod} from '#presentation/auth/runner-session-auth.js';\nimport {createAuthE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createAuthInterModulePresentation} from '#presentation/inter-module.js';\nimport {\n administrationBootstrapRoutes,\n administrationRoutes,\n createAdministrationUserRoutes,\n} from '#presentation/routes/administration.js';\nimport {buildAuthRoutes} from '#presentation/routes/index.js';\nimport {onPasswordResetSendRequested} from '#presentation/subscribers/index.js';\nimport {passwordLoginMethods} from './login-methods.js';\n\nconst authPublisherEventSchemas = {...authEventSchemas, ...administrationActionEventSchemas};\n\nexport type {AdminRole, JobLeaseTokenClaims, RunnerSessionTokenClaims} from '@shipfox/api-auth-dto';\nexport {\n ADMIN_ROLES,\n getCurrentAdminRole,\n hasMinimumAdminRole,\n highestAdminRole,\n requireAdminRole,\n revokeAdminGrant,\n} from '#core/admin-role.js';\nexport type {\n ListAdministratorUsersParams,\n ListAdministratorUsersResult,\n} from '#core/administration.js';\nexport {\n bootstrapFirstAdminOwner,\n grantAdministratorRole,\n impersonateUser,\n listAdministratorUsers,\n reactivateAdministratorUser,\n revokeAdministratorGrant,\n revokeAdministratorUserSessions,\n suspendAdministratorUser,\n} from '#core/administration.js';\nexport type {\n CreateImpersonatedSessionTokenParams,\n CreateImpersonatedSessionTokenResult,\n CreateSessionForUserError,\n CreateSessionForUserParams,\n CreateSessionForUserResult,\n ProvisionUserParams,\n} from '#core/auth.js';\nexport {createImpersonatedSessionToken, createSessionForUser, provisionUser} from '#core/auth.js';\nexport type {EmailOwner, FindUserByEmailParams} from '#core/email-owner.js';\nexport {findUserByEmail} from '#core/email-owner.js';\nexport type {AdminGrant} from '#core/entities/admin-grant.js';\nexport type {User, UserStatus} from '#core/entities/user.js';\nexport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n AdminRoleRequiredError,\n AuthDependencyUnavailableError,\n CannotImpersonateAdministratorError,\n CannotImpersonateSelfError,\n EmailNotVerifiedError,\n ImpersonationDisabledError,\n ImpersonationExpiredError,\n ImpersonationTargetNotActiveError,\n InvalidAdminBootstrapTokenError,\n InvalidAdministratorUserDirectoryFilterError,\n InvalidCredentialsError,\n LastAdminOwnerError,\n SignupNotAllowedError,\n UserNotFoundError,\n} from '#core/errors.js';\nexport {\n issueJobLeaseToken,\n jobLeaseParamsFrom,\n verifyJobLeaseToken,\n} from '#core/job-lease-token.js';\nexport type {SignupDenialMessageFormat, SignupPolicy} from '#core/ports.js';\nexport {\n issueRunnerSessionToken,\n verifyRunnerSessionToken,\n} from '#core/runner-session-token.js';\nexport {\n createEnvironmentSignupPolicy,\n DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE,\n} from '#core/signup-policy.js';\nexport type {ImpersonationResult} from '#db/impersonation.js';\nexport {\n type AuthenticatedSessionContext,\n createJwtAuthMethod,\n getAuthenticatedSessionContext,\n type RefreshSessionId,\n type UserId,\n} from '#presentation/auth/jwt-auth.js';\nexport {createLeaseTokenAuthMethod} from '#presentation/auth/lease-token-auth.js';\nexport {\n authCookiePlugin,\n clearRefreshTokenCookie,\n getRefreshTokenCookie,\n setRefreshTokenCookie,\n} from '#presentation/auth/refresh-cookie.js';\nexport {createRunnerSessionAuthMethod} from '#presentation/auth/runner-session-auth.js';\n\nconst subscriber = subscriberFactory<AuthEventMap>();\n\nexport interface CreateAuthModuleOptions {\n workspaces: import('@shipfox/api-workspaces-dto/inter-module').WorkspacesInterModuleClient;\n signupPolicy?: SignupPolicy;\n}\n\nexport function createAuthModule({\n workspaces,\n signupPolicy = createEnvironmentSignupPolicy(),\n}: CreateAuthModuleOptions): ShipfoxModule {\n return {\n name: 'auth',\n database: {db, migrationsPath, databaseNamespace: 'auth'},\n auth: [createJwtAuthMethod(), createLeaseTokenAuthMethod(), createRunnerSessionAuthMethod()],\n loginMethods: passwordLoginMethods(config.AUTH_PASSWORD_ENABLED),\n routes: [\n buildAuthRoutes(config.AUTH_PASSWORD_ENABLED, workspaces, signupPolicy),\n administrationBootstrapRoutes,\n administrationRoutes,\n ...createAdministrationUserRoutes(workspaces),\n ],\n e2eRoutes: [createAuthE2eRoutes(workspaces)],\n publishers: [{name: 'auth', table: authOutbox, db, eventSchemas: authPublisherEventSchemas}],\n subscribers: [subscriber(AUTH_PASSWORD_RESET_SEND_REQUESTED, onPasswordResetSendRequested)],\n interModulePresentations: [createAuthInterModulePresentation()],\n };\n}\n"],"names":["AUTH_PASSWORD_RESET_SEND_REQUESTED","authEventSchemas","administrationActionEventSchemas","subscriberFactory","config","createEnvironmentSignupPolicy","db","migrationsPath","authOutbox","createJwtAuthMethod","createLeaseTokenAuthMethod","createRunnerSessionAuthMethod","createAuthE2eRoutes","createAuthInterModulePresentation","administrationBootstrapRoutes","administrationRoutes","createAdministrationUserRoutes","buildAuthRoutes","onPasswordResetSendRequested","passwordLoginMethods","authPublisherEventSchemas","ADMIN_ROLES","getCurrentAdminRole","hasMinimumAdminRole","highestAdminRole","requireAdminRole","revokeAdminGrant","bootstrapFirstAdminOwner","grantAdministratorRole","impersonateUser","listAdministratorUsers","reactivateAdministratorUser","revokeAdministratorGrant","revokeAdministratorUserSessions","suspendAdministratorUser","createImpersonatedSessionToken","createSessionForUser","provisionUser","findUserByEmail","AdminBootstrapClosedError","AdminGrantAlreadyExistsError","AdminGrantNotFoundError","AdminIdempotencyKeyReuseError","AdminRoleRequiredError","AuthDependencyUnavailableError","CannotImpersonateAdministratorError","CannotImpersonateSelfError","EmailNotVerifiedError","ImpersonationDisabledError","ImpersonationExpiredError","ImpersonationTargetNotActiveError","InvalidAdminBootstrapTokenError","InvalidAdministratorUserDirectoryFilterError","InvalidCredentialsError","LastAdminOwnerError","SignupNotAllowedError","UserNotFoundError","issueJobLeaseToken","jobLeaseParamsFrom","verifyJobLeaseToken","issueRunnerSessionToken","verifyRunnerSessionToken","DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE","getAuthenticatedSessionContext","authCookiePlugin","clearRefreshTokenCookie","getRefreshTokenCookie","setRefreshTokenCookie","subscriber","createAuthModule","workspaces","signupPolicy","name","database","databaseNamespace","auth","loginMethods","AUTH_PASSWORD_ENABLED","routes","e2eRoutes","publishers","table","eventSchemas","subscribers","interModulePresentations"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {\n AUTH_PASSWORD_RESET_SEND_REQUESTED,\n type AuthEventMap,\n authEventSchemas,\n} from '@shipfox/api-auth-dto';\nimport {administrationActionEventSchemas} from '@shipfox/api-common-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {subscriberFactory} from '@shipfox/node-module';\nimport {config} from '#config.js';\nimport type {SignupPolicy} from '#core/ports.js';\nimport {createEnvironmentSignupPolicy} from '#core/signup-policy.js';\nimport {db} from '#db/db.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {authOutbox} from '#db/schema/outbox.js';\nimport {createJwtAuthMethod} from '#presentation/auth/jwt-auth.js';\nimport {createLeaseTokenAuthMethod} from '#presentation/auth/lease-token-auth.js';\nimport {createRunnerSessionAuthMethod} from '#presentation/auth/runner-session-auth.js';\nimport {createAuthE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createAuthInterModulePresentation} from '#presentation/inter-module.js';\nimport {\n administrationBootstrapRoutes,\n administrationRoutes,\n createAdministrationUserRoutes,\n} from '#presentation/routes/administration.js';\nimport {buildAuthRoutes} from '#presentation/routes/index.js';\nimport {onPasswordResetSendRequested} from '#presentation/subscribers/index.js';\nimport {createAuthMaintenanceActivities} from '#temporal/activities/index.js';\nimport {AUTH_AGENT_ACCESS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';\nimport {passwordLoginMethods} from './login-methods.js';\n\nconst authPublisherEventSchemas = {...authEventSchemas, ...administrationActionEventSchemas};\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst workflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nexport type {AdminRole, JobLeaseTokenClaims, RunnerSessionTokenClaims} from '@shipfox/api-auth-dto';\nexport {\n ADMIN_ROLES,\n getCurrentAdminRole,\n hasMinimumAdminRole,\n highestAdminRole,\n requireAdminRole,\n revokeAdminGrant,\n} from '#core/admin-role.js';\nexport type {\n ListAdministratorUsersParams,\n ListAdministratorUsersResult,\n} from '#core/administration.js';\nexport {\n bootstrapFirstAdminOwner,\n grantAdministratorRole,\n impersonateUser,\n listAdministratorUsers,\n reactivateAdministratorUser,\n revokeAdministratorGrant,\n revokeAdministratorUserSessions,\n suspendAdministratorUser,\n} from '#core/administration.js';\nexport type {\n CreateImpersonatedSessionTokenParams,\n CreateImpersonatedSessionTokenResult,\n CreateSessionForUserError,\n CreateSessionForUserParams,\n CreateSessionForUserResult,\n ProvisionUserParams,\n} from '#core/auth.js';\nexport {createImpersonatedSessionToken, createSessionForUser, provisionUser} from '#core/auth.js';\nexport type {\n CimdAddress,\n CimdAddressResolver,\n CimdHttpRequester,\n CimdHttpResponse,\n FetchCimdMetadataOptions,\n FetchedCimdMetadata,\n} from '#core/cimd.js';\nexport {\n fetchClientIdMetadata,\n isPublicUnicastAddress,\n OAUTH_CIMD_FETCH_TIMEOUT_MS,\n OAUTH_CIMD_MAX_BODY_BYTES,\n} from '#core/cimd.js';\nexport type {EmailOwner, FindUserByEmailParams} from '#core/email-owner.js';\nexport {findUserByEmail} from '#core/email-owner.js';\nexport type {AdminGrant} from '#core/entities/admin-grant.js';\nexport type {User, UserStatus} from '#core/entities/user.js';\nexport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n AdminRoleRequiredError,\n AuthDependencyUnavailableError,\n CannotImpersonateAdministratorError,\n CannotImpersonateSelfError,\n EmailNotVerifiedError,\n ImpersonationDisabledError,\n ImpersonationExpiredError,\n ImpersonationTargetNotActiveError,\n InvalidAdminBootstrapTokenError,\n InvalidAdministratorUserDirectoryFilterError,\n InvalidCredentialsError,\n InvalidOAuthClientMetadataError,\n InvalidOAuthConfigurationError,\n LastAdminOwnerError,\n OAuthMetadataFetchError,\n OAuthRedirectUriNotRegisteredError,\n SignupNotAllowedError,\n UserNotFoundError,\n} from '#core/errors.js';\nexport {\n issueJobLeaseToken,\n jobLeaseParamsFrom,\n verifyJobLeaseToken,\n} from '#core/job-lease-token.js';\nexport type {OAuthGrantType, ValidatedOAuthClientMetadata} from '#core/oauth-client.js';\nexport {\n assertOAuthClientMetadataMatchesRequest,\n assertOAuthRedirectUriRegistered,\n isOAuthLoopbackRedirectUri,\n metadataForAgentClient,\n OAUTH_CIMD_CACHE_MAX_AGE_SECONDS,\n OAUTH_CLIENT_ID_MAX_BYTES,\n OAUTH_CLIENT_NAME_MAX_BYTES,\n OAUTH_REDIRECT_URI_MAX_BYTES,\n OAUTH_REDIRECT_URI_MAX_COUNT,\n oauthRedirectUriMatches,\n validateOAuthClientId,\n validateOAuthClientMetadataDocument,\n validateOAuthDynamicClientRegistration,\n validateOAuthPublicOrigin,\n validateOAuthRedirectUri,\n} from '#core/oauth-client.js';\nexport type {\n OAuthClientResolver,\n OAuthClientResolverOptions,\n RegisteredOAuthClient,\n RegisterOAuthClientParams,\n ResolvedOAuthClient,\n ResolveOAuthClientParams,\n} from '#core/oauth-client-resolver.js';\nexport {\n createOAuthClientResolver,\n OAUTH_CIMD_CACHE_MAX_ENTRIES,\n registerOAuthClient,\n resolveOAuthClient,\n} from '#core/oauth-client-resolver.js';\nexport type {SignupDenialMessageFormat, SignupPolicy} from '#core/ports.js';\nexport {\n issueRunnerSessionToken,\n verifyRunnerSessionToken,\n} from '#core/runner-session-token.js';\nexport {\n createEnvironmentSignupPolicy,\n DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE,\n} from '#core/signup-policy.js';\nexport type {ImpersonationResult} from '#db/impersonation.js';\nexport {\n type AuthenticatedSessionContext,\n createJwtAuthMethod,\n getAuthenticatedSessionContext,\n type RefreshSessionId,\n type UserId,\n} from '#presentation/auth/jwt-auth.js';\nexport {createLeaseTokenAuthMethod} from '#presentation/auth/lease-token-auth.js';\nexport {\n authCookiePlugin,\n clearRefreshTokenCookie,\n getRefreshTokenCookie,\n setRefreshTokenCookie,\n} from '#presentation/auth/refresh-cookie.js';\nexport {createRunnerSessionAuthMethod} from '#presentation/auth/runner-session-auth.js';\nexport type {CreateOAuthRoutesOptions} from '#presentation/routes/oauth.js';\nexport {\n createOAuthClientIdentificationRoutes,\n createOAuthMetadataRoutes,\n createOAuthRoutes,\n} from '#presentation/routes/oauth.js';\n\nconst subscriber = subscriberFactory<AuthEventMap>();\n\nexport interface CreateAuthModuleOptions {\n workspaces: import('@shipfox/api-workspaces-dto/inter-module').WorkspacesInterModuleClient;\n signupPolicy?: SignupPolicy;\n}\n\nexport function createAuthModule({\n workspaces,\n signupPolicy = createEnvironmentSignupPolicy(),\n}: CreateAuthModuleOptions): ShipfoxModule {\n return {\n name: 'auth',\n database: {db, migrationsPath, databaseNamespace: 'auth'},\n auth: [createJwtAuthMethod(), createLeaseTokenAuthMethod(), createRunnerSessionAuthMethod()],\n loginMethods: passwordLoginMethods(config.AUTH_PASSWORD_ENABLED),\n routes: [\n buildAuthRoutes(config.AUTH_PASSWORD_ENABLED, workspaces, signupPolicy),\n administrationBootstrapRoutes,\n administrationRoutes,\n ...createAdministrationUserRoutes(workspaces),\n ],\n e2eRoutes: [createAuthE2eRoutes(workspaces)],\n publishers: [{name: 'auth', table: authOutbox, db, eventSchemas: authPublisherEventSchemas}],\n subscribers: [subscriber(AUTH_PASSWORD_RESET_SEND_REQUESTED, onPasswordResetSendRequested)],\n workers: [\n {\n taskQueue: AUTH_AGENT_ACCESS_MAINTENANCE_TASK_QUEUE,\n workflowsPath,\n activities: createAuthMaintenanceActivities,\n workflows: [\n {\n name: 'agentAccessRetentionCron',\n id: 'auth-agent-access-retention',\n cronSchedule: '10 * * * *',\n },\n ],\n },\n ],\n interModulePresentations: [createAuthInterModulePresentation()],\n };\n}\n"],"names":["dirname","resolve","fileURLToPath","AUTH_PASSWORD_RESET_SEND_REQUESTED","authEventSchemas","administrationActionEventSchemas","subscriberFactory","config","createEnvironmentSignupPolicy","db","migrationsPath","authOutbox","createJwtAuthMethod","createLeaseTokenAuthMethod","createRunnerSessionAuthMethod","createAuthE2eRoutes","createAuthInterModulePresentation","administrationBootstrapRoutes","administrationRoutes","createAdministrationUserRoutes","buildAuthRoutes","onPasswordResetSendRequested","createAuthMaintenanceActivities","AUTH_AGENT_ACCESS_MAINTENANCE_TASK_QUEUE","passwordLoginMethods","authPublisherEventSchemas","packageRoot","url","workflowsPath","ADMIN_ROLES","getCurrentAdminRole","hasMinimumAdminRole","highestAdminRole","requireAdminRole","revokeAdminGrant","bootstrapFirstAdminOwner","grantAdministratorRole","impersonateUser","listAdministratorUsers","reactivateAdministratorUser","revokeAdministratorGrant","revokeAdministratorUserSessions","suspendAdministratorUser","createImpersonatedSessionToken","createSessionForUser","provisionUser","fetchClientIdMetadata","isPublicUnicastAddress","OAUTH_CIMD_FETCH_TIMEOUT_MS","OAUTH_CIMD_MAX_BODY_BYTES","findUserByEmail","AdminBootstrapClosedError","AdminGrantAlreadyExistsError","AdminGrantNotFoundError","AdminIdempotencyKeyReuseError","AdminRoleRequiredError","AuthDependencyUnavailableError","CannotImpersonateAdministratorError","CannotImpersonateSelfError","EmailNotVerifiedError","ImpersonationDisabledError","ImpersonationExpiredError","ImpersonationTargetNotActiveError","InvalidAdminBootstrapTokenError","InvalidAdministratorUserDirectoryFilterError","InvalidCredentialsError","InvalidOAuthClientMetadataError","InvalidOAuthConfigurationError","LastAdminOwnerError","OAuthMetadataFetchError","OAuthRedirectUriNotRegisteredError","SignupNotAllowedError","UserNotFoundError","issueJobLeaseToken","jobLeaseParamsFrom","verifyJobLeaseToken","assertOAuthClientMetadataMatchesRequest","assertOAuthRedirectUriRegistered","isOAuthLoopbackRedirectUri","metadataForAgentClient","OAUTH_CIMD_CACHE_MAX_AGE_SECONDS","OAUTH_CLIENT_ID_MAX_BYTES","OAUTH_CLIENT_NAME_MAX_BYTES","OAUTH_REDIRECT_URI_MAX_BYTES","OAUTH_REDIRECT_URI_MAX_COUNT","oauthRedirectUriMatches","validateOAuthClientId","validateOAuthClientMetadataDocument","validateOAuthDynamicClientRegistration","validateOAuthPublicOrigin","validateOAuthRedirectUri","createOAuthClientResolver","OAUTH_CIMD_CACHE_MAX_ENTRIES","registerOAuthClient","resolveOAuthClient","issueRunnerSessionToken","verifyRunnerSessionToken","DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE","getAuthenticatedSessionContext","authCookiePlugin","clearRefreshTokenCookie","getRefreshTokenCookie","setRefreshTokenCookie","createOAuthClientIdentificationRoutes","createOAuthMetadataRoutes","createOAuthRoutes","subscriber","createAuthModule","workspaces","signupPolicy","name","database","databaseNamespace","auth","loginMethods","AUTH_PASSWORD_ENABLED","routes","e2eRoutes","publishers","table","eventSchemas","subscribers","workers","taskQueue","activities","workflows","id","cronSchedule","interModulePresentations"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type AuthTokenType = 'session' | 'job_lease' | 'runner_session';
|
|
2
2
|
export type AuthTokenVerificationOutcome = 'ok' | 'rejected';
|
|
3
3
|
export type AuthTokenRefreshOutcome = 'rotated' | 'grace' | 'rejected';
|
|
4
|
-
export type AuthRateLimitAction = 'login' | 'email-send' | 'bootstrap' | 'bootstrap-state' | 'lookup' | 'directory' | 'impersonate';
|
|
4
|
+
export type AuthRateLimitAction = 'login' | 'email-send' | 'bootstrap' | 'bootstrap-state' | 'lookup' | 'directory' | 'impersonate' | 'oauth-register' | 'oauth-cimd' | 'oauth-authorize' | 'oauth-token';
|
|
5
5
|
export type AuthRateLimitScope = 'ip' | 'email' | 'actor';
|
|
6
6
|
export type AuthRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';
|
|
7
7
|
export type AuthImpersonationOutcome = 'succeeded' | 'failed';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/metrics/instance.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,gBAAgB,CAAC;AACvE,MAAM,MAAM,4BAA4B,GAAG,IAAI,GAAG,UAAU,CAAC;AAC7D,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AACvE,MAAM,MAAM,mBAAmB,GAC3B,OAAO,GACP,YAAY,GACZ,WAAW,GACX,iBAAiB,GACjB,QAAQ,GACR,WAAW,GACX,aAAa,CAAC;AAClB,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1D,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AACzE,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG,QAAQ,CAAC;AA2C9D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAEhE;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,4BAA4B,GACpC,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAE3E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,OAAO,EAAE,oBAAoB,CAAC;CAC/B,GAAG,IAAI,CAQP;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAElF"}
|
|
1
|
+
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/metrics/instance.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,gBAAgB,CAAC;AACvE,MAAM,MAAM,4BAA4B,GAAG,IAAI,GAAG,UAAU,CAAC;AAC7D,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AACvE,MAAM,MAAM,mBAAmB,GAC3B,OAAO,GACP,YAAY,GACZ,WAAW,GACX,iBAAiB,GACjB,QAAQ,GACR,WAAW,GACX,aAAa,GACb,gBAAgB,GAChB,YAAY,GACZ,iBAAiB,GACjB,aAAa,CAAC;AAClB,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1D,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AACzE,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG,QAAQ,CAAC;AA2C9D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAEhE;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,4BAA4B,GACpC,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAE3E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,OAAO,EAAE,oBAAoB,CAAC;CAC/B,GAAG,IAAI,CAQP;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAElF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/metrics/instance.ts"],"sourcesContent":["import {instanceMetrics} from '@shipfox/node-opentelemetry';\n\nexport type AuthTokenType = 'session' | 'job_lease' | 'runner_session';\nexport type AuthTokenVerificationOutcome = 'ok' | 'rejected';\nexport type AuthTokenRefreshOutcome = 'rotated' | 'grace' | 'rejected';\nexport type AuthRateLimitAction =\n | 'login'\n | 'email-send'\n | 'bootstrap'\n | 'bootstrap-state'\n | 'lookup'\n | 'directory'\n | 'impersonate';\nexport type AuthRateLimitScope = 'ip' | 'email' | 'actor';\nexport type AuthRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';\nexport type AuthImpersonationOutcome = 'succeeded' | 'failed';\n\nconst meter = instanceMetrics.getMeter('auth');\n\nconst tokenIssuedCount = meter.createCounter<{token_type: AuthTokenType}>('auth_token_issued', {\n description: 'Tokens issued by token type',\n});\n\nconst tokenVerifiedCount = meter.createCounter<{\n token_type: AuthTokenType;\n outcome: AuthTokenVerificationOutcome;\n}>('auth_token_verified', {description: 'Token verification attempts by token type and outcome'});\n\nconst tokenRefreshedCount = meter.createCounter<{outcome: AuthTokenRefreshOutcome}>(\n 'auth_token_refreshed',\n {description: 'Refresh-token exchanges by outcome'},\n);\n\nconst rateLimitCheckCount = meter.createCounter<{\n action: AuthRateLimitAction;\n scope: AuthRateLimitScope;\n outcome: AuthRateLimitOutcome;\n}>('auth_rate_limit_checks', {\n description: 'Authentication rate limit checks by action, scope, and outcome',\n});\n\nconst rateLimitPruneFailureCount = meter.createCounter('auth_rate_limit_prune_failures', {\n description: 'Authentication rate limit prune failures',\n});\n\nconst impersonationCommandCount = meter.createCounter<{outcome: AuthImpersonationOutcome}>(\n 'auth_impersonation_commands',\n {description: 'Impersonation mint command attempts by outcome'},\n);\n\nfunction recordMetric(record: () => void): void {\n try {\n record();\n } catch {\n // Metrics must not affect authentication outcomes.\n }\n}\n\nexport function recordTokenIssued(tokenType: AuthTokenType): void {\n recordMetric(() => tokenIssuedCount.add(1, {token_type: tokenType}));\n}\n\nexport function recordTokenVerified(\n tokenType: AuthTokenType,\n outcome: AuthTokenVerificationOutcome,\n): void {\n recordMetric(() => tokenVerifiedCount.add(1, {token_type: tokenType, outcome}));\n}\n\nexport function recordTokenRefreshed(outcome: AuthTokenRefreshOutcome): void {\n recordMetric(() => tokenRefreshedCount.add(1, {outcome}));\n}\n\nexport function recordAuthRateLimitCheck(params: {\n action: AuthRateLimitAction;\n scope: AuthRateLimitScope;\n outcome: AuthRateLimitOutcome;\n}): void {\n recordMetric(() =>\n rateLimitCheckCount.add(1, {\n action: params.action,\n scope: params.scope,\n outcome: params.outcome,\n }),\n );\n}\n\nexport function recordAuthRateLimitPruneFailure(): void {\n recordMetric(() => rateLimitPruneFailureCount.add(1));\n}\n\nexport function recordImpersonationOutcome(outcome: AuthImpersonationOutcome): void {\n recordMetric(() => impersonationCommandCount.add(1, {outcome}));\n}\n"],"names":["instanceMetrics","meter","getMeter","tokenIssuedCount","createCounter","description","tokenVerifiedCount","tokenRefreshedCount","rateLimitCheckCount","rateLimitPruneFailureCount","impersonationCommandCount","recordMetric","record","recordTokenIssued","tokenType","add","token_type","recordTokenVerified","outcome","recordTokenRefreshed","recordAuthRateLimitCheck","params","action","scope","recordAuthRateLimitPruneFailure","recordImpersonationOutcome"],"mappings":"AAAA,SAAQA,eAAe,QAAO,8BAA8B;
|
|
1
|
+
{"version":3,"sources":["../../src/metrics/instance.ts"],"sourcesContent":["import {instanceMetrics} from '@shipfox/node-opentelemetry';\n\nexport type AuthTokenType = 'session' | 'job_lease' | 'runner_session';\nexport type AuthTokenVerificationOutcome = 'ok' | 'rejected';\nexport type AuthTokenRefreshOutcome = 'rotated' | 'grace' | 'rejected';\nexport type AuthRateLimitAction =\n | 'login'\n | 'email-send'\n | 'bootstrap'\n | 'bootstrap-state'\n | 'lookup'\n | 'directory'\n | 'impersonate'\n | 'oauth-register'\n | 'oauth-cimd'\n | 'oauth-authorize'\n | 'oauth-token';\nexport type AuthRateLimitScope = 'ip' | 'email' | 'actor';\nexport type AuthRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';\nexport type AuthImpersonationOutcome = 'succeeded' | 'failed';\n\nconst meter = instanceMetrics.getMeter('auth');\n\nconst tokenIssuedCount = meter.createCounter<{token_type: AuthTokenType}>('auth_token_issued', {\n description: 'Tokens issued by token type',\n});\n\nconst tokenVerifiedCount = meter.createCounter<{\n token_type: AuthTokenType;\n outcome: AuthTokenVerificationOutcome;\n}>('auth_token_verified', {description: 'Token verification attempts by token type and outcome'});\n\nconst tokenRefreshedCount = meter.createCounter<{outcome: AuthTokenRefreshOutcome}>(\n 'auth_token_refreshed',\n {description: 'Refresh-token exchanges by outcome'},\n);\n\nconst rateLimitCheckCount = meter.createCounter<{\n action: AuthRateLimitAction;\n scope: AuthRateLimitScope;\n outcome: AuthRateLimitOutcome;\n}>('auth_rate_limit_checks', {\n description: 'Authentication rate limit checks by action, scope, and outcome',\n});\n\nconst rateLimitPruneFailureCount = meter.createCounter('auth_rate_limit_prune_failures', {\n description: 'Authentication rate limit prune failures',\n});\n\nconst impersonationCommandCount = meter.createCounter<{outcome: AuthImpersonationOutcome}>(\n 'auth_impersonation_commands',\n {description: 'Impersonation mint command attempts by outcome'},\n);\n\nfunction recordMetric(record: () => void): void {\n try {\n record();\n } catch {\n // Metrics must not affect authentication outcomes.\n }\n}\n\nexport function recordTokenIssued(tokenType: AuthTokenType): void {\n recordMetric(() => tokenIssuedCount.add(1, {token_type: tokenType}));\n}\n\nexport function recordTokenVerified(\n tokenType: AuthTokenType,\n outcome: AuthTokenVerificationOutcome,\n): void {\n recordMetric(() => tokenVerifiedCount.add(1, {token_type: tokenType, outcome}));\n}\n\nexport function recordTokenRefreshed(outcome: AuthTokenRefreshOutcome): void {\n recordMetric(() => tokenRefreshedCount.add(1, {outcome}));\n}\n\nexport function recordAuthRateLimitCheck(params: {\n action: AuthRateLimitAction;\n scope: AuthRateLimitScope;\n outcome: AuthRateLimitOutcome;\n}): void {\n recordMetric(() =>\n rateLimitCheckCount.add(1, {\n action: params.action,\n scope: params.scope,\n outcome: params.outcome,\n }),\n );\n}\n\nexport function recordAuthRateLimitPruneFailure(): void {\n recordMetric(() => rateLimitPruneFailureCount.add(1));\n}\n\nexport function recordImpersonationOutcome(outcome: AuthImpersonationOutcome): void {\n recordMetric(() => impersonationCommandCount.add(1, {outcome}));\n}\n"],"names":["instanceMetrics","meter","getMeter","tokenIssuedCount","createCounter","description","tokenVerifiedCount","tokenRefreshedCount","rateLimitCheckCount","rateLimitPruneFailureCount","impersonationCommandCount","recordMetric","record","recordTokenIssued","tokenType","add","token_type","recordTokenVerified","outcome","recordTokenRefreshed","recordAuthRateLimitCheck","params","action","scope","recordAuthRateLimitPruneFailure","recordImpersonationOutcome"],"mappings":"AAAA,SAAQA,eAAe,QAAO,8BAA8B;AAqB5D,MAAMC,QAAQD,gBAAgBE,QAAQ,CAAC;AAEvC,MAAMC,mBAAmBF,MAAMG,aAAa,CAA8B,qBAAqB;IAC7FC,aAAa;AACf;AAEA,MAAMC,qBAAqBL,MAAMG,aAAa,CAG3C,uBAAuB;IAACC,aAAa;AAAuD;AAE/F,MAAME,sBAAsBN,MAAMG,aAAa,CAC7C,wBACA;IAACC,aAAa;AAAoC;AAGpD,MAAMG,sBAAsBP,MAAMG,aAAa,CAI5C,0BAA0B;IAC3BC,aAAa;AACf;AAEA,MAAMI,6BAA6BR,MAAMG,aAAa,CAAC,kCAAkC;IACvFC,aAAa;AACf;AAEA,MAAMK,4BAA4BT,MAAMG,aAAa,CACnD,+BACA;IAACC,aAAa;AAAgD;AAGhE,SAASM,aAAaC,MAAkB;IACtC,IAAI;QACFA;IACF,EAAE,OAAM;IACN,mDAAmD;IACrD;AACF;AAEA,OAAO,SAASC,kBAAkBC,SAAwB;IACxDH,aAAa,IAAMR,iBAAiBY,GAAG,CAAC,GAAG;YAACC,YAAYF;QAAS;AACnE;AAEA,OAAO,SAASG,oBACdH,SAAwB,EACxBI,OAAqC;IAErCP,aAAa,IAAML,mBAAmBS,GAAG,CAAC,GAAG;YAACC,YAAYF;YAAWI;QAAO;AAC9E;AAEA,OAAO,SAASC,qBAAqBD,OAAgC;IACnEP,aAAa,IAAMJ,oBAAoBQ,GAAG,CAAC,GAAG;YAACG;QAAO;AACxD;AAEA,OAAO,SAASE,yBAAyBC,MAIxC;IACCV,aAAa,IACXH,oBAAoBO,GAAG,CAAC,GAAG;YACzBO,QAAQD,OAAOC,MAAM;YACrBC,OAAOF,OAAOE,KAAK;YACnBL,SAASG,OAAOH,OAAO;QACzB;AAEJ;AAEA,OAAO,SAASM;IACdb,aAAa,IAAMF,2BAA2BM,GAAG,CAAC;AACpD;AAEA,OAAO,SAASU,2BAA2BP,OAAiC;IAC1EP,aAAa,IAAMD,0BAA0BK,GAAG,CAAC,GAAG;YAACG;QAAO;AAC9D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RouteGroup } from '@shipfox/node-fastify';
|
|
2
|
+
export interface CreateOAuthRoutesOptions {
|
|
3
|
+
/** Validated here and deliberately injected until production composition. */
|
|
4
|
+
apiPublicUrl: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createOAuthMetadataRoutes(options: CreateOAuthRoutesOptions): RouteGroup;
|
|
7
|
+
export declare function createOAuthClientIdentificationRoutes(): RouteGroup;
|
|
8
|
+
export declare function createOAuthRoutes(options: CreateOAuthRoutesOptions): RouteGroup;
|
|
9
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/oauth.ts"],"names":[],"mappings":"AAOA,OAAO,EAA2B,KAAK,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAWhF,MAAM,WAAW,wBAAwB;IACvC,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;CACtB;AAoGD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,wBAAwB,GAAG,UAAU,CASvF;AAED,wBAAgB,qCAAqC,IAAI,UAAU,CAElE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,UAAU,CAO/E"}
|