@absolutejs/auth 0.35.0-beta.0 → 0.35.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/dist/cli/migrate.d.ts +2 -0
- package/dist/cli/migrate.js +2719 -0
- package/dist/cli/migrate.js.map +35 -0
- package/dist/client/index.js +2 -32
- package/dist/client/index.js.map +2 -2
- package/dist/client/react.js +2 -32
- package/dist/client/react.js.map +2 -2
- package/dist/client/solid.js +2 -32
- package/dist/client/solid.js.map +2 -2
- package/dist/client/svelte.js +2 -32
- package/dist/client/svelte.js.map +2 -2
- package/dist/client/vue.js +2 -32
- package/dist/client/vue.js.map +2 -2
- package/dist/htmx/index.js +2 -32
- package/dist/htmx/index.js.map +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2126 -3302
- package/dist/index.js.map +20 -57
- package/dist/migrations/generate.d.ts +2 -0
- package/dist/migrations/index.d.ts +5 -0
- package/dist/migrations/runner.d.ts +13 -0
- package/dist/migrations/types.d.ts +14 -0
- package/dist/plugins/index.js +2 -32
- package/dist/plugins/index.js.map +2 -2
- package/package.json +5 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/adaptive/postgresStores.ts", "../../src/stores/postgres.ts", "../../src/apikeys/postgresStores.ts", "../../src/audit/postgresAuditStore.ts", "../../src/credentials/postgresCredentialStore.ts", "../../src/fga/postgresStores.ts", "../../src/linkedProviders/neonStores.ts", "../../node_modules/citra/dist/index.js", "../../src/lockout/postgresLockoutStore.ts", "../../src/mfa/postgresMfaStore.ts", "../../src/oidc/postgresStores.ts", "../../src/organizations/postgresOrganizationStore.ts", "../../src/passwordless/postgresPasswordlessTokenStore.ts", "../../src/portal/postgresSetupSessionStore.ts", "../../src/roles/postgresRoleStore.ts", "../../src/scim/postgresScimTokenStore.ts", "../../src/session/neonStore.ts", "../../src/sso/postgresSamlServiceProviderStore.ts", "../../src/sso/postgresSsoConnectionStore.ts", "../../src/vault/postgresVaultStore.ts", "../../src/webauthn/postgresWebAuthnCredentialStore.ts", "../../src/webhooks/postgresStore.ts", "../../src/migrations/generate.ts", "../../src/migrations/runner.ts", "../../src/migrations/index.ts", "../../src/cli/migrate.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { and, desc, eq } from 'drizzle-orm';\nimport {\n\tbigint,\n\tboolean,\n\tdoublePrecision,\n\tpgTable,\n\tprimaryKey,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tKnownDevice,\n\tKnownDeviceStore,\n\tLoginAttempt,\n\tLoginHistoryStore\n} from './types';\n\nconst ID_LENGTH = 255;\n\nexport const knownDevicesTable = pgTable(\n\t'auth_known_devices',\n\t{\n\t\tdevice_id: varchar('device_id', { length: ID_LENGTH }).notNull(),\n\t\tfirst_seen_at_ms: bigint('first_seen_at_ms', {\n\t\t\tmode: 'number'\n\t\t}).notNull(),\n\t\tlabel: varchar('label', { length: ID_LENGTH }),\n\t\tlast_seen_at_ms: bigint('last_seen_at_ms', {\n\t\t\tmode: 'number'\n\t\t}).notNull(),\n\t\ttrusted: boolean('trusted').notNull().default(false),\n\t\tuser_id: varchar('user_id', { length: ID_LENGTH }).notNull()\n\t},\n\t(table) => [primaryKey({ columns: [table.user_id, table.device_id] })]\n);\n\nexport const loginHistoryTable = pgTable('auth_login_history', {\n\tattempt_id: varchar('attempt_id', { length: ID_LENGTH }).primaryKey(),\n\tcountry: varchar('country', { length: ID_LENGTH }),\n\tdevice_id: varchar('device_id', { length: ID_LENGTH }).notNull(),\n\tip_address: varchar('ip_address', { length: ID_LENGTH }),\n\tlatitude: doublePrecision('latitude'),\n\tlongitude: doublePrecision('longitude'),\n\toutcome: varchar('outcome', { length: ID_LENGTH }).notNull(),\n\ttimestamp_ms: bigint('timestamp_ms', { mode: 'number' }).notNull(),\n\tuser_id: varchar('user_id', { length: ID_LENGTH }).notNull()\n});\n\ntype KnownDeviceRow = typeof knownDevicesTable.$inferSelect;\ntype LoginAttemptRow = typeof loginHistoryTable.$inferSelect;\n\nconst toRiskAction = (value: string) => {\n\tif (value === 'deny') return 'deny';\n\tif (value === 'step_up') return 'step_up';\n\n\treturn 'allow';\n};\n\nconst toDevice = (row: KnownDeviceRow): KnownDevice => ({\n\tdeviceId: row.device_id,\n\tfirstSeenAt: row.first_seen_at_ms,\n\tlabel: row.label ?? undefined,\n\tlastSeenAt: row.last_seen_at_ms,\n\ttrusted: row.trusted,\n\tuserId: row.user_id\n});\n\nconst toDeviceValues = (\n\tdevice: KnownDevice\n): typeof knownDevicesTable.$inferInsert => ({\n\tdevice_id: device.deviceId,\n\tfirst_seen_at_ms: device.firstSeenAt,\n\tlabel: device.label ?? null,\n\tlast_seen_at_ms: device.lastSeenAt,\n\ttrusted: device.trusted,\n\tuser_id: device.userId\n});\n\nconst toAttempt = (row: LoginAttemptRow): LoginAttempt => ({\n\tattemptId: row.attempt_id,\n\tcountry: row.country ?? undefined,\n\tdeviceId: row.device_id,\n\tipAddress: row.ip_address ?? undefined,\n\tlatitude: row.latitude ?? undefined,\n\tlongitude: row.longitude ?? undefined,\n\toutcome: toRiskAction(row.outcome),\n\ttimestamp: row.timestamp_ms,\n\tuserId: row.user_id\n});\n\nconst toAttemptValues = (\n\tattempt: LoginAttempt\n): typeof loginHistoryTable.$inferInsert => ({\n\tattempt_id: attempt.attemptId,\n\tcountry: attempt.country ?? null,\n\tdevice_id: attempt.deviceId,\n\tip_address: attempt.ipAddress ?? null,\n\tlatitude: attempt.latitude ?? null,\n\tlongitude: attempt.longitude ?? null,\n\toutcome: attempt.outcome,\n\ttimestamp_ms: attempt.timestamp,\n\tuser_id: attempt.userId\n});\n\nexport const createNeonKnownDeviceStore = (databaseUrl: string) =>\n\tcreatePostgresKnownDeviceStore(createNeonDatabase(databaseUrl));\nexport const createNeonLoginHistoryStore = (databaseUrl: string) =>\n\tcreatePostgresLoginHistoryStore(createNeonDatabase(databaseUrl));\nexport const createPostgresKnownDeviceStore = (\n\tdb: AnyPgDatabase\n): KnownDeviceStore => ({\n\tfindDevice: async (userId, deviceId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(knownDevicesTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(knownDevicesTable.user_id, userId),\n\t\t\t\t\teq(knownDevicesTable.device_id, deviceId)\n\t\t\t\t)\n\t\t\t)\n\t\t\t.limit(1);\n\n\t\treturn row ? toDevice(row) : undefined;\n\t},\n\tlistDevices: async (userId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(knownDevicesTable)\n\t\t\t.where(eq(knownDevicesTable.user_id, userId))\n\t\t\t.orderBy(desc(knownDevicesTable.last_seen_at_ms));\n\n\t\treturn rows.map(toDevice);\n\t},\n\tsaveDevice: async (device) => {\n\t\tconst values = toDeviceValues(device);\n\t\tawait db\n\t\t\t.insert(knownDevicesTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: values,\n\t\t\t\ttarget: [knownDevicesTable.user_id, knownDevicesTable.device_id]\n\t\t\t});\n\t}\n});\nexport const createPostgresLoginHistoryStore = (\n\tdb: AnyPgDatabase\n): LoginHistoryStore => ({\n\tlistRecent: async (userId, limit) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(loginHistoryTable)\n\t\t\t.where(eq(loginHistoryTable.user_id, userId))\n\t\t\t.orderBy(desc(loginHistoryTable.timestamp_ms))\n\t\t\t.limit(limit);\n\n\t\treturn rows.map(toAttempt);\n\t},\n\trecordAttempt: async (attempt) => {\n\t\tawait db.insert(loginHistoryTable).values(toAttemptValues(attempt));\n\t}\n});\n",
|
|
6
|
+
"import { neon } from '@neondatabase/serverless';\nimport { drizzle } from 'drizzle-orm/neon-http';\nimport type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';\n\n// Shared scaffolding for the enterprise stores. Every new store ships an\n// in-memory implementation (dev/test) plus a Postgres implementation that accepts\n// a Drizzle `PgDatabase` — so it runs on Neon (neon-http) AND node-postgres without\n// the package bundling a second driver. `createNeonDatabase` is the convenience\n// wrapper consumers reach for when they just want a Neon connection string.\n\nexport type AnyPgDatabase = PgDatabase<PgQueryResultHKT>;\n\nexport const createNeonDatabase = (databaseUrl: string) =>\n\tdrizzle(neon(databaseUrl));\n",
|
|
7
|
+
"import { desc, eq, lt } from 'drizzle-orm';\nimport { bigint, pgTable, text, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tAccessToken,\n\tAccessTokenStore,\n\tApiClient,\n\tApiClientStore,\n\tApiKey,\n\tApiKeyStore\n} from './types';\n\nconst ID_LENGTH = 255;\n\nexport const accessTokensTable = pgTable('auth_access_tokens', {\n\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\thashed_token: varchar('hashed_token', { length: ID_LENGTH }).notNull(),\n\towner_id: varchar('owner_id', { length: ID_LENGTH }),\n\tscopes: text('scopes').array().notNull(),\n\ttoken_id: varchar('token_id', { length: ID_LENGTH }).primaryKey()\n});\nexport const apiClientsTable = pgTable('auth_api_clients', {\n\tclient_id: varchar('client_id', { length: ID_LENGTH }).primaryKey(),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\thashed_secret: varchar('hashed_secret', { length: ID_LENGTH }).notNull(),\n\tname: varchar('name', { length: ID_LENGTH }).notNull(),\n\towner_id: varchar('owner_id', { length: ID_LENGTH }),\n\tscopes: text('scopes').array().notNull()\n});\nexport const apiKeysTable = pgTable('auth_api_keys', {\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }),\n\thashed_key: varchar('hashed_key', { length: ID_LENGTH }).notNull(),\n\tkey_id: varchar('key_id', { length: ID_LENGTH }).primaryKey(),\n\tlast_used_at_ms: bigint('last_used_at_ms', { mode: 'number' }),\n\tname: varchar('name', { length: ID_LENGTH }).notNull(),\n\towner_id: varchar('owner_id', { length: ID_LENGTH }),\n\tprefix: varchar('prefix', { length: ID_LENGTH }).notNull(),\n\tscopes: text('scopes').array().notNull()\n});\n\ntype ApiKeyRow = typeof apiKeysTable.$inferSelect;\ntype ApiClientRow = typeof apiClientsTable.$inferSelect;\ntype AccessTokenRow = typeof accessTokensTable.$inferSelect;\n\nconst toKey = (row: ApiKeyRow): ApiKey => ({\n\tcreatedAt: row.created_at_ms,\n\texpiresAt: row.expires_at_ms ?? undefined,\n\thashedKey: row.hashed_key,\n\tkeyId: row.key_id,\n\tlastUsedAt: row.last_used_at_ms ?? undefined,\n\tname: row.name,\n\townerId: row.owner_id ?? undefined,\n\tprefix: row.prefix,\n\tscopes: row.scopes\n});\n\nconst toKeyValues = (key: ApiKey): typeof apiKeysTable.$inferInsert => ({\n\tcreated_at_ms: key.createdAt,\n\texpires_at_ms: key.expiresAt ?? null,\n\thashed_key: key.hashedKey,\n\tkey_id: key.keyId,\n\tlast_used_at_ms: key.lastUsedAt ?? null,\n\tname: key.name,\n\towner_id: key.ownerId ?? null,\n\tprefix: key.prefix,\n\tscopes: key.scopes\n});\n\nconst toClient = (row: ApiClientRow): ApiClient => ({\n\tclientId: row.client_id,\n\tcreatedAt: row.created_at_ms,\n\thashedSecret: row.hashed_secret,\n\tname: row.name,\n\townerId: row.owner_id ?? undefined,\n\tscopes: row.scopes\n});\n\nconst toClientValues = (\n\tclient: ApiClient\n): typeof apiClientsTable.$inferInsert => ({\n\tclient_id: client.clientId,\n\tcreated_at_ms: client.createdAt,\n\thashed_secret: client.hashedSecret,\n\tname: client.name,\n\towner_id: client.ownerId ?? null,\n\tscopes: client.scopes\n});\n\nconst toAccessToken = (row: AccessTokenRow): AccessToken => ({\n\tclientId: row.client_id,\n\tcreatedAt: row.created_at_ms,\n\texpiresAt: row.expires_at_ms,\n\thashedToken: row.hashed_token,\n\townerId: row.owner_id ?? undefined,\n\tscopes: row.scopes,\n\ttokenId: row.token_id\n});\n\nconst toAccessTokenValues = (\n\ttoken: AccessToken\n): typeof accessTokensTable.$inferInsert => ({\n\tclient_id: token.clientId,\n\tcreated_at_ms: token.createdAt,\n\texpires_at_ms: token.expiresAt,\n\thashed_token: token.hashedToken,\n\towner_id: token.ownerId ?? null,\n\tscopes: token.scopes,\n\ttoken_id: token.tokenId\n});\n\nexport const createNeonAccessTokenStore = (databaseUrl: string) =>\n\tcreatePostgresAccessTokenStore(createNeonDatabase(databaseUrl));\nexport const createNeonApiClientStore = (databaseUrl: string) =>\n\tcreatePostgresApiClientStore(createNeonDatabase(databaseUrl));\nexport const createNeonApiKeyStore = (databaseUrl: string) =>\n\tcreatePostgresApiKeyStore(createNeonDatabase(databaseUrl));\nexport const createPostgresAccessTokenStore = (\n\tdb: AnyPgDatabase\n): AccessTokenStore => ({\n\tdeleteExpired: async (now) => {\n\t\tawait db\n\t\t\t.delete(accessTokensTable)\n\t\t\t.where(lt(accessTokensTable.expires_at_ms, now));\n\t},\n\tdeleteToken: async (tokenId) => {\n\t\tawait db\n\t\t\t.delete(accessTokensTable)\n\t\t\t.where(eq(accessTokensTable.token_id, tokenId));\n\t},\n\tfindByHashedToken: async (hashedToken) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(accessTokensTable)\n\t\t\t.where(eq(accessTokensTable.hashed_token, hashedToken))\n\t\t\t.limit(1);\n\n\t\treturn row ? toAccessToken(row) : undefined;\n\t},\n\tsaveToken: async (token) => {\n\t\tconst values = toAccessTokenValues(token);\n\t\tawait db.insert(accessTokensTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: accessTokensTable.token_id\n\t\t});\n\t}\n});\nexport const createPostgresApiClientStore = (\n\tdb: AnyPgDatabase\n): ApiClientStore => ({\n\tdeleteClient: async (clientId) => {\n\t\tawait db\n\t\t\t.delete(apiClientsTable)\n\t\t\t.where(eq(apiClientsTable.client_id, clientId));\n\t},\n\tfindClient: async (clientId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(apiClientsTable)\n\t\t\t.where(eq(apiClientsTable.client_id, clientId))\n\t\t\t.limit(1);\n\n\t\treturn row ? toClient(row) : undefined;\n\t},\n\tlistClients: async (ownerId) => {\n\t\tconst rows =\n\t\t\townerId === undefined\n\t\t\t\t? await db\n\t\t\t\t\t\t.select()\n\t\t\t\t\t\t.from(apiClientsTable)\n\t\t\t\t\t\t.orderBy(desc(apiClientsTable.created_at_ms))\n\t\t\t\t: await db\n\t\t\t\t\t\t.select()\n\t\t\t\t\t\t.from(apiClientsTable)\n\t\t\t\t\t\t.where(eq(apiClientsTable.owner_id, ownerId))\n\t\t\t\t\t\t.orderBy(desc(apiClientsTable.created_at_ms));\n\n\t\treturn rows.map(toClient);\n\t},\n\tsaveClient: async (client) => {\n\t\tconst values = toClientValues(client);\n\t\tawait db.insert(apiClientsTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: apiClientsTable.client_id\n\t\t});\n\t}\n});\nexport const createPostgresApiKeyStore = (db: AnyPgDatabase): ApiKeyStore => ({\n\tdeleteKey: async (keyId) => {\n\t\tawait db.delete(apiKeysTable).where(eq(apiKeysTable.key_id, keyId));\n\t},\n\tfindByHashedKey: async (hashedKey) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(apiKeysTable)\n\t\t\t.where(eq(apiKeysTable.hashed_key, hashedKey))\n\t\t\t.limit(1);\n\n\t\treturn row ? toKey(row) : undefined;\n\t},\n\tlistKeys: async (ownerId) => {\n\t\tconst rows =\n\t\t\townerId === undefined\n\t\t\t\t? await db\n\t\t\t\t\t\t.select()\n\t\t\t\t\t\t.from(apiKeysTable)\n\t\t\t\t\t\t.orderBy(desc(apiKeysTable.created_at_ms))\n\t\t\t\t: await db\n\t\t\t\t\t\t.select()\n\t\t\t\t\t\t.from(apiKeysTable)\n\t\t\t\t\t\t.where(eq(apiKeysTable.owner_id, ownerId))\n\t\t\t\t\t\t.orderBy(desc(apiKeysTable.created_at_ms));\n\n\t\treturn rows.map(toKey);\n\t},\n\tsaveKey: async (key) => {\n\t\tconst values = toKeyValues(key);\n\t\tawait db.insert(apiKeysTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: apiKeysTable.key_id\n\t\t});\n\t},\n\ttouchKey: async (keyId, lastUsedAt) => {\n\t\tawait db\n\t\t\t.update(apiKeysTable)\n\t\t\t.set({ last_used_at_ms: lastUsedAt })\n\t\t\t.where(eq(apiKeysTable.key_id, keyId));\n\t}\n});\n",
|
|
8
|
+
"import { desc, eq, lt } from 'drizzle-orm';\nimport { bigint, jsonb, pgTable, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { AuditEvent, AuditEventType, AuditSink } from './types';\n\nconst ID_LENGTH = 255;\nconst IP_LENGTH = 64;\nconst TYPE_LENGTH = 64;\nconst DEFAULT_AUDIT_LIMIT = 100;\n\nexport const auditEventsTable = pgTable('auth_audit_events', {\n\tat_ms: bigint('at_ms', { mode: 'number' }).notNull(),\n\tid: varchar('id', { length: ID_LENGTH }).primaryKey(),\n\tip: varchar('ip', { length: IP_LENGTH }),\n\tmetadata_json: jsonb('metadata_json').$type<Record<string, unknown>>(),\n\torganization_id: varchar('organization_id', { length: ID_LENGTH }),\n\ttype: varchar('type', { length: TYPE_LENGTH }).notNull(),\n\tuser_id: varchar('user_id', { length: ID_LENGTH })\n});\n\ntype AuditRow = typeof auditEventsTable.$inferSelect;\n\nconst toEvent = (row: AuditRow): AuditEvent => ({\n\tat: row.at_ms,\n\tip: row.ip ?? undefined,\n\tmetadata: row.metadata_json ?? undefined,\n\torganizationId: row.organization_id ?? undefined,\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- deserialization boundary: `type` was persisted from AuditEventType, so reading it back is sound\n\ttype: row.type as AuditEventType,\n\tuserId: row.user_id ?? undefined\n});\n\nexport const createNeonAuditSink = (databaseUrl: string) =>\n\tcreatePostgresAuditSink(createNeonDatabase(databaseUrl));\nexport const createPostgresAuditSink = (db: AnyPgDatabase): AuditSink => ({\n\tappend: async (event) => {\n\t\tawait db.insert(auditEventsTable).values({\n\t\t\tat_ms: event.at,\n\t\t\tid: crypto.randomUUID(),\n\t\t\tip: event.ip ?? null,\n\t\t\tmetadata_json: event.metadata ?? null,\n\t\t\torganization_id: event.organizationId ?? null,\n\t\t\ttype: event.type,\n\t\t\tuser_id: event.userId ?? null\n\t\t});\n\t},\n\tlist: async (filter) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(auditEventsTable)\n\t\t\t.where(\n\t\t\t\tfilter?.userId\n\t\t\t\t\t? eq(auditEventsTable.user_id, filter.userId)\n\t\t\t\t\t: undefined\n\t\t\t)\n\t\t\t.orderBy(desc(auditEventsTable.at_ms))\n\t\t\t.limit(filter?.limit ?? DEFAULT_AUDIT_LIMIT);\n\n\t\treturn rows.map(toEvent);\n\t},\n\tprune: async (before) => {\n\t\tconst deleted = await db\n\t\t\t.delete(auditEventsTable)\n\t\t\t.where(lt(auditEventsTable.at_ms, before))\n\t\t\t.returning({ id: auditEventsTable.id });\n\n\t\treturn deleted.length;\n\t}\n});\n",
|
|
9
|
+
"import { eq } from 'drizzle-orm';\nimport { bigint, boolean, pgTable, text, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tCredentialRecord,\n\tCredentialStatus,\n\tCredentialStore,\n\tCredentialToken\n} from './types';\n\nconst EMAIL_LENGTH = 320;\nconst ID_LENGTH = 255;\nconst STATUS_LENGTH = 32;\nconst TOKEN_HASH_LENGTH = 255;\n\nexport const credentialsTable = pgTable('auth_credentials', {\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\temail: varchar('email', { length: EMAIL_LENGTH }).primaryKey(),\n\temail_verified: boolean('email_verified').notNull().default(false),\n\torganization_id: varchar('organization_id', { length: ID_LENGTH }),\n\tpassword_hash: text('password_hash').notNull(),\n\tstatus: varchar('status', { length: STATUS_LENGTH })\n\t\t.notNull()\n\t\t.default('active'),\n\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull(),\n\tuser_id: varchar('user_id', { length: ID_LENGTH })\n});\n\nconst createTokenTable = (name: string) =>\n\tpgTable(name, {\n\t\temail: varchar('email', { length: EMAIL_LENGTH }).notNull(),\n\t\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\t\ttoken_hash: varchar('token_hash', {\n\t\t\tlength: TOKEN_HASH_LENGTH\n\t\t}).primaryKey()\n\t});\n\nexport const credentialResetTokensTable = createTokenTable(\n\t'auth_credential_reset_tokens'\n);\nexport const credentialVerificationTokensTable = createTokenTable(\n\t'auth_credential_verification_tokens'\n);\n\ntype CredentialRow = typeof credentialsTable.$inferSelect;\ntype CredentialInsert = typeof credentialsTable.$inferInsert;\ntype TokenTable = ReturnType<typeof createTokenTable>;\ntype TokenRow = TokenTable['$inferSelect'];\ntype TokenInsert = TokenTable['$inferInsert'];\n\nconst CREDENTIAL_STATUSES: CredentialStatus[] = ['active', 'disabled'];\n\nconst isCredentialStatus = (value: string): value is CredentialStatus =>\n\tCREDENTIAL_STATUSES.some((status) => status === value);\n\nconst toCredentialRecord = (row: CredentialRow): CredentialRecord => ({\n\tcreatedAt: row.created_at_ms,\n\temail: row.email,\n\temailVerified: row.email_verified,\n\torganizationId: row.organization_id ?? undefined,\n\tpasswordHash: row.password_hash,\n\tstatus: isCredentialStatus(row.status) ? row.status : 'active',\n\tupdatedAt: row.updated_at_ms,\n\tuserId: row.user_id ?? undefined\n});\n\nconst toToken = (row: TokenRow): CredentialToken => ({\n\temail: row.email,\n\texpiresAt: row.expires_at_ms,\n\ttokenHash: row.token_hash\n});\n\nconst saveToken = async (\n\tdb: AnyPgDatabase,\n\ttable: TokenTable,\n\ttoken: CredentialToken\n) => {\n\tconst values: TokenInsert = {\n\t\temail: token.email.toLowerCase(),\n\t\texpires_at_ms: token.expiresAt,\n\t\ttoken_hash: token.tokenHash\n\t};\n\tawait db\n\t\t.insert(table)\n\t\t.values(values)\n\t\t.onConflictDoUpdate({ set: values, target: table.token_hash });\n};\n\nconst consumeToken = async (\n\tdb: AnyPgDatabase,\n\ttable: TokenTable,\n\ttokenHash: string\n) => {\n\tconst [row] = await db\n\t\t.select()\n\t\t.from(table)\n\t\t.where(eq(table.token_hash, tokenHash))\n\t\t.limit(1);\n\tif (!row) return undefined;\n\n\tawait db.delete(table).where(eq(table.token_hash, tokenHash));\n\tif (row.expires_at_ms < Date.now()) return undefined;\n\n\treturn toToken(row);\n};\n\nexport const createNeonCredentialStore = (databaseUrl: string) =>\n\tcreatePostgresCredentialStore(createNeonDatabase(databaseUrl));\nexport const createPostgresCredentialStore = (\n\tdb: AnyPgDatabase\n): CredentialStore => ({\n\tconsumeResetToken: (tokenHash) =>\n\t\tconsumeToken(db, credentialResetTokensTable, tokenHash),\n\tconsumeVerificationToken: (tokenHash) =>\n\t\tconsumeToken(db, credentialVerificationTokensTable, tokenHash),\n\tgetCredentialByEmail: async (email) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(credentialsTable)\n\t\t\t.where(eq(credentialsTable.email, email.toLowerCase()))\n\t\t\t.limit(1);\n\n\t\treturn row ? toCredentialRecord(row) : undefined;\n\t},\n\tsaveCredential: async (credential) => {\n\t\tconst values: CredentialInsert = {\n\t\t\tcreated_at_ms: credential.createdAt,\n\t\t\temail: credential.email.toLowerCase(),\n\t\t\temail_verified: credential.emailVerified,\n\t\t\torganization_id: credential.organizationId ?? null,\n\t\t\tpassword_hash: credential.passwordHash,\n\t\t\tstatus: credential.status,\n\t\t\tupdated_at_ms: credential.updatedAt,\n\t\t\tuser_id: credential.userId ?? null\n\t\t};\n\t\tawait db\n\t\t\t.insert(credentialsTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: values,\n\t\t\t\ttarget: credentialsTable.email\n\t\t\t});\n\t},\n\tsaveResetToken: (token) => saveToken(db, credentialResetTokensTable, token),\n\tsaveVerificationToken: (token) =>\n\t\tsaveToken(db, credentialVerificationTokensTable, token),\n\tsetEmailVerified: async (email) => {\n\t\tawait db\n\t\t\t.update(credentialsTable)\n\t\t\t.set({ email_verified: true, updated_at_ms: Date.now() })\n\t\t\t.where(eq(credentialsTable.email, email.toLowerCase()));\n\t}\n});\n",
|
|
10
|
+
"import { and, eq } from 'drizzle-orm';\nimport { pgTable, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport { warrantKey } from './inMemoryStores';\nimport type { Warrant, WarrantStore } from './types';\n\nconst ID_LENGTH = 255;\n\nexport const warrantsTable = pgTable('auth_fga_warrants', {\n\tid: varchar('id', { length: ID_LENGTH }).primaryKey(),\n\trelation: varchar('relation', { length: ID_LENGTH }).notNull(),\n\tresource_id: varchar('resource_id', { length: ID_LENGTH }).notNull(),\n\tresource_type: varchar('resource_type', { length: ID_LENGTH }).notNull(),\n\tsubject_id: varchar('subject_id', { length: ID_LENGTH }).notNull(),\n\tsubject_relation: varchar('subject_relation', { length: ID_LENGTH }),\n\tsubject_type: varchar('subject_type', { length: ID_LENGTH }).notNull()\n});\n\ntype WarrantRow = typeof warrantsTable.$inferSelect;\n\nconst toWarrant = (row: WarrantRow): Warrant => ({\n\trelation: row.relation,\n\tresourceId: row.resource_id,\n\tresourceType: row.resource_type,\n\tsubjectId: row.subject_id,\n\tsubjectRelation: row.subject_relation ?? undefined,\n\tsubjectType: row.subject_type\n});\n\nexport const createNeonWarrantStore = (databaseUrl: string) =>\n\tcreatePostgresWarrantStore(createNeonDatabase(databaseUrl));\nexport const createPostgresWarrantStore = (\n\tdb: AnyPgDatabase\n): WarrantStore => ({\n\tdeleteWarrant: async (warrant) => {\n\t\tawait db\n\t\t\t.delete(warrantsTable)\n\t\t\t.where(eq(warrantsTable.id, warrantKey(warrant)));\n\t},\n\tlistForResource: async (resourceType, resourceId, relation) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(warrantsTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(warrantsTable.resource_type, resourceType),\n\t\t\t\t\teq(warrantsTable.resource_id, resourceId),\n\t\t\t\t\teq(warrantsTable.relation, relation)\n\t\t\t\t)\n\t\t\t);\n\n\t\treturn rows.map(toWarrant);\n\t},\n\tlistResourceIds: async (resourceType) => {\n\t\tconst rows = await db\n\t\t\t.selectDistinct({ resourceId: warrantsTable.resource_id })\n\t\t\t.from(warrantsTable)\n\t\t\t.where(eq(warrantsTable.resource_type, resourceType));\n\n\t\treturn rows.map((row) => row.resourceId);\n\t},\n\tsaveWarrant: async (warrant) => {\n\t\tawait db\n\t\t\t.insert(warrantsTable)\n\t\t\t.values({\n\t\t\t\tid: warrantKey(warrant),\n\t\t\t\trelation: warrant.relation,\n\t\t\t\tresource_id: warrant.resourceId,\n\t\t\t\tresource_type: warrant.resourceType,\n\t\t\t\tsubject_id: warrant.subjectId,\n\t\t\t\tsubject_relation: warrant.subjectRelation ?? null,\n\t\t\t\tsubject_type: warrant.subjectType\n\t\t\t})\n\t\t\t.onConflictDoNothing({ target: warrantsTable.id });\n\t}\n});\n",
|
|
11
|
+
"import type {\n\tLinkedProviderBinding,\n\tLinkedProviderBindingStore,\n\tLinkedProviderGrant,\n\tLinkedProviderGrantStore\n} from '@absolutejs/linked-providers';\nimport { neon } from '@neondatabase/serverless';\nimport { desc, eq } from 'drizzle-orm';\nimport { drizzle, NeonHttpDatabase } from 'drizzle-orm/neon-http';\nimport {\n\ttype AnyPgTable,\n\tjsonb,\n\tpgTable,\n\ttext,\n\ttimestamp,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport type { OAuth2ConfigurationOptions } from '../types';\nimport { createOAuthLinkedProviderCredentialResolver } from './oauthResolver';\n\nexport const linkedProviderBindingsTable = pgTable('linked_provider_bindings', {\n\tavailable_scopes: jsonb('available_scopes')\n\t\t.$type<string[]>()\n\t\t.notNull()\n\t\t.default([]),\n\tcapabilities: jsonb('capabilities').$type<string[]>().default([]),\n\tconnector_provider: varchar('connector_provider', { length: 64 }).notNull(),\n\tcreated_at: timestamp('created_at').notNull().defaultNow(),\n\temail: varchar('email', { length: 320 }),\n\texternal_account_id: varchar('external_account_id', {\n\t\tlength: 255\n\t}).notNull(),\n\texternal_account_type: varchar('external_account_type', {\n\t\tlength: 64\n\t}).notNull(),\n\tgrant_id: varchar('grant_id', { length: 255 }).notNull(),\n\tid: varchar('id', { length: 255 }).primaryKey(),\n\tlabel: varchar('label', { length: 255 }),\n\tmetadata: jsonb('metadata').$type<Record<string, unknown>>().default({}),\n\tstatus: varchar('status', { length: 64 })\n\t\t.$type<LinkedProviderBinding['status']>()\n\t\t.notNull(),\n\tupdated_at: timestamp('updated_at').notNull().defaultNow(),\n\tusername: varchar('username', { length: 255 })\n});\nexport const linkedProviderGrantsTable = pgTable('linked_provider_grants', {\n\taccess_token_ciphertext: text('access_token_ciphertext'),\n\tauth_provider_key: varchar('auth_provider_key', { length: 64 }).notNull(),\n\tcreated_at: timestamp('created_at').notNull().defaultNow(),\n\texpires_at: timestamp('expires_at'),\n\tgranted_scopes: jsonb('granted_scopes')\n\t\t.$type<string[]>()\n\t\t.notNull()\n\t\t.default([]),\n\tid: varchar('id', { length: 255 }).primaryKey(),\n\tlast_refresh_error: text('last_refresh_error'),\n\tlast_refreshed_at: timestamp('last_refreshed_at'),\n\tmetadata: jsonb('metadata').$type<Record<string, unknown>>().default({}),\n\towner_ref: varchar('owner_ref', { length: 255 }).notNull(),\n\tprovider_family: varchar('provider_family', { length: 64 }).notNull(),\n\tprovider_subject: varchar('provider_subject', { length: 255 }).notNull(),\n\trefresh_token_ciphertext: text('refresh_token_ciphertext'),\n\tstatus: varchar('status', { length: 64 })\n\t\t.$type<LinkedProviderGrant['status']>()\n\t\t.notNull(),\n\ttoken_type: varchar('token_type', { length: 64 }),\n\tupdated_at: timestamp('updated_at').notNull().defaultNow()\n});\nexport const linkedProviderSchema = {\n\tlinkedProviderBindings: linkedProviderBindingsTable,\n\tlinkedProviderGrants: linkedProviderGrantsTable\n} satisfies Record<string, AnyPgTable>;\n\nexport type LinkedProviderSchema = typeof linkedProviderSchema;\nexport type LinkedProviderGrantRow =\n\ttypeof linkedProviderGrantsTable.$inferSelect;\nexport type LinkedProviderBindingRow =\n\ttypeof linkedProviderBindingsTable.$inferSelect;\n\nconst toTimestamp = (value: number | undefined) =>\n\tvalue === undefined ? null : new Date(value);\n\nconst fromTimestamp = (value: Date | null) =>\n\tvalue === null ? undefined : value.getTime();\n\nconst toGrant = (row: LinkedProviderGrantRow): LinkedProviderGrant => ({\n\taccessTokenCiphertext: row.access_token_ciphertext ?? undefined,\n\tauthProviderKey: row.auth_provider_key,\n\tcreatedAt: row.created_at.getTime(),\n\texpiresAt: fromTimestamp(row.expires_at),\n\tgrantedScopes: row.granted_scopes ?? [],\n\tid: row.id,\n\tlastRefreshedAt: fromTimestamp(row.last_refreshed_at),\n\tlastRefreshError: row.last_refresh_error ?? undefined,\n\tmetadata: row.metadata ?? undefined,\n\townerRef: row.owner_ref,\n\tproviderFamily: row.provider_family,\n\tproviderSubject: row.provider_subject,\n\trefreshTokenCiphertext: row.refresh_token_ciphertext ?? undefined,\n\tstatus: row.status,\n\ttokenType: row.token_type ?? undefined,\n\tupdatedAt: row.updated_at.getTime()\n});\n\nconst toBinding = (row: LinkedProviderBindingRow): LinkedProviderBinding => ({\n\tavailableScopes: row.available_scopes ?? [],\n\tcapabilities: row.capabilities ?? undefined,\n\tconnectorProvider: row.connector_provider,\n\tcreatedAt: row.created_at.getTime(),\n\temail: row.email ?? undefined,\n\texternalAccountId: row.external_account_id,\n\texternalAccountType: row.external_account_type,\n\tgrantId: row.grant_id,\n\tid: row.id,\n\tlabel: row.label ?? undefined,\n\tmetadata: row.metadata ?? undefined,\n\tstatus: row.status,\n\tupdatedAt: row.updated_at.getTime(),\n\tusername: row.username ?? undefined\n});\n\nexport const createNeonLinkedProviderBindingStore = (\n\tdb: NeonHttpDatabase<LinkedProviderSchema>\n): LinkedProviderBindingStore => ({\n\tgetBinding: async (id) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(linkedProviderBindingsTable)\n\t\t\t.where(eq(linkedProviderBindingsTable.id, id))\n\t\t\t.limit(1);\n\n\t\treturn row ? toBinding(row) : undefined;\n\t},\n\tlistBindingsByGrant: async (grantId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(linkedProviderBindingsTable)\n\t\t\t.where(eq(linkedProviderBindingsTable.grant_id, grantId))\n\t\t\t.orderBy(desc(linkedProviderBindingsTable.updated_at));\n\n\t\treturn rows.map(toBinding);\n\t},\n\tlistBindingsByOwner: async (ownerRef) => {\n\t\tconst rows = await db\n\t\t\t.select({ binding: linkedProviderBindingsTable })\n\t\t\t.from(linkedProviderBindingsTable)\n\t\t\t.innerJoin(\n\t\t\t\tlinkedProviderGrantsTable,\n\t\t\t\teq(\n\t\t\t\t\tlinkedProviderBindingsTable.grant_id,\n\t\t\t\t\tlinkedProviderGrantsTable.id\n\t\t\t\t)\n\t\t\t)\n\t\t\t.where(eq(linkedProviderGrantsTable.owner_ref, ownerRef))\n\t\t\t.orderBy(desc(linkedProviderBindingsTable.updated_at));\n\n\t\treturn rows.map(({ binding }) => toBinding(binding));\n\t},\n\tremoveBinding: async (id) => {\n\t\tawait db\n\t\t\t.delete(linkedProviderBindingsTable)\n\t\t\t.where(eq(linkedProviderBindingsTable.id, id));\n\t},\n\tsaveBinding: async (binding) => {\n\t\tawait db\n\t\t\t.insert(linkedProviderBindingsTable)\n\t\t\t.values({\n\t\t\t\tavailable_scopes: binding.availableScopes,\n\t\t\t\tcapabilities: binding.capabilities ?? [],\n\t\t\t\tconnector_provider: binding.connectorProvider,\n\t\t\t\tcreated_at: new Date(binding.createdAt),\n\t\t\t\temail: binding.email ?? null,\n\t\t\t\texternal_account_id: binding.externalAccountId,\n\t\t\t\texternal_account_type: binding.externalAccountType,\n\t\t\t\tgrant_id: binding.grantId,\n\t\t\t\tid: binding.id,\n\t\t\t\tlabel: binding.label ?? null,\n\t\t\t\tmetadata: binding.metadata ?? {},\n\t\t\t\tstatus: binding.status,\n\t\t\t\tupdated_at: new Date(binding.updatedAt),\n\t\t\t\tusername: binding.username ?? null\n\t\t\t})\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: {\n\t\t\t\t\tavailable_scopes: binding.availableScopes,\n\t\t\t\t\tcapabilities: binding.capabilities ?? [],\n\t\t\t\t\tconnector_provider: binding.connectorProvider,\n\t\t\t\t\temail: binding.email ?? null,\n\t\t\t\t\texternal_account_id: binding.externalAccountId,\n\t\t\t\t\texternal_account_type: binding.externalAccountType,\n\t\t\t\t\tgrant_id: binding.grantId,\n\t\t\t\t\tlabel: binding.label ?? null,\n\t\t\t\t\tmetadata: binding.metadata ?? {},\n\t\t\t\t\tstatus: binding.status,\n\t\t\t\t\tupdated_at: new Date(binding.updatedAt),\n\t\t\t\t\tusername: binding.username ?? null\n\t\t\t\t},\n\t\t\t\ttarget: linkedProviderBindingsTable.id\n\t\t\t});\n\t}\n});\nexport const createNeonLinkedProviderGrantStore = (\n\tdb: NeonHttpDatabase<LinkedProviderSchema>\n): LinkedProviderGrantStore => ({\n\tgetGrant: async (id) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(linkedProviderGrantsTable)\n\t\t\t.where(eq(linkedProviderGrantsTable.id, id))\n\t\t\t.limit(1);\n\n\t\treturn row ? toGrant(row) : undefined;\n\t},\n\tlistGrantsByOwner: async (ownerRef) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(linkedProviderGrantsTable)\n\t\t\t.where(eq(linkedProviderGrantsTable.owner_ref, ownerRef))\n\t\t\t.orderBy(desc(linkedProviderGrantsTable.updated_at));\n\n\t\treturn rows.map(toGrant);\n\t},\n\tremoveGrant: async (id) => {\n\t\tawait db\n\t\t\t.delete(linkedProviderBindingsTable)\n\t\t\t.where(eq(linkedProviderBindingsTable.grant_id, id));\n\t\tawait db\n\t\t\t.delete(linkedProviderGrantsTable)\n\t\t\t.where(eq(linkedProviderGrantsTable.id, id));\n\t},\n\tsaveGrant: async (grant) => {\n\t\tawait db\n\t\t\t.insert(linkedProviderGrantsTable)\n\t\t\t.values({\n\t\t\t\taccess_token_ciphertext: grant.accessTokenCiphertext ?? null,\n\t\t\t\tauth_provider_key: grant.authProviderKey,\n\t\t\t\tcreated_at: new Date(grant.createdAt),\n\t\t\t\texpires_at: toTimestamp(grant.expiresAt),\n\t\t\t\tgranted_scopes: grant.grantedScopes,\n\t\t\t\tid: grant.id,\n\t\t\t\tlast_refresh_error: grant.lastRefreshError ?? null,\n\t\t\t\tlast_refreshed_at: toTimestamp(grant.lastRefreshedAt),\n\t\t\t\tmetadata: grant.metadata ?? {},\n\t\t\t\towner_ref: grant.ownerRef,\n\t\t\t\tprovider_family: grant.providerFamily,\n\t\t\t\tprovider_subject: grant.providerSubject,\n\t\t\t\trefresh_token_ciphertext: grant.refreshTokenCiphertext ?? null,\n\t\t\t\tstatus: grant.status,\n\t\t\t\ttoken_type: grant.tokenType ?? null,\n\t\t\t\tupdated_at: new Date(grant.updatedAt)\n\t\t\t})\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: {\n\t\t\t\t\taccess_token_ciphertext:\n\t\t\t\t\t\tgrant.accessTokenCiphertext ?? null,\n\t\t\t\t\tauth_provider_key: grant.authProviderKey,\n\t\t\t\t\texpires_at: toTimestamp(grant.expiresAt),\n\t\t\t\t\tgranted_scopes: grant.grantedScopes,\n\t\t\t\t\tlast_refresh_error: grant.lastRefreshError ?? null,\n\t\t\t\t\tlast_refreshed_at: toTimestamp(grant.lastRefreshedAt),\n\t\t\t\t\tmetadata: grant.metadata ?? {},\n\t\t\t\t\towner_ref: grant.ownerRef,\n\t\t\t\t\tprovider_family: grant.providerFamily,\n\t\t\t\t\tprovider_subject: grant.providerSubject,\n\t\t\t\t\trefresh_token_ciphertext:\n\t\t\t\t\t\tgrant.refreshTokenCiphertext ?? null,\n\t\t\t\t\tstatus: grant.status,\n\t\t\t\t\ttoken_type: grant.tokenType ?? null,\n\t\t\t\t\tupdated_at: new Date(grant.updatedAt)\n\t\t\t\t},\n\t\t\t\ttarget: linkedProviderGrantsTable.id\n\t\t\t});\n\t}\n});\nexport const createNeonLinkedProviderStores = (databaseUrl: string) => {\n\tconst sql = neon(databaseUrl);\n\tconst db = drizzle(sql, { schema: linkedProviderSchema });\n\n\treturn {\n\t\tbindingStore: createNeonLinkedProviderBindingStore(db),\n\t\tdb,\n\t\tgrantStore: createNeonLinkedProviderGrantStore(db)\n\t};\n};\n\nexport type CreateNeonOAuthLinkedProviderCredentialResolverOptions = {\n\tdatabaseUrl: string;\n\tprovidersConfiguration: OAuth2ConfigurationOptions;\n\tnow?: () => number;\n};\n\nexport const createNeonOAuthLinkedProviderCredentialResolver = async ({\n\tdatabaseUrl,\n\tnow,\n\tprovidersConfiguration\n}: CreateNeonOAuthLinkedProviderCredentialResolverOptions) => {\n\tconst stores = createNeonLinkedProviderStores(databaseUrl);\n\n\treturn createOAuthLinkedProviderCredentialResolver({\n\t\t...stores,\n\t\tnow,\n\t\tprovidersConfiguration\n\t});\n};\n",
|
|
12
|
+
"// @bun\n// src/constants.ts\nvar BASE64_BLOCK_SIZE = 4;\nvar NUM_GENERATOR_BYTES = 32;\n\n// src/graphqlQueries.ts\nvar anilistProfileQuery = `query {\n Viewer {\n id\n name\n about\n avatar {\n large\n medium\n }\n bannerImage\n siteUrl\n createdAt\n updatedAt\n donatorTier\n donatorBadge\n unreadNotificationCount\n options {\n titleLanguage\n displayAdultContent\n airingNotifications\n profileColor\n activityMergeTime\n staffNameLanguage\n }\n mediaListOptions {\n scoreFormat\n rowOrder\n animeList {\n sectionOrder\n customLists\n advancedScoringEnabled\n }\n mangaList {\n sectionOrder\n customLists\n advancedScoringEnabled\n }\n }\n statistics {\n anime {\n count\n meanScore\n minutesWatched\n episodesWatched\n }\n manga {\n count\n meanScore\n chaptersRead\n volumesRead\n }\n }\n favourites {\n anime {\n nodes {\n id\n title {\n romaji\n english\n }\n siteUrl\n }\n }\n manga {\n nodes {\n id\n title {\n romaji\n english\n }\n siteUrl\n }\n }\n characters {\n nodes {\n id\n name {\n full\n }\n image {\n large\n }\n }\n }\n staff {\n nodes {\n id\n name {\n full\n }\n image {\n large\n }\n }\n }\n studios {\n nodes {\n id\n name\n siteUrl\n }\n }\n }\n isFollower\n isFollowing\n }\n}`;\n\n// src/providers.ts\nvar defineProviders = (providers) => providers;\nvar providers = defineProviders({\n \"42\": {\n authorizationUrl: \"https://api.intra.42.fr/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.intra.42.fr/v2/me\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.intra.42.fr/oauth/token\"\n }\n },\n amazoncognito: {\n authorizationUrl: \"https://${domain}/oauth2/authorize\",\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `https://${config.domain}/oauth2/userInfo`\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: (config) => `https://${config.domain}/oauth2/revoke`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `https://${config.domain}/oauth2/token`\n }\n },\n anilist: {\n authorizationUrl: \"https://anilist.co/api/v2/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n body: {\n query: anilistProfileQuery\n },\n encoding: \"application/json\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n method: \"POST\",\n url: \"https://graphql.anilist.co\"\n },\n scopeRequired: false,\n subject: [\"data\", \"Viewer\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://anilist.co/api/v2/oauth/token\"\n }\n },\n apple: {\n authorizationUrl: \"https://appleid.apple.com/auth/authorize\",\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://appleid.apple.com/auth/userinfo\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://appleid.apple.com/auth/token\"\n }\n },\n atlassian: {\n authorizationUrl: \"https://auth.atlassian.com/authorize\",\n createAuthorizationURLSearchParams: {\n audience: \"api.atlassian.com\"\n },\n email: [\"email\"],\n fullName: [\"name\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"picture\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.atlassian.com/me\"\n },\n scopeRequired: true,\n subject: [\"account_id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://auth.atlassian.com/oauth/token\"\n }\n },\n attio: {\n authorizationUrl: \"https://app.attio.com/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.attio.com/v2/self\"\n },\n scopeRequired: true,\n subject: [\"workspace_id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://app.attio.com/oauth/token\"\n }\n },\n auth0: {\n authorizationUrl: (config) => `https://${config.domain}/authorize`,\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `https://${config.domain}/userinfo`\n },\n revocationRequest: {\n authIn: \"body\",\n body: new URLSearchParams({\n token_type_hint: \"refresh_token\"\n }),\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: (config) => `https://${config.domain}/oauth/revoke`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `https://${config.domain}/oauth/token`\n }\n },\n authentik: {\n authorizationUrl: (config) => `https://${config.baseURL}/oauth/authorize`,\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `https://${config.baseURL}/api/v3/user/`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `https://${config.baseURL}/oauth/token`\n }\n },\n autodesk: {\n authorizationUrl: \"https://developer.api.autodesk.com/authentication/v2/authorize\",\n email: [\"email\"],\n familyName: [\"family_name\"],\n fullName: [\"name\"],\n givenName: [\"given_name\"],\n isOIDC: true,\n isRefreshable: true,\n picture: [\"picture\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.userprofile.autodesk.com/userinfo\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://developer.api.autodesk.com/authentication/v2/token\"\n }\n },\n battlenet: {\n authorizationUrl: \"https://oauth.battle.net/authorize\",\n isOIDC: true,\n isRefreshable: false,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://oauth.battle.net/userinfo\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://oauth.battle.net/token\"\n }\n },\n bitbucket: {\n authorizationUrl: \"https://bitbucket.org/site/oauth2/authorize\",\n fullName: [\"display_name\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"links\", \"avatar\", \"href\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.bitbucket.org/2.0/user\"\n },\n scopeRequired: false,\n subject: [\"uuid\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://bitbucket.org/site/oauth2/access_token\"\n }\n },\n box: {\n authorizationUrl: \"https://account.box.com/api/oauth2/authorize\",\n email: [\"login\"],\n fullName: [\"name\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"avatar_url\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.box.com/2.0/users/me\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: \"https://api.box.com/oauth2/revoke\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.box.com/oauth2/token\"\n }\n },\n bungie: {\n authorizationUrl: \"https://www.bungie.net/en/OAuth/Authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n headers: {\n \"X-API-Key\": \"<YOUR_API_KEY>\"\n },\n method: \"GET\",\n url: \"https://www.bungie.net/Platform/User/GetCurrentBungieNetUser\"\n },\n scopeRequired: false,\n subject: [\"Response\", \"membershipId\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://www.bungie.net/Platform/App/OAuth/token\"\n }\n },\n close: {\n authorizationUrl: \"https://app.close.com/oauth2/authorize/\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.close.com/api/v1/me/\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.close.com/oauth2/token/\"\n }\n },\n coinbase: {\n authorizationUrl: \"https://www.coinbase.com/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.coinbase.com/v2/user\"\n },\n scopeRequired: false,\n subject: [\"data\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.coinbase.com/oauth/token\"\n }\n },\n discord: {\n authorizationUrl: \"https://discord.com/api/oauth2/authorize\",\n email: [\"email\"],\n isOIDC: true,\n isRefreshable: true,\n picture: [\"avatar\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://discord.com/api/users/@me\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://discord.com/api/oauth2/token\"\n }\n },\n donationalerts: {\n authorizationUrl: \"https://www.donationalerts.com/oauth/authorize\",\n email: [\"data\", \"email\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"data\", \"avatar\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://www.donationalerts.com/api/v1/user/oauth\"\n },\n scopeRequired: false,\n subject: [\"data\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://www.donationalerts.com/oauth/token\"\n }\n },\n dribbble: {\n authorizationUrl: \"https://dribbble.com/oauth/authorize\",\n isOIDC: false,\n isRefreshable: false,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.dribbble.com/v2/user\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://dribbble.com/oauth/token\"\n }\n },\n dropbox: {\n authorizationUrl: \"https://www.dropbox.com/oauth2/authorize\",\n email: [\"email\"],\n familyName: [\"name\", \"surname\"],\n fullName: [\"name\", \"display_name\"],\n givenName: [\"name\", \"given_name\"],\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"POST\",\n url: \"https://api.dropboxapi.com/2/users/get_current_account\"\n },\n revocationRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n url: \"https://api.dropboxapi.com/2/auth/token/revoke\"\n },\n scopeRequired: false,\n subject: [\"account_id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.dropboxapi.com/oauth2/token\"\n }\n },\n epicgames: {\n authorizationUrl: \"https://www.epicgames.com/id/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.epicgames.dev/epic/oauth/v2/userInfo\"\n },\n scopeRequired: false,\n subject: [\"account_id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.epicgames.dev/epic/oauth/v1/token\"\n }\n },\n etsy: {\n authorizationUrl: \"https://www.etsy.com/oauth/connect\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://openapi.etsy.com/v3/application/users/me\"\n },\n scopeRequired: false,\n subject: [\"results\", \"0\", \"user_id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.etsy.com/v3/public/oauth/token\"\n }\n },\n facebook: {\n authorizationUrl: \"https://www.facebook.com/v16.0/dialog/oauth\",\n email: [\"email\"],\n familyName: [\"family_name\"],\n fullName: [\"name\"],\n givenName: [\"given_name\"],\n isOIDC: true,\n isRefreshable: false,\n picture: [\"picture\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"query\",\n encoding: \"application/json\",\n method: \"GET\",\n searchParams: [[\"fields\", \"id,name,email,picture\"]],\n url: \"https://graph.facebook.com/me\"\n },\n scopeRequired: false,\n subject: [\"sub\"],\n subjectBySource: {\n idToken: [\"sub\"],\n profile: [\"id\"]\n },\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://graph.facebook.com/v16.0/oauth/access_token\"\n }\n },\n figma: {\n authorizationUrl: \"https://www.figma.com/oauth\",\n email: [\"email\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"img_url\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.figma.com/v1/me\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.figma.com/v1/oauth/token\"\n }\n },\n gitea: {\n authorizationUrl: (config) => `${config.baseURL}/login/oauth/authorize`,\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `${config.baseURL}/api/v1/user`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `${config.baseURL}/login/oauth/access_token`\n }\n },\n github: {\n authorizationUrl: \"https://github.com/login/oauth/authorize\",\n email: [\"email\"],\n isOIDC: false,\n isRefreshable: false,\n picture: [\"avatar_url\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.github.com/user\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://github.com/login/oauth/access_token\"\n }\n },\n gitlab: {\n authorizationUrl: (config) => `${config.baseURL}/oauth/authorize`,\n email: [\"email\"],\n fullName: [\"name\"],\n isOIDC: true,\n isRefreshable: true,\n picture: [\"picture\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://gitlab.com/api/v4/user\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: (config) => `${config.baseURL}/oauth/revoke`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `${config.baseURL}/oauth/token`\n }\n },\n gohighlevel: {\n authorizationUrl: \"https://marketplace.gohighlevel.com/oauth/chooselocation\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://services.leadconnectorhq.com/users/me\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://services.leadconnectorhq.com/oauth/token\"\n }\n },\n google: {\n authorizationUrl: \"https://accounts.google.com/o/oauth2/v2/auth\",\n email: [\"email\"],\n familyName: [\"family_name\"],\n fullName: [\"name\"],\n givenName: [\"given_name\"],\n isOIDC: true,\n isRefreshable: true,\n picture: [\"picture\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://openidconnect.googleapis.com/v1/userinfo\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: \"https://oauth2.googleapis.com/revoke\"\n },\n scopeRequired: true,\n subject: [\"sub\"],\n subjectBySource: {\n idToken: [\"sub\"],\n profile: [\"sub\"]\n },\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://oauth2.googleapis.com/token\"\n }\n },\n hubspot: {\n authorizationUrl: \"https://app.hubspot.com/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.hubapi.com/oauth/v1/access-tokens/me\"\n },\n scopeRequired: true,\n subject: [\"hub_id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.hubapi.com/oauth/v1/token\"\n }\n },\n intuit: {\n authorizationUrl: \"https://appcenter.intuit.com/connect/oauth2\",\n isOIDC: true,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => config.environment === \"production\" ? \"https://accounts.platform.intuit.com/v1/openid_connect/userinfo\" : \"https://sandbox-accounts.platform.intuit.com/v1/openid_connect/userinfo\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n headers: (config) => ({\n Authorization: `Basic ${encodeBase64(`${config.clientId}:${config.clientSecret}`)}`\n }),\n tokenParamName: \"token\",\n url: \"https://developer.api.intuit.com/v2/oauth2/tokens/revoke\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer\"\n }\n },\n kakao: {\n authorizationUrl: \"https://kauth.kakao.com/oauth/authorize\",\n isOIDC: true,\n isRefreshable: true,\n picture: [\"picture\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://kapi.kakao.com/v2/user/me\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://kauth.kakao.com/oauth/token\"\n }\n },\n keycloak: {\n authorizationUrl: (config) => `${config.realmURL}/protocol/openid-connect/auth`,\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.kick.com/v1/user\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: (config) => `${config.realmURL}/protocol/openid-connect/revoke`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `${config.realmURL}/protocol/openid-connect/token`\n }\n },\n kick: {\n authorizationUrl: \"https://id.kick.com/oauth/authorize\",\n email: [\"data\", \"email\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"data\", \"profile_picture\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.kick.com/public/v1/users\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: \"https://id.kick.com/oauth/revoke\"\n },\n scopeRequired: true,\n subject: [\"data\", \"user_id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://id.kick.com/oauth/token\"\n }\n },\n lichess: {\n authorizationUrl: \"https://lichess.org/oauth/authorize\",\n isOIDC: false,\n isRefreshable: false,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://lichess.org/api/account\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://lichess.org/api/token\"\n }\n },\n line: {\n authorizationUrl: \"https://access.line.me/oauth2/v2.1/authorize\",\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.line.me/v2/profile\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.line.me/oauth2/v2.1/token\"\n }\n },\n linear: {\n authorizationUrl: \"https://linear.app/oauth/authorize\",\n isOIDC: false,\n isRefreshable: false,\n profileRequest: {\n authIn: \"header\",\n body: {\n query: `query { viewer { id name } }`\n },\n encoding: \"application/json\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n method: \"POST\",\n url: \"https://api.linear.app/graphql\"\n },\n revocationRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n url: \"https://api.linear.app/oauth/revoke\"\n },\n scopeRequired: false,\n subject: [\"data\", \"viewer\", \"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.linear.app/oauth/token\"\n }\n },\n linkedin: {\n authorizationUrl: \"https://www.linkedin.com/oauth/v2/authorization\",\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.linkedin.com/v2/me\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://www.linkedin.com/oauth/v2/accessToken\"\n }\n },\n mastodon: {\n authorizationUrl: (config) => `${config.baseURL}/oauth/authorize`,\n isOIDC: false,\n isRefreshable: false,\n picture: [\"avatar\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `${config.baseURL}/api/v1/accounts/verify_credentials`\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: (config) => `${config.baseURL}/oauth/revoke`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `${config.baseURL}/oauth/token`\n }\n },\n mercadolibre: {\n authorizationUrl: \"https://auth.mercadolibre.com/authorization\",\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.mercadolibre.com/users/me\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.mercadolibre.com/oauth/token\"\n }\n },\n mercadopago: {\n authorizationUrl: \"https://auth.mercadopago.com/authorization\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.mercadopago.com/v1/users/me\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.mercadopago.com/oauth/token\"\n }\n },\n microsoftentraid: {\n authorizationUrl: (config) => `https://${config.tenantId}.b2clogin.com/${config.tenantId}/oauth2/v2.0/authorize`,\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `https://${config.tenantId}.b2clogin.com/${config.tenantId}/openid/userinfo`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `https://${config.tenantId}.b2clogin.com/${config.tenantId}/oauth2/v2.0/token`\n }\n },\n monday: {\n authorizationUrl: \"https://auth.monday.com/oauth2/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n body: {\n query: \"query { me { id name email } }\"\n },\n encoding: \"application/json\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n method: \"POST\",\n url: \"https://api.monday.com/v2\"\n },\n scopeRequired: true,\n subject: [\"data\", \"me\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://auth.monday.com/oauth2/token\"\n }\n },\n myanimelist: {\n authorizationUrl: \"https://myanimelist.net/v1/oauth2/authorize\",\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"plain\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.myanimelist.net/v2/users/@me\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://myanimelist.net/v1/oauth2/token\"\n }\n },\n naver: {\n authorizationUrl: \"https://nid.naver.com/oauth2.0/authorize\",\n email: [\"response\", \"email\"],\n fullName: [\"response\", \"name\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"response\", \"profile_image\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://openapi.naver.com/v1/nid/me\"\n },\n scopeRequired: false,\n subject: [\"response\", \"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://nid.naver.com/oauth2.0/token\"\n }\n },\n notion: {\n authorizationUrl: \"https://api.notion.com/v1/oauth/authorize\",\n email: [\"bot\", \"owner\", \"user\", \"person\", \"email\"],\n isOIDC: false,\n isRefreshable: false,\n picture: [\"bot\", \"owner\", \"user\", \"avatar_url\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n headers: {\n \"Notion-Version\": \"2022-06-28\"\n },\n method: \"GET\",\n url: \"https://api.notion.com/v1/users/me\"\n },\n scopeRequired: false,\n subject: [\"bot\", \"owner\", \"user\", \"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n url: \"https://api.notion.com/v1/oauth/token\"\n }\n },\n okta: {\n authorizationUrl: (config) => `https://${config.domain}/oauth2/default/v1/authorize`,\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `https://${config.domain}/oauth2/default/v1/userinfo`\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: (config) => `https://${config.domain}/oauth2/default/v1/revoke`\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `https://${config.domain}/oauth2/default/v1/token`\n }\n },\n osu: {\n authorizationUrl: \"https://osu.ppy.sh/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n picture: [\"avatar_url\"],\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://osu.ppy.sh/api/v2/me\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://osu.ppy.sh/oauth/token\"\n }\n },\n patreon: {\n authorizationUrl: \"https://www.patreon.com/oauth2/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://www.patreon.com/api/oauth2/v2/identity\"\n },\n scopeRequired: false,\n subject: [\"data\", \"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://www.patreon.com/api/oauth2/token\"\n }\n },\n pipedrive: {\n authorizationUrl: \"https://oauth.pipedrive.com/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.pipedrive.com/v1/users/me\"\n },\n scopeRequired: true,\n subject: [\"data\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://oauth.pipedrive.com/oauth/token\"\n }\n },\n polar: {\n authorizationUrl: \"https://polar.sh/oauth2/authorize\",\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.polar.sh/v1/oauth2/userinfo\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: \"https://api.polar.sh/v1/oauth2/revoke\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.polar.sh/v1/oauth2/token\"\n }\n },\n polaraccesslink: {\n authorizationUrl: \"https://flow.polar.com/oauth2/authorization\",\n isOIDC: false,\n isRefreshable: false,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://www.polaraccesslink.com/v3/users/me\"\n },\n scopeRequired: false,\n subject: [\"x_user_id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"header\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://polarremote.com/v2/oauth2/token\"\n }\n },\n polarteampro: {\n authorizationUrl: \"https://auth.polar.com/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://www.polaraccesslink.com/v3/users/<USER_ID>\"\n },\n scopeRequired: false,\n subject: [\"x_user_id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"header\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://auth.polar.com/oauth/token\"\n }\n },\n reddit: {\n authorizationUrl: \"https://www.reddit.com/api/v1/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://oauth.reddit.com/api/v1/me\"\n },\n revocationRequest: {\n authIn: \"header\",\n body: new URLSearchParams({\n token_type_hint: \"refresh_token\"\n }),\n encoding: \"application/json\",\n url: \"https://www.reddit.com/api/v1/revoke_token\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"header\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://www.reddit.com/api/v1/access_token\"\n }\n },\n roblox: {\n authorizationUrl: \"https://apis.roblox.com/oauth/v1/authorize\",\n isOIDC: true,\n isRefreshable: true,\n picture: [\"picture\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://apis.roblox.com/oauth/v1/userinfo\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://apis.roblox.com/oauth/v1/token\"\n }\n },\n salesforce: {\n authorizationUrl: \"https://login.salesforce.com/services/oauth2/authorize\",\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://login.salesforce.com/services/oauth2/userinfo\"\n },\n revocationRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n url: \"https://login.salesforce.com/services/oauth2/revoke\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://login.salesforce.com/services/oauth2/token\"\n }\n },\n shikimori: {\n authorizationUrl: \"https://shikimori.org/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://shikimori.one/api/users/whoami\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://shikimori.org/oauth/token\"\n }\n },\n slack: {\n authorizationUrl: \"https://slack.com/openid/connect/authorize\",\n isOIDC: true,\n isRefreshable: true,\n profileRequest: {\n authIn: \"query\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://slack.com/api/users.identity\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: \"https://slack.com/api/auth.revoke\"\n },\n scopeRequired: true,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://slack.com/api/openid.connect.token\"\n }\n },\n spotify: {\n authorizationUrl: \"https://accounts.spotify.com/authorize\",\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.spotify.com/v1/me\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://accounts.spotify.com/api/token\"\n }\n },\n startgg: {\n authorizationUrl: \"https://start.gg/oauth/authorize\",\n email: [\"data\", \"currentUser\", \"email\"],\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n body: {\n query: `query { currentUser { id slug email player { gamerTag } } }`\n },\n encoding: \"application/json\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\"\n },\n method: \"POST\",\n url: \"https://api.start.gg/gql/alpha\"\n },\n scopeRequired: false,\n subject: [\"data\", \"currentUser\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.start.gg/oauth/access_token\"\n }\n },\n strava: {\n authorizationUrl: \"https://www.strava.com/oauth/authorize\",\n familyName: [\"lastname\"],\n givenName: [\"firstname\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"profile\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://www.strava.com/api/v3/athlete\"\n },\n revocationRequest: {\n authIn: \"query\",\n body: new URLSearchParams({\n token_type_hint: \"access_token\"\n }),\n encoding: \"application/json\",\n tokenParamName: \"access_token\",\n url: \"https://www.strava.com/oauth/deauthorize\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://www.strava.com/oauth/token\"\n }\n },\n synology: {\n authorizationUrl: (config) => `${config.baseURL}/webman/sso/SSOOauth.cgi?client_id=${config.clientId}&response_type=code&redirect_uri=${config.redirectUri}`,\n isOIDC: false,\n isRefreshable: false,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `${config.baseURL}/webman/sso/SSOUserInfo.cgi?client_id=${config.clientId}&access_token=${config.accessToken}`\n },\n scopeRequired: false,\n subject: [\"data\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `${config.baseURL}/webman/sso/SSOAccessToken.cgi?client_id=${config.clientId}&client_secret=${config.clientSecret}`\n }\n },\n tiktok: {\n authorizationUrl: \"https://www.tiktok.com/v2/auth/authorize\",\n createAuthorizationURLSearchParams: (config) => ({\n client_key: config.clientId\n }),\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"query\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://open.douyin.com/oauth/userinfo\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"token\",\n url: \"https://open.tiktokapis.com/v2/oauth/revoke/\"\n },\n scopeRequired: false,\n subject: [\"data\", \"open_id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://open.tiktokapis.com/v2/oauth/token/\"\n }\n },\n tiltify: {\n authorizationUrl: \"https://v5api.tiltify.com/oauth/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://v5api.tiltify.com/api/public/current-user\"\n },\n scopeRequired: false,\n subject: [\"data\", \"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://v5api.tiltify.com/oauth/token\"\n }\n },\n tumblr: {\n authorizationUrl: \"https://www.tumblr.com/oauth2/authorize\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.tumblr.com/v2/user/info\"\n },\n scopeRequired: false,\n subject: [\"response\", \"user\", \"name\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.tumblr.com/v2/oauth2/token\"\n }\n },\n twitch: {\n authorizationUrl: \"https://id.twitch.tv/oauth2/authorize\",\n isOIDC: true,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n headers: (config) => ({\n \"Client-Id\": config.clientId\n }),\n method: \"GET\",\n url: \"https://api.twitch.tv/helix/users\"\n },\n revocationRequest: {\n authIn: \"query\",\n encoding: \"application/json\",\n headers: (config) => ({\n \"Client-Id\": config.clientId\n }),\n tokenParamName: \"token\",\n url: \"https://id.twitch.tv/oauth2/revoke\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://id.twitch.tv/oauth2/token\"\n }\n },\n twitter: {\n authorizationUrl: \"https://twitter.com/i/oauth2/authorize\",\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.twitter.com/2/users/me\"\n },\n revocationRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n url: \"https://api.twitter.com/2/oauth2/revoke\"\n },\n scopeRequired: false,\n subject: [\"data\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.twitter.com/2/oauth2/token\"\n }\n },\n vk: {\n authorizationUrl: \"https://oauth.vk.com/authorize\",\n isOIDC: false,\n isRefreshable: false,\n profileRequest: {\n authIn: \"query\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.vk.com/method/users.get\"\n },\n scopeRequired: false,\n subject: [\"response\", \"0\", \"id\"],\n subjectType: \"number\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://oauth.vk.com/access_token\"\n }\n },\n withings: {\n authorizationUrl: \"https://account.withings.com/oauth2_user/authorize2\",\n isOIDC: false,\n isRefreshable: true,\n profileRequest: {\n authIn: \"header\",\n body: async (config) => {\n const props = await getWithingsProps(config);\n if (props === undefined)\n throw new Error(\"Failed to get Withings search properties\");\n const { nonce, hashedSignature } = props;\n return [\n [\"action\", \"getuser\"],\n [\"nonce\", nonce],\n [\"client_id\", config.clientId],\n [\"signature\", hashedSignature]\n ];\n },\n encoding: \"application/x-www-form-urlencoded\",\n method: \"POST\",\n url: \"https://wbsapi.withings.net/v2/oauth2\"\n },\n refreshAccessTokenBody: {\n action: \"requesttoken\"\n },\n revocationRequest: {\n authIn: \"header\",\n body: async (config) => {\n const props = await getWithingsProps(config);\n if (!props)\n throw new Error(\"Failed to get Withings props\");\n const { nonce, hashedSignature } = props;\n return [\n [\"action\", \"revoke\"],\n [\"client_id\", config.clientId],\n [\"nonce\", nonce],\n [\"signature\", hashedSignature]\n ];\n },\n encoding: \"application/x-www-form-urlencoded\",\n method: \"POST\",\n url: \"https://wbsapi.withings.net/v2/oauth2\"\n },\n scopeRequired: true,\n subject: [\"userid\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://wbsapi.withings.net/v2/oauth2\"\n },\n validateAuthorizationCodeBody: {\n action: \"requesttoken\"\n }\n },\n workos: {\n authorizationUrl: (config) => `https://${config.domain}/oauth2/authorize`,\n createAuthorizationURLSearchParams: () => {\n const nonce = crypto.randomUUID();\n return {\n nonce\n };\n },\n email: [\"email\"],\n familyName: [\"family_name\"],\n fullName: [\"name\"],\n givenName: [\"given_name\"],\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"POST\",\n url: (config) => `https://${config.domain}/oauth2/userinfo`\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `https://${config.domain}/oauth2/token`\n }\n },\n yahoo: {\n authorizationUrl: \"https://api.login.yahoo.com/oauth2/request_auth\",\n isOIDC: true,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.login.yahoo.com/openid/v1/userinfo\"\n },\n revocationRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n url: \"https://api.login.yahoo.com/oauth2/revoke\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://api.login.yahoo.com/oauth2/get_token\"\n }\n },\n yandex: {\n authorizationUrl: \"https://oauth.yandex.com/authorize\",\n createAuthorizationURLSearchParams: {\n device_id: crypto.randomUUID(),\n device_name: `${navigator.platform ?? \"Unknown\"} \\u2014 ${(navigator.userAgent.split(\")\")[0] || \"\").split(\"(\").pop() || \"Unknown\"}`\n },\n email: [\"default_email\"],\n familyName: [\"last_name\"],\n fullName: [\"real_name\"],\n givenName: [\"first_name\"],\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://login.yandex.ru/info\"\n },\n revocationRequest: {\n authIn: \"body\",\n encoding: \"application/json\",\n tokenParamName: \"access_token\",\n url: \"https://oauth.yandex.com/revoke_token\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://oauth.yandex.com/token\"\n }\n },\n zoho: {\n authorizationUrl: (config) => `https://accounts.zoho.${config.region ?? \"com\"}/oauth/v2/auth`,\n isOIDC: false,\n isRefreshable: true,\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: (config) => `https://accounts.zoho.${config.region ?? \"com\"}/oauth/user/info`\n },\n revocationRequest: {\n authIn: \"query\",\n encoding: \"application/x-www-form-urlencoded\",\n tokenParamName: \"token\",\n url: (config) => `https://accounts.zoho.${config.region ?? \"com\"}/oauth/v2/token/revoke`\n },\n scopeRequired: true,\n subject: [\"ZUID\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: (config) => `https://accounts.zoho.${config.region ?? \"com\"}/oauth/v2/token`\n }\n },\n zoom: {\n authorizationUrl: \"https://zoom.us/oauth/authorize\",\n email: [\"email\"],\n familyName: [\"last_name\"],\n givenName: [\"first_name\"],\n isOIDC: false,\n isRefreshable: true,\n picture: [\"pic_url\"],\n PKCEMethod: \"S256\",\n profileRequest: {\n authIn: \"header\",\n encoding: \"application/json\",\n method: \"GET\",\n url: \"https://api.zoom.us/v2/users/me\"\n },\n revocationRequest: {\n authIn: \"query\",\n encoding: \"application/json\",\n headers: (config) => ({\n Authorization: `Basic ${btoa(`${config.clientId}:${config.clientSecret}`)}`\n }),\n tokenParamName: \"token\",\n url: \"https://zoom.us/oauth/revoke\"\n },\n scopeRequired: false,\n subject: [\"id\"],\n subjectType: \"string\",\n tokenRequest: {\n authIn: \"body\",\n encoding: \"application/x-www-form-urlencoded\",\n url: \"https://zoom.us/oauth/token\"\n }\n }\n});\n\n// src/typeGuards.ts\nvar hasClientSecret = (credentials) => {\n if (typeof credentials !== \"object\" || credentials === null)\n return false;\n const secret = Reflect.get(credentials, \"clientSecret\");\n return typeof secret === \"string\";\n};\nvar isExpectedType = (value, kind) => {\n switch (kind) {\n case \"string\":\n return typeof value === \"string\";\n case \"number\":\n return typeof value === \"number\";\n case \"boolean\":\n return typeof value === \"boolean\";\n case \"object\":\n return typeof value === \"object\" && value !== null;\n default:\n return false;\n }\n};\nvar isObject = (value) => value !== null && typeof value === \"object\" && !Array.isArray(value) && Object.prototype.toString.call(value) === \"[object Object]\";\nvar isOIDCProviderOption = (option) => {\n if (!isValidProviderOption(option))\n return false;\n const provider = providers[option];\n return provider.isOIDC;\n};\nvar isPKCEProviderOption = (option) => {\n if (!isValidProviderOption(option))\n return false;\n const provider = providers[option];\n return provider.PKCEMethod !== undefined;\n};\nvar isRefreshableOAuth2Client = (providerName, _client) => isRefreshableProviderOption(providerName);\nvar isRefreshableProviderOption = (option) => {\n if (!isValidProviderOption(option))\n return false;\n const provider = providers[option];\n return provider.isRefreshable;\n};\nvar isRevocableOAuth2Client = (providerName, _client) => isRevocableProviderOption(providerName);\nvar isRevocableProviderOption = (option) => {\n if (!isValidProviderOption(option))\n return false;\n const provider = providers[option];\n return provider.revocationRequest !== undefined;\n};\nvar isScopeRequiredProviderOption = (option) => {\n if (!isValidProviderOption(option))\n return false;\n const provider = providers[option];\n return provider.scopeRequired;\n};\nvar isValidProviderOption = (option) => Object.hasOwn(providers, option);\n\n// src/utils.ts\nvar createOAuth2FetchError = async (response) => {\n const clone = response.clone();\n const prefix = `HTTP ${response.status} ${response.statusText} for ${response.url}`;\n const payload = await response.json().catch(() => null);\n if (payload && typeof payload === \"object\" && Object.keys(payload).length) {\n return new Error(`${prefix}\n${JSON.stringify(payload)}`);\n }\n const text = await clone.text().catch(() => \"\");\n if (text) {\n return new Error(`${prefix}\n${text}`);\n }\n return new Error(prefix);\n};\nvar createOAuth2Request = ({\n url,\n body,\n authIn,\n headers,\n encoding,\n clientId,\n clientSecret\n}) => {\n const oauthHeaders = new Headers(headers);\n oauthHeaders.set(\"Accept\", \"application/json\");\n oauthHeaders.set(\"User-Agent\", \"citra\");\n if (authIn === \"header\") {\n if (!clientSecret) {\n throw new Error(\"clientSecret required for header auth\");\n }\n oauthHeaders.set(\"Authorization\", `Basic ${encodeBase64(`${clientId}:${clientSecret}`)}`);\n }\n if (encoding === \"application/json\") {\n oauthHeaders.set(\"Content-Type\", \"application/json\");\n return new Request(url, {\n body: JSON.stringify(body),\n headers: oauthHeaders,\n method: \"POST\"\n });\n }\n oauthHeaders.set(\"Content-Type\", \"application/x-www-form-urlencoded\");\n const entries = body instanceof URLSearchParams ? Array.from(body.entries()) : Object.entries(body).filter((entry) => typeof entry[1] === \"string\");\n const params = new URLSearchParams(entries);\n if (authIn === \"body\") {\n params.set(\"client_id\", clientId);\n clientSecret && params.set(\"client_secret\", clientSecret);\n }\n return new Request(url, {\n body: params.toString(),\n headers: oauthHeaders,\n method: \"POST\"\n });\n};\nvar decodeBase64 = (input, toUint8Array = false) => {\n const b64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"==\".slice(0, (BASE64_BLOCK_SIZE - input.length % BASE64_BLOCK_SIZE) % BASE64_BLOCK_SIZE);\n const raw = atob(b64);\n if (!toUint8Array) {\n return raw;\n }\n const bytes = new Uint8Array(raw.length);\n for (let i = 0;i < raw.length; i++) {\n bytes[i] = raw.charCodeAt(i);\n }\n return bytes;\n};\nvar decodeJWT = (tokenString) => {\n const [headerSegment, payloadSegment, signatureSegment] = tokenString.split(\".\");\n if (!headerSegment || !payloadSegment || !signatureSegment) {\n throw new Error(\"Invalid JWT format\");\n }\n const decodedPayload = decodeBase64(payloadSegment);\n if (typeof decodedPayload !== \"string\") {\n throw new Error(\"Expected JWT payload to be a UTF-8 string\");\n }\n const claims = JSON.parse(decodedPayload);\n return claims;\n};\nvar encodeBase64 = (input) => {\n let raw;\n if (typeof input === \"string\") {\n raw = input;\n } else {\n const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);\n raw = bytes.reduce((acc, byte) => acc + String.fromCharCode(byte), \"\");\n }\n return btoa(raw);\n};\nvar getWithingsProps = async (config) => {\n const timestamp = Math.floor(Date.now() / 1000);\n const signature = `getnonce,${config.clientId},${timestamp}`;\n const hashedSignature = await hmacSha256(signature, config.clientSecret);\n const nonceUrl = new URL(\"https://wbsapi.withings.net/v2/signature\");\n nonceUrl.searchParams.set(\"action\", \"getnonce\");\n nonceUrl.searchParams.set(\"client_id\", config.clientId);\n nonceUrl.searchParams.set(\"timestamp\", timestamp.toString());\n nonceUrl.searchParams.set(\"signature\", hashedSignature);\n const nonceTarget = nonceUrl.toString();\n const nonceResponse = await fetch(nonceTarget, {\n ...h2IfHttps(nonceTarget),\n method: \"POST\"\n });\n const nonceData = await nonceResponse.json();\n if (nonceData.status === 0) {\n return {\n hashedSignature,\n nonce: nonceData.body.nonce\n };\n }\n return;\n};\nvar h2IfHttps = (url) => {\n const init = url.startsWith(\"https://\") ? { protocol: \"http2\" } : {};\n return init;\n};\nvar hmacSha256 = async (message, secret) => {\n const encoder = new TextEncoder;\n const key = await crypto.subtle.importKey(\"raw\", encoder.encode(secret), { hash: \"SHA-256\", name: \"HMAC\" }, false, [\"sign\"]);\n const sigBuffer = await crypto.subtle.sign(\"HMAC\", key, encoder.encode(message));\n return Array.from(new Uint8Array(sigBuffer)).map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n};\nvar extractPropFromIdentity = (identity, keys, propType) => {\n let value = identity;\n for (const key of keys) {\n if (Array.isArray(value))\n value = value[Number(key)];\n if (!isObject(value)) {\n throw new Error(`Invalid identity data shape: expected object, got ${typeof value}`);\n }\n value = value[key];\n }\n if (propType !== undefined && !isExpectedType(value, propType)) {\n throw new Error(`Invalid identity data shape: expected ${propType}, got ${typeof value}`);\n }\n return value;\n};\nvar getProviderSubjectKeys = (providerConfiguration, source) => providerConfiguration.subjectBySource?.[source] ?? providerConfiguration.subject;\nvar setPropInIdentity = (identity, keys, value) => {\n if (keys.length === 0) {\n return identity;\n }\n let cursor = identity;\n for (const key of keys.slice(0, -1)) {\n const next = cursor[key];\n cursor[key] = isObject(next) ? next : {};\n cursor = cursor[key];\n }\n cursor[keys[keys.length - 1]] = value;\n return identity;\n};\nvar normalizeProviderIdentity = ({\n identity,\n providerConfiguration,\n source\n}) => {\n const sourceKeys = getProviderSubjectKeys(providerConfiguration, source);\n const canonicalKeys = providerConfiguration.subject;\n if (sourceKeys.join(\".\") === canonicalKeys.join(\".\")) {\n return identity;\n }\n const subject = extractPropFromIdentity(identity, sourceKeys, providerConfiguration.subjectType);\n const normalizedIdentity = structuredClone(identity);\n return setPropInIdentity(normalizedIdentity, canonicalKeys, subject);\n};\n\n// src/arctic-utils.ts\nvar createS256CodeChallenge = async (codeVerifier) => {\n const data = new TextEncoder().encode(codeVerifier);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n return base64Url(hashBuffer);\n};\nvar createRandomBase64UrlGenerator = (length) => () => {\n const buffer = crypto.getRandomValues(new Uint8Array(length));\n return base64Url(buffer);\n};\nvar generateCodeVerifier = createRandomBase64UrlGenerator(NUM_GENERATOR_BYTES);\nvar generateState = createRandomBase64UrlGenerator(NUM_GENERATOR_BYTES);\nvar base64Url = (input) => encodeBase64(input).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n// src/oidc.ts\nvar ALG_ES256 = \"ES256\";\nvar ALG_RS256 = \"RS256\";\nvar CLOCK_SKEW_SECONDS = 60;\nvar DEFAULT_SCOPES = [\"openid\", \"email\", \"profile\"];\nvar JWKS_REFETCH_COOLDOWN_MS = 60000;\nvar JWT_SEGMENT_COUNT = 3;\nvar MILLISECONDS_PER_SECOND = 1000;\nvar trimTrailingSlash = (value) => value.endsWith(\"/\") ? value.slice(0, -1) : value;\nvar fetchJson = async (url) => {\n const response = await fetch(url, {\n headers: { accept: \"application/json\" }\n });\n if (!response.ok) {\n throw new Error(`Request to ${url} failed with status ${response.status}`);\n }\n return response.json();\n};\nvar decodeJsonSegment = (segment) => {\n const decoded = decodeBase64(segment);\n if (typeof decoded !== \"string\") {\n throw new Error(\"Expected a base64url-encoded JWT segment\");\n }\n const parsed = JSON.parse(decoded);\n if (typeof parsed !== \"object\" || parsed === null) {\n throw new Error(\"Expected a JWT segment to decode to a JSON object\");\n }\n return parsed;\n};\nvar importVerificationKey = (jwk, alg) => {\n if (alg === ALG_RS256) {\n return crypto.subtle.importKey(\"jwk\", jwk, { hash: \"SHA-256\", name: \"RSASSA-PKCS1-v1_5\" }, false, [\"verify\"]);\n }\n if (alg === ALG_ES256) {\n return crypto.subtle.importKey(\"jwk\", jwk, { name: \"ECDSA\", namedCurve: \"P-256\" }, false, [\"verify\"]);\n }\n throw new Error(`Unsupported id_token signing algorithm \"${alg}\"`);\n};\nvar verifySignature = (key, alg, signingInput, signature) => {\n const algorithm = alg === ALG_ES256 ? { hash: \"SHA-256\", name: \"ECDSA\" } : { name: \"RSASSA-PKCS1-v1_5\" };\n return crypto.subtle.verify(algorithm, key, new Uint8Array(signature), new TextEncoder().encode(signingInput));\n};\nvar selectKey = (jwks, kid) => jwks.find((jwk) => kid === undefined || jwk.kid === kid);\nvar assertClaims = (payload, expected) => {\n const aud = Reflect.get(payload, \"aud\");\n const exp = Reflect.get(payload, \"exp\");\n const iss = Reflect.get(payload, \"iss\");\n const sub = Reflect.get(payload, \"sub\");\n const audiences = Array.isArray(aud) ? aud : [aud];\n const nowSeconds = Math.floor(Date.now() / MILLISECONDS_PER_SECOND);\n if (iss !== expected.issuer) {\n throw new Error('id_token \"iss\" does not match the provider issuer');\n }\n if (typeof sub !== \"string\" || sub.length === 0) {\n throw new Error('id_token is missing \"sub\"');\n }\n if (!audiences.includes(expected.audience)) {\n throw new Error('id_token \"aud\" does not include the client id');\n }\n if (typeof exp !== \"number\" || exp + CLOCK_SKEW_SECONDS < nowSeconds) {\n throw new Error(\"id_token has expired\");\n }\n if (expected.nonce !== undefined && Reflect.get(payload, \"nonce\") !== expected.nonce) {\n throw new Error('id_token \"nonce\" does not match');\n }\n const claims = { ...payload, aud, exp, iss, sub };\n return claims;\n};\nvar verifyIdToken = async ({\n audience,\n idToken,\n issuer,\n jwks,\n nonce\n}) => {\n const segments = idToken.split(\".\");\n const [headerSegment, payloadSegment, signatureSegment] = segments;\n if (segments.length !== JWT_SEGMENT_COUNT || headerSegment === undefined || payloadSegment === undefined || signatureSegment === undefined) {\n throw new Error(\"Invalid id_token: expected three segments\");\n }\n const header = decodeJsonSegment(headerSegment);\n const alg = Reflect.get(header, \"alg\");\n const kid = Reflect.get(header, \"kid\");\n if (typeof alg !== \"string\") {\n throw new Error('id_token header is missing \"alg\"');\n }\n const jwk = selectKey(jwks, typeof kid === \"string\" ? kid : undefined);\n if (jwk === undefined) {\n throw new Error('No JWKS key matches the id_token \"kid\"');\n }\n const key = await importVerificationKey(jwk, alg);\n const signature = decodeBase64(signatureSegment, true);\n if (typeof signature === \"string\") {\n throw new Error(\"Failed to decode the id_token signature\");\n }\n const isValid = await verifySignature(key, alg, `${headerSegment}.${payloadSegment}`, signature);\n if (!isValid) {\n throw new Error(\"id_token signature verification failed\");\n }\n return assertClaims(decodeJsonSegment(payloadSegment), {\n audience,\n issuer,\n nonce\n });\n};\nvar toDiscoveryDocument = (value, expectedIssuer) => {\n if (typeof value !== \"object\" || value === null) {\n throw new Error(\"OIDC discovery document is not a JSON object\");\n }\n const issuer = Reflect.get(value, \"issuer\");\n const authorizationEndpoint = Reflect.get(value, \"authorization_endpoint\");\n const tokenEndpoint = Reflect.get(value, \"token_endpoint\");\n const jwksUri = Reflect.get(value, \"jwks_uri\");\n const userinfoEndpoint = Reflect.get(value, \"userinfo_endpoint\");\n if (typeof issuer !== \"string\" || typeof authorizationEndpoint !== \"string\" || typeof tokenEndpoint !== \"string\" || typeof jwksUri !== \"string\") {\n throw new Error(\"OIDC discovery document is missing required endpoints\");\n }\n if (trimTrailingSlash(issuer) !== trimTrailingSlash(expectedIssuer)) {\n throw new Error(`OIDC discovery issuer \"${issuer}\" does not match configured issuer \"${expectedIssuer}\"`);\n }\n return {\n authorization_endpoint: authorizationEndpoint,\n issuer,\n jwks_uri: jwksUri,\n token_endpoint: tokenEndpoint,\n userinfo_endpoint: typeof userinfoEndpoint === \"string\" ? userinfoEndpoint : undefined\n };\n};\nvar fetchDiscoveryDocument = async (issuer) => {\n const base = trimTrailingSlash(issuer);\n const document = await fetchJson(`${base}/.well-known/openid-configuration`);\n return toDiscoveryDocument(document, issuer);\n};\nvar fetchJwks = async (jwksUri) => {\n const body = await fetchJson(jwksUri);\n const value = Reflect.get(body ?? {}, \"keys\");\n if (!Array.isArray(value)) {\n throw new Error('JWKS response is missing a \"keys\" array');\n }\n const keys = value;\n return keys;\n};\nvar createOIDCClient = async (config) => {\n const discovery = await fetchDiscoveryDocument(config.issuer);\n const scopes = config.scopes !== undefined && config.scopes.length > 0 ? config.scopes : DEFAULT_SCOPES;\n let cachedJwks;\n let jwksFetchedAtMs = 0;\n const resolveJwks = async (forceRefresh) => {\n const isStale = Date.now() - jwksFetchedAtMs > JWKS_REFETCH_COOLDOWN_MS;\n if (cachedJwks === undefined || forceRefresh && isStale) {\n cachedJwks = await fetchJwks(discovery.jwks_uri);\n jwksFetchedAtMs = Date.now();\n }\n return cachedJwks;\n };\n const createAuthorizationUrl = async (options) => {\n const url = new URL(discovery.authorization_endpoint);\n const challenge = await createS256CodeChallenge(options.codeVerifier);\n const { searchParams } = url;\n searchParams.set(\"client_id\", config.clientId);\n searchParams.set(\"code_challenge\", challenge);\n searchParams.set(\"code_challenge_method\", \"S256\");\n searchParams.set(\"redirect_uri\", config.redirectUri);\n searchParams.set(\"response_type\", \"code\");\n searchParams.set(\"scope\", (options.scope ?? scopes).join(\" \"));\n searchParams.set(\"state\", options.state);\n if (options.nonce !== undefined) {\n searchParams.set(\"nonce\", options.nonce);\n }\n return url;\n };\n const validateAuthorizationCode = async (options) => {\n const body = new URLSearchParams;\n body.set(\"client_id\", config.clientId);\n body.set(\"client_secret\", config.clientSecret);\n body.set(\"code\", options.code);\n body.set(\"code_verifier\", options.codeVerifier);\n body.set(\"grant_type\", \"authorization_code\");\n body.set(\"redirect_uri\", config.redirectUri);\n const response = await fetch(discovery.token_endpoint, {\n body,\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/x-www-form-urlencoded\"\n },\n method: \"POST\"\n });\n if (!response.ok) {\n throw new Error(`OIDC token request failed with status ${response.status}`);\n }\n const tokens = await response.json();\n return tokens;\n };\n const verifyToken = async (idToken, options) => {\n const jwks = await resolveJwks(false);\n const params = {\n audience: config.clientId,\n idToken,\n issuer: discovery.issuer,\n nonce: options?.nonce\n };\n try {\n return await verifyIdToken({ ...params, jwks });\n } catch (error) {\n const refreshed = await resolveJwks(true);\n if (refreshed === jwks)\n throw error;\n return verifyIdToken({ ...params, jwks: refreshed });\n }\n };\n const fetchUserProfile = async (accessToken) => {\n if (discovery.userinfo_endpoint === undefined) {\n throw new Error(\"OIDC provider does not expose a userinfo endpoint\");\n }\n const response = await fetch(discovery.userinfo_endpoint, {\n headers: {\n accept: \"application/json\",\n authorization: `Bearer ${accessToken}`\n }\n });\n if (!response.ok) {\n throw new Error(`OIDC userinfo request failed with status ${response.status}`);\n }\n const profile = await response.json();\n return profile;\n };\n return {\n createAuthorizationUrl,\n discovery,\n fetchUserProfile,\n validateAuthorizationCode,\n verifyIdToken: verifyToken\n };\n};\n// src/providerOptions.ts\nvar oidcProviderOptions = Object.keys(providers).filter(isOIDCProviderOption);\nvar pkceProviderOptions = Object.keys(providers).filter(isPKCEProviderOption);\nvar providerOptions = Object.keys(providers).filter(isValidProviderOption);\nvar refreshableProviderOptions = Object.keys(providers).filter(isRefreshableProviderOption);\nvar revocableProviderOptions = Object.keys(providers).filter(isRevocableProviderOption);\nvar scopeRequiredProviderOptions = Object.keys(providers).filter(isScopeRequiredProviderOption);\n\n// src/index.ts\nvar createOAuth2Client = async (providerName, config) => {\n const meta = providers[providerName];\n const isConfigPropertyFunction = (cfgProp) => typeof cfgProp === \"function\";\n const resolveConfigProp = async (cfgProp) => {\n const result = isConfigPropertyFunction(cfgProp) ? cfgProp(config) : cfgProp;\n return result;\n };\n const authorizationUrl = await resolveConfigProp(meta.authorizationUrl);\n const tokenUrl = await resolveConfigProp(meta.tokenRequest.url);\n return {\n async createAuthorizationUrl(opts) {\n const { state, scope = [], searchParams = [], codeVerifier } = opts;\n const url = new URL(authorizationUrl);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"client_id\", config.clientId);\n if (config.redirectUri)\n url.searchParams.set(\"redirect_uri\", config.redirectUri);\n if (state)\n url.searchParams.set(\"state\", state);\n if (scope.length !== 0) {\n const delimeter = providerName === \"withings\" ? \",\" : \" \";\n url.searchParams.set(\"scope\", scope.join(delimeter));\n }\n if (meta.PKCEMethod !== undefined) {\n if (!codeVerifier) {\n throw new Error(\"`codeVerifier` is required when PKCE is enabled\");\n }\n const codeChallenge = meta.PKCEMethod === \"S256\" ? await createS256CodeChallenge(codeVerifier) : codeVerifier;\n url.searchParams.set(\"code_challenge_method\", meta.PKCEMethod);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n }\n Object.entries(resolveConfigProp(meta.createAuthorizationURLSearchParams) ?? {}).forEach(([key, value]) => url.searchParams.set(key, value));\n searchParams.forEach(([key, value]) => url.searchParams.set(key, value));\n return url;\n },\n async fetchUserProfile(accessToken) {\n const { profileRequest } = meta;\n const {\n url,\n method,\n authIn,\n searchParams,\n body: profileBody,\n headers,\n encoding\n } = profileRequest;\n const endpoint = new URL(await resolveConfigProp(url));\n const resolvedBody = await resolveConfigProp(profileBody);\n new URLSearchParams(await resolveConfigProp(searchParams)).forEach((value, key) => endpoint.searchParams.append(key, value));\n let headerEntries = [];\n const rawHeaders = headers ? await resolveConfigProp(headers) : undefined;\n if (rawHeaders instanceof Headers)\n headerEntries = Array.from(rawHeaders.entries());\n else if (Array.isArray(rawHeaders))\n headerEntries = rawHeaders;\n else if (rawHeaders && typeof rawHeaders === \"object\")\n headerEntries = Object.entries(rawHeaders);\n const profileHeaders = Object.fromEntries(headerEntries.filter(([, value]) => value !== \"\"));\n if (authIn === \"header\") {\n profileHeaders.Authorization = `Bearer ${accessToken}`;\n } else {\n endpoint.searchParams.append(\"access_token\", accessToken);\n }\n const init = { headers: profileHeaders, method };\n if (method === \"POST\" && resolvedBody !== undefined) {\n profileHeaders[\"Content-Type\"] = encoding;\n init.body = encoding === \"application/json\" ? JSON.stringify(resolvedBody) : new URLSearchParams(resolvedBody).toString();\n }\n const profileTarget = endpoint.toString();\n const response = await fetch(profileTarget, {\n ...h2IfHttps(profileTarget),\n ...init\n });\n if (!response.ok)\n throw await createOAuth2FetchError(response);\n return response.json();\n },\n async refreshAccessToken(refreshToken) {\n const { authIn, encoding } = meta.tokenRequest;\n const params = new URLSearchParams(meta.refreshAccessTokenBody);\n params.set(\"grant_type\", \"refresh_token\");\n params.set(\"refresh_token\", refreshToken);\n const { clientId } = config;\n let clientSecretValue;\n if (hasClientSecret(config)) {\n clientSecretValue = config.clientSecret;\n params.set(\"client_id\", clientId);\n params.set(\"client_secret\", clientSecretValue);\n }\n const request = createOAuth2Request({\n authIn,\n body: params,\n clientId,\n clientSecret: clientSecretValue,\n encoding,\n url: tokenUrl\n });\n const response = await fetch(request, {\n ...h2IfHttps(request.url)\n });\n if (!response.ok)\n throw await createOAuth2FetchError(response);\n return response.json();\n },\n async revokeToken(token) {\n const { revocationRequest } = meta;\n if (!revocationRequest) {\n throw new Error(\"Token revocation not defined for this provider\");\n }\n const { url, authIn, body, headers, tokenParamName } = revocationRequest;\n const endpoint = await resolveConfigProp(url);\n const resolvedBody = await resolveConfigProp(body);\n const revocationBody = new URLSearchParams(resolvedBody);\n const revocationHeaders = new Headers(headers && await resolveConfigProp(headers));\n const { clientId } = config;\n const clientSecret = hasClientSecret(config) ? config.clientSecret : undefined;\n let request;\n if (authIn === \"body\") {\n revocationBody.set(tokenParamName, token);\n revocationBody.set(\"client_id\", clientId);\n if (clientSecret)\n revocationBody.set(\"client_secret\", clientSecret);\n request = createOAuth2Request({\n authIn: \"body\",\n body: revocationBody,\n clientId,\n clientSecret,\n encoding: \"application/x-www-form-urlencoded\",\n headers: revocationHeaders,\n url: endpoint.toString()\n });\n } else if (authIn === \"header\") {\n revocationHeaders.set(\"Authorization\", `Bearer ${token}`);\n request = createOAuth2Request({\n authIn: \"header\",\n body: revocationBody,\n clientId,\n clientSecret,\n encoding: \"application/x-www-form-urlencoded\",\n headers: revocationHeaders,\n url: endpoint.toString()\n });\n } else {\n request = createOAuth2Request({\n authIn: \"query\",\n body: revocationBody,\n clientId,\n clientSecret,\n encoding: \"application/x-www-form-urlencoded\",\n headers: revocationHeaders,\n url: `${endpoint.toString()}?${tokenParamName}=${token}`\n });\n }\n const response = await fetch(request, {\n ...h2IfHttps(request.url)\n });\n if (!response.ok)\n throw await createOAuth2FetchError(response);\n },\n async validateAuthorizationCode(opts) {\n const { code, codeVerifier } = opts;\n const { authIn, encoding } = meta.tokenRequest;\n const bodyObj = {};\n for (const key in meta.validateAuthorizationCodeBody ?? {}) {\n const value = meta.validateAuthorizationCodeBody[key];\n if (typeof value === \"string\")\n bodyObj[key] = value;\n }\n bodyObj.grant_type = \"authorization_code\";\n bodyObj.code = code;\n if (config.redirectUri)\n bodyObj.redirect_uri = config.redirectUri;\n if (meta.PKCEMethod !== undefined) {\n if (!codeVerifier) {\n throw new Error(\"codeVerifier required when PKCE is enabled\");\n }\n bodyObj.code_verifier = codeVerifier;\n }\n const payload = encoding === \"application/json\" ? bodyObj : new URLSearchParams(bodyObj);\n const request = createOAuth2Request({\n authIn,\n body: payload,\n clientId: config.clientId,\n clientSecret: hasClientSecret(config) ? config.clientSecret : undefined,\n encoding,\n url: tokenUrl\n });\n const response = await fetch(request, {\n ...h2IfHttps(request.url)\n });\n if (!response.ok)\n throw await createOAuth2FetchError(response);\n return response.json();\n }\n };\n};\nexport {\n verifyIdToken,\n scopeRequiredProviderOptions,\n revocableProviderOptions,\n refreshableProviderOptions,\n providers,\n providerOptions,\n pkceProviderOptions,\n oidcProviderOptions,\n normalizeProviderIdentity,\n isValidProviderOption,\n isScopeRequiredProviderOption,\n isRevocableProviderOption,\n isRevocableOAuth2Client,\n isRefreshableProviderOption,\n isRefreshableOAuth2Client,\n isPKCEProviderOption,\n isObject,\n isOIDCProviderOption,\n isExpectedType,\n hmacSha256,\n hasClientSecret,\n h2IfHttps,\n getWithingsProps,\n getProviderSubjectKeys,\n generateState,\n generateCodeVerifier,\n extractPropFromIdentity,\n encodeBase64,\n defineProviders,\n decodeJWT,\n decodeBase64,\n createS256CodeChallenge,\n createOIDCClient,\n createOAuth2Request,\n createOAuth2FetchError,\n createOAuth2Client\n};\n",
|
|
13
|
+
"import { eq } from 'drizzle-orm';\nimport { bigint, integer, pgTable, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { LockoutRecord, LockoutStore } from './types';\n\nconst KEY_LENGTH = 320;\n\nexport const lockoutsTable = pgTable('auth_lockouts', {\n\tfailed_attempts: integer('failed_attempts').notNull().default(0),\n\tkey: varchar('key', { length: KEY_LENGTH }).primaryKey(),\n\tlocked_until_ms: bigint('locked_until_ms', { mode: 'number' }),\n\twindow_started_at_ms: bigint('window_started_at_ms', {\n\t\tmode: 'number'\n\t}).notNull()\n});\n\ntype LockoutRow = typeof lockoutsTable.$inferSelect;\ntype LockoutInsert = typeof lockoutsTable.$inferInsert;\n\nconst toRecord = (row: LockoutRow): LockoutRecord => ({\n\tfailedAttempts: row.failed_attempts,\n\tkey: row.key,\n\tlockedUntil: row.locked_until_ms ?? undefined,\n\twindowStartedAt: row.window_started_at_ms\n});\n\nexport const createNeonLockoutStore = (databaseUrl: string) =>\n\tcreatePostgresLockoutStore(createNeonDatabase(databaseUrl));\nexport const createPostgresLockoutStore = (db: AnyPgDatabase): LockoutStore => {\n\tconst get = async (key: string) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(lockoutsTable)\n\t\t\t.where(eq(lockoutsTable.key, key))\n\t\t\t.limit(1);\n\n\t\treturn row ? toRecord(row) : undefined;\n\t};\n\tconst save = async (record: LockoutRecord) => {\n\t\tconst values: LockoutInsert = {\n\t\t\tfailed_attempts: record.failedAttempts,\n\t\t\tkey: record.key,\n\t\t\tlocked_until_ms: record.lockedUntil ?? null,\n\t\t\twindow_started_at_ms: record.windowStartedAt\n\t\t};\n\t\tawait db\n\t\t\t.insert(lockoutsTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({ set: values, target: lockoutsTable.key });\n\t};\n\n\treturn {\n\t\tget,\n\t\tincrement: async (key, windowMs) => {\n\t\t\tconst now = Date.now();\n\t\t\tconst existing = await get(key);\n\t\t\tconst next: LockoutRecord =\n\t\t\t\texisting !== undefined &&\n\t\t\t\tnow - existing.windowStartedAt <= windowMs\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...existing,\n\t\t\t\t\t\t\tfailedAttempts: existing.failedAttempts + 1\n\t\t\t\t\t\t}\n\t\t\t\t\t: { failedAttempts: 1, key, windowStartedAt: now };\n\t\t\tawait save(next);\n\n\t\t\treturn next;\n\t\t},\n\t\tlock: async (key, lockedUntil) => {\n\t\t\tconst existing = (await get(key)) ?? {\n\t\t\t\tfailedAttempts: 0,\n\t\t\t\tkey,\n\t\t\t\twindowStartedAt: Date.now()\n\t\t\t};\n\t\t\tawait save({ ...existing, lockedUntil });\n\t\t},\n\t\treset: async (key) => {\n\t\t\tawait db.delete(lockoutsTable).where(eq(lockoutsTable.key, key));\n\t\t}\n\t};\n};\n",
|
|
14
|
+
"import { eq } from 'drizzle-orm';\nimport {\n\tbigint,\n\tboolean,\n\tjsonb,\n\tpgTable,\n\ttext,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { MfaEnrollment, MFAStore } from './types';\n\nconst ID_LENGTH = 255;\n\nexport const mfaEnrollmentsTable = pgTable('auth_mfa_enrollments', {\n\tbackup_code_hashes: jsonb('backup_code_hashes')\n\t\t.$type<string[]>()\n\t\t.notNull()\n\t\t.default([]),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tlast_used_at_ms: bigint('last_used_at_ms', { mode: 'number' }),\n\ttotp_secret_ciphertext: text('totp_secret_ciphertext'),\n\ttotp_verified: boolean('totp_verified').notNull().default(false),\n\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull(),\n\tuser_id: varchar('user_id', { length: ID_LENGTH }).primaryKey()\n});\n\ntype MfaRow = typeof mfaEnrollmentsTable.$inferSelect;\ntype MfaInsert = typeof mfaEnrollmentsTable.$inferInsert;\n\nconst toEnrollment = (row: MfaRow): MfaEnrollment => ({\n\tbackupCodeHashes: row.backup_code_hashes,\n\tcreatedAt: row.created_at_ms,\n\tlastUsedAt: row.last_used_at_ms ?? undefined,\n\ttotpSecretCiphertext: row.totp_secret_ciphertext ?? undefined,\n\ttotpVerified: row.totp_verified,\n\tupdatedAt: row.updated_at_ms,\n\tuserId: row.user_id\n});\n\nexport const createNeonMfaStore = (databaseUrl: string) =>\n\tcreatePostgresMfaStore(createNeonDatabase(databaseUrl));\nexport const createPostgresMfaStore = (db: AnyPgDatabase): MFAStore => ({\n\tgetEnrollment: async (userId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(mfaEnrollmentsTable)\n\t\t\t.where(eq(mfaEnrollmentsTable.user_id, userId))\n\t\t\t.limit(1);\n\n\t\treturn row ? toEnrollment(row) : undefined;\n\t},\n\tlistEnrollments: async () => {\n\t\tconst rows = await db.select().from(mfaEnrollmentsTable);\n\n\t\treturn rows.map(toEnrollment);\n\t},\n\tremoveEnrollment: async (userId) => {\n\t\tawait db\n\t\t\t.delete(mfaEnrollmentsTable)\n\t\t\t.where(eq(mfaEnrollmentsTable.user_id, userId));\n\t},\n\tsaveEnrollment: async (enrollment) => {\n\t\tconst values: MfaInsert = {\n\t\t\tbackup_code_hashes: enrollment.backupCodeHashes,\n\t\t\tcreated_at_ms: enrollment.createdAt,\n\t\t\tlast_used_at_ms: enrollment.lastUsedAt ?? null,\n\t\t\ttotp_secret_ciphertext: enrollment.totpSecretCiphertext ?? null,\n\t\t\ttotp_verified: enrollment.totpVerified,\n\t\t\tupdated_at_ms: enrollment.updatedAt,\n\t\t\tuser_id: enrollment.userId\n\t\t};\n\t\tawait db.insert(mfaEnrollmentsTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: mfaEnrollmentsTable.user_id\n\t\t});\n\t}\n});\n",
|
|
15
|
+
"import { and, desc, eq, gt, lt } from 'drizzle-orm';\nimport {\n\tbigint,\n\tboolean,\n\tjsonb,\n\tpgTable,\n\ttext,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tAuthorizationCode,\n\tAuthorizationCodeStore,\n\tClientAssertionJtiStore,\n\tClientRegistrationToken,\n\tClientRegistrationTokenStore,\n\tDeviceAuthorization,\n\tDeviceAuthorizationStatus,\n\tDeviceAuthorizationStore,\n\tInitialAccessTokenStore,\n\tLogoutDelivery,\n\tLogoutDeliveryStore,\n\tOAuthClient,\n\tOAuthClientStore,\n\tOidcRefreshToken,\n\tOidcRefreshTokenStore,\n\tPushedAuthorizationRequest,\n\tPushedAuthorizationRequestStore\n} from './types';\n\nconst URL_LENGTH = 2048;\nconst DEFAULT_LIST_LIMIT = 100;\n\nconst ID_LENGTH = 255;\n\nexport const oauthClientAssertionJtisTable = pgTable(\n\t'auth_oauth_client_assertion_jtis',\n\t{\n\t\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\t\tcomposite_key: varchar('composite_key', {\n\t\t\tlength: ID_LENGTH\n\t\t}).primaryKey(),\n\t\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\t\tjti: varchar('jti', { length: ID_LENGTH }).notNull()\n\t}\n);\n\nexport const oauthClientRegistrationTokensTable = pgTable(\n\t'auth_oauth_client_registration_tokens',\n\t{\n\t\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\ttoken_hash: varchar('token_hash', { length: ID_LENGTH }).primaryKey()\n\t}\n);\n\nexport const oauthClientsTable = pgTable('auth_oauth_clients', {\n\tbackchannel_logout_uri: varchar('backchannel_logout_uri', {\n\t\tlength: URL_LENGTH\n\t}),\n\tclient_id: varchar('client_id', { length: ID_LENGTH }).primaryKey(),\n\thashed_secret: varchar('hashed_secret', { length: ID_LENGTH }),\n\tjwks_json: jsonb('jwks_json').$type<JsonWebKey[]>(),\n\tjwks_uri: varchar('jwks_uri', { length: URL_LENGTH }),\n\tname: varchar('name', { length: ID_LENGTH }).notNull(),\n\tpost_logout_redirect_uris: text('post_logout_redirect_uris').array(),\n\tredirect_uris: text('redirect_uris').array().notNull(),\n\trequire_pushed_authorization_requests: boolean(\n\t\t'require_pushed_authorization_requests'\n\t),\n\trequire_signed_request_object: boolean('require_signed_request_object'),\n\tscopes: text('scopes').array().notNull()\n});\n\nexport const oauthCodesTable = pgTable('auth_oauth_codes', {\n\tacr: varchar('acr', { length: ID_LENGTH }),\n\tclaims_json: jsonb('claims_json').$type<Record<string, unknown>>(),\n\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\tcode_challenge: varchar('code_challenge', { length: ID_LENGTH }).notNull(),\n\tcode_hash: varchar('code_hash', { length: ID_LENGTH }).primaryKey(),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tdpop_jkt: varchar('dpop_jkt', { length: ID_LENGTH }),\n\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\tnonce: varchar('nonce', { length: ID_LENGTH }),\n\tredirect_uri: varchar('redirect_uri', { length: ID_LENGTH }).notNull(),\n\tscopes: text('scopes').array().notNull(),\n\tuser_id: varchar('user_id', { length: ID_LENGTH }).notNull()\n});\n\nexport const oauthDeviceAuthorizationsTable = pgTable(\n\t'auth_oauth_device_authorizations',\n\t{\n\t\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\tdevice_code_hash: varchar('device_code_hash', {\n\t\t\tlength: ID_LENGTH\n\t\t}).primaryKey(),\n\t\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\t\tinterval_seconds: bigint('interval_seconds', { mode: 'number' }).notNull(),\n\t\tscopes: text('scopes').array().notNull(),\n\t\tstatus: varchar('status', { length: 16 }).notNull(),\n\t\tuser_code: varchar('user_code', { length: 16 }).notNull().unique(),\n\t\tuser_sub: varchar('user_sub', { length: ID_LENGTH })\n\t}\n);\n\nexport const oauthInitialAccessTokensTable = pgTable(\n\t'auth_oauth_initial_access_tokens',\n\t{\n\t\ttoken_hash: varchar('token_hash', { length: ID_LENGTH }).primaryKey()\n\t}\n);\n\nexport const oauthLogoutDeliveriesTable = pgTable(\n\t'auth_oauth_logout_deliveries',\n\t{\n\t\tattempts: bigint('attempts', { mode: 'number' }).notNull(),\n\t\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\tendpoint_url: varchar('endpoint_url', { length: URL_LENGTH }).notNull(),\n\t\tid: varchar('id', { length: ID_LENGTH }).primaryKey(),\n\t\tlast_error: text('last_error'),\n\t\tlast_status: bigint('last_status', { mode: 'number' }),\n\t\tlogout_token: text('logout_token').notNull(),\n\t\tuser_id: varchar('user_id', { length: ID_LENGTH }).notNull()\n\t}\n);\n\nexport const oauthPushedAuthorizationRequestsTable = pgTable(\n\t'auth_oauth_pushed_authorization_requests',\n\t{\n\t\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\t\tparams_json: jsonb('params_json')\n\t\t\t.$type<Record<string, string>>()\n\t\t\t.notNull(),\n\t\trequest_uri_hash: varchar('request_uri_hash', {\n\t\t\tlength: ID_LENGTH\n\t\t}).primaryKey()\n\t}\n);\n\nexport const oauthRefreshTokensTable = pgTable('auth_oauth_refresh_tokens', {\n\tacr: varchar('acr', { length: ID_LENGTH }),\n\tclaims_json: jsonb('claims_json').$type<Record<string, unknown>>(),\n\tclient_id: varchar('client_id', { length: ID_LENGTH }).notNull(),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tdpop_jkt: varchar('dpop_jkt', { length: ID_LENGTH }),\n\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\tscopes: text('scopes').array().notNull(),\n\ttoken_hash: varchar('token_hash', { length: ID_LENGTH }).primaryKey(),\n\tuser_id: varchar('user_id', { length: ID_LENGTH }).notNull()\n});\n\ntype ClientRow = typeof oauthClientsTable.$inferSelect;\ntype CodeRow = typeof oauthCodesTable.$inferSelect;\ntype DeviceAuthRow = typeof oauthDeviceAuthorizationsTable.$inferSelect;\ntype LogoutDeliveryRow = typeof oauthLogoutDeliveriesTable.$inferSelect;\ntype RefreshRow = typeof oauthRefreshTokensTable.$inferSelect;\n\nconst toClient = (row: ClientRow): OAuthClient => ({\n\tbackchannelLogoutUri: row.backchannel_logout_uri ?? undefined,\n\tclientId: row.client_id,\n\thashedSecret: row.hashed_secret ?? undefined,\n\tjwks: row.jwks_json ?? undefined,\n\tjwksUri: row.jwks_uri ?? undefined,\n\tname: row.name,\n\tpostLogoutRedirectUris: row.post_logout_redirect_uris ?? undefined,\n\tredirectUris: row.redirect_uris,\n\trequirePushedAuthorizationRequests:\n\t\trow.require_pushed_authorization_requests ?? undefined,\n\trequireSignedRequestObject: row.require_signed_request_object ?? undefined,\n\tscopes: row.scopes\n});\n\nconst toLogoutDelivery = (row: LogoutDeliveryRow): LogoutDelivery => ({\n\tattempts: row.attempts,\n\tclientId: row.client_id,\n\tcreatedAt: row.created_at_ms,\n\tendpointUrl: row.endpoint_url,\n\tid: row.id,\n\tlastError: row.last_error ?? undefined,\n\tlastStatus: row.last_status ?? undefined,\n\tlogoutToken: row.logout_token,\n\tuserId: row.user_id\n});\n\nconst toCode = (row: CodeRow): AuthorizationCode => ({\n\tacr: row.acr ?? undefined,\n\tclaims: row.claims_json ?? undefined,\n\tclientId: row.client_id,\n\tcodeChallenge: row.code_challenge,\n\tcodeHash: row.code_hash,\n\tcreatedAt: row.created_at_ms,\n\tdpopJkt: row.dpop_jkt ?? undefined,\n\texpiresAt: row.expires_at_ms,\n\tnonce: row.nonce ?? undefined,\n\tredirectUri: row.redirect_uri,\n\tscopes: row.scopes,\n\tuserId: row.user_id\n});\n\nconst toCodeValues = (\n\tcode: AuthorizationCode\n): typeof oauthCodesTable.$inferInsert => ({\n\tacr: code.acr ?? null,\n\tclaims_json: code.claims ?? null,\n\tclient_id: code.clientId,\n\tcode_challenge: code.codeChallenge,\n\tcode_hash: code.codeHash,\n\tcreated_at_ms: code.createdAt,\n\tdpop_jkt: code.dpopJkt ?? null,\n\texpires_at_ms: code.expiresAt,\n\tnonce: code.nonce ?? null,\n\tredirect_uri: code.redirectUri,\n\tscopes: code.scopes,\n\tuser_id: code.userId\n});\n\nconst toDeviceAuth = (row: DeviceAuthRow): DeviceAuthorization => ({\n\tclientId: row.client_id,\n\tcreatedAt: row.created_at_ms,\n\tdeviceCodeHash: row.device_code_hash,\n\texpiresAt: row.expires_at_ms,\n\tintervalSeconds: row.interval_seconds,\n\tscopes: row.scopes,\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- deserialization boundary: status was persisted from DeviceAuthorizationStatus\n\tstatus: row.status as DeviceAuthorizationStatus,\n\tuserCode: row.user_code,\n\tuserSub: row.user_sub ?? undefined\n});\n\nconst toRefresh = (row: RefreshRow): OidcRefreshToken => ({\n\tacr: row.acr ?? undefined,\n\tclaims: row.claims_json ?? undefined,\n\tclientId: row.client_id,\n\tcreatedAt: row.created_at_ms,\n\tdpopJkt: row.dpop_jkt ?? undefined,\n\texpiresAt: row.expires_at_ms,\n\tscopes: row.scopes,\n\ttokenHash: row.token_hash,\n\tuserId: row.user_id\n});\n\nconst toRefreshValues = (\n\ttoken: OidcRefreshToken\n): typeof oauthRefreshTokensTable.$inferInsert => ({\n\tacr: token.acr ?? null,\n\tclaims_json: token.claims ?? null,\n\tclient_id: token.clientId,\n\tcreated_at_ms: token.createdAt,\n\tdpop_jkt: token.dpopJkt ?? null,\n\texpires_at_ms: token.expiresAt,\n\tscopes: token.scopes,\n\ttoken_hash: token.tokenHash,\n\tuser_id: token.userId\n});\n\nexport const createNeonAuthorizationCodeStore = (databaseUrl: string) =>\n\tcreatePostgresAuthorizationCodeStore(createNeonDatabase(databaseUrl));\nexport const createNeonClientAssertionJtiStore = (databaseUrl: string) =>\n\tcreatePostgresClientAssertionJtiStore(createNeonDatabase(databaseUrl));\nexport const createNeonClientRegistrationTokenStore = (databaseUrl: string) =>\n\tcreatePostgresClientRegistrationTokenStore(createNeonDatabase(databaseUrl));\nexport const createNeonDeviceAuthorizationStore = (databaseUrl: string) =>\n\tcreatePostgresDeviceAuthorizationStore(createNeonDatabase(databaseUrl));\nexport const createNeonInitialAccessTokenStore = (databaseUrl: string) =>\n\tcreatePostgresInitialAccessTokenStore(createNeonDatabase(databaseUrl));\nexport const createNeonLogoutDeliveryStore = (databaseUrl: string) =>\n\tcreatePostgresLogoutDeliveryStore(createNeonDatabase(databaseUrl));\nexport const createNeonOAuthClientStore = (databaseUrl: string) =>\n\tcreatePostgresOAuthClientStore(createNeonDatabase(databaseUrl));\nexport const createNeonOidcRefreshTokenStore = (databaseUrl: string) =>\n\tcreatePostgresOidcRefreshTokenStore(createNeonDatabase(databaseUrl));\nexport const createNeonPushedAuthorizationRequestStore = (databaseUrl: string) =>\n\tcreatePostgresPushedAuthorizationRequestStore(createNeonDatabase(databaseUrl));\nexport const createPostgresAuthorizationCodeStore = (\n\tdb: AnyPgDatabase\n): AuthorizationCodeStore => ({\n\tconsumeCode: async (codeHash) => {\n\t\tconst [row] = await db\n\t\t\t.delete(oauthCodesTable)\n\t\t\t.where(eq(oauthCodesTable.code_hash, codeHash))\n\t\t\t.returning();\n\n\t\treturn row ? toCode(row) : undefined;\n\t},\n\tsaveCode: async (code) => {\n\t\tawait db.insert(oauthCodesTable).values(toCodeValues(code));\n\t}\n});\nexport const createPostgresClientAssertionJtiStore = (\n\tdb: AnyPgDatabase\n): ClientAssertionJtiStore => ({\n\trecordIfFresh: async (clientId, jti, expiresAt) => {\n\t\t// Lazy GC of expired entries on each call. Bounded by the assertion `exp` window\n\t\t// (~5 min), so this stays cheap even at high call volume.\n\t\tawait db\n\t\t\t.delete(oauthClientAssertionJtisTable)\n\t\t\t.where(lt(oauthClientAssertionJtisTable.expires_at_ms, Date.now()));\n\t\tconst compositeKey = `${clientId}|${jti}`;\n\t\ttry {\n\t\t\tawait db.insert(oauthClientAssertionJtisTable).values({\n\t\t\t\tclient_id: clientId,\n\t\t\t\tcomposite_key: compositeKey,\n\t\t\t\texpires_at_ms: expiresAt,\n\t\t\t\tjti\n\t\t\t});\n\n\t\t\treturn true;\n\t\t} catch {\n\t\t\t// PK collision = we've seen this jti for this client before = replay.\n\t\t\treturn false;\n\t\t}\n\t}\n});\nexport const createPostgresClientRegistrationTokenStore = (\n\tdb: AnyPgDatabase\n): ClientRegistrationTokenStore => ({\n\tdeleteByClientId: async (clientId) => {\n\t\tawait db\n\t\t\t.delete(oauthClientRegistrationTokensTable)\n\t\t\t.where(eq(oauthClientRegistrationTokensTable.client_id, clientId));\n\t},\n\tfindByTokenHash: async (tokenHash) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(oauthClientRegistrationTokensTable)\n\t\t\t.where(eq(oauthClientRegistrationTokensTable.token_hash, tokenHash))\n\t\t\t.limit(1);\n\t\tif (!row) return undefined;\n\t\tconst token: ClientRegistrationToken = {\n\t\t\tclientId: row.client_id,\n\t\t\tcreatedAt: row.created_at_ms,\n\t\t\ttokenHash: row.token_hash\n\t\t};\n\n\t\treturn token;\n\t},\n\tsaveToken: async (token) => {\n\t\t// One reg token per client — drop any prior token before saving.\n\t\tawait db\n\t\t\t.delete(oauthClientRegistrationTokensTable)\n\t\t\t.where(\n\t\t\t\teq(oauthClientRegistrationTokensTable.client_id, token.clientId)\n\t\t\t);\n\t\tawait db.insert(oauthClientRegistrationTokensTable).values({\n\t\t\tclient_id: token.clientId,\n\t\t\tcreated_at_ms: token.createdAt,\n\t\t\ttoken_hash: token.tokenHash\n\t\t});\n\t}\n});\nexport const createPostgresDeviceAuthorizationStore = (\n\tdb: AnyPgDatabase\n): DeviceAuthorizationStore => ({\n\tdeleteByDeviceCodeHash: async (deviceCodeHash) => {\n\t\tawait db\n\t\t\t.delete(oauthDeviceAuthorizationsTable)\n\t\t\t.where(\n\t\t\t\teq(\n\t\t\t\t\toauthDeviceAuthorizationsTable.device_code_hash,\n\t\t\t\t\tdeviceCodeHash\n\t\t\t\t)\n\t\t\t);\n\t},\n\tfindByDeviceCodeHash: async (deviceCodeHash) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(oauthDeviceAuthorizationsTable)\n\t\t\t.where(\n\t\t\t\teq(\n\t\t\t\t\toauthDeviceAuthorizationsTable.device_code_hash,\n\t\t\t\t\tdeviceCodeHash\n\t\t\t\t)\n\t\t\t)\n\t\t\t.limit(1);\n\n\t\treturn row ? toDeviceAuth(row) : undefined;\n\t},\n\tfindByUserCode: async (userCode) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(oauthDeviceAuthorizationsTable)\n\t\t\t.where(eq(oauthDeviceAuthorizationsTable.user_code, userCode))\n\t\t\t.limit(1);\n\n\t\treturn row ? toDeviceAuth(row) : undefined;\n\t},\n\tsaveDeviceAuthorization: async (deviceAuthorization) => {\n\t\tawait db.insert(oauthDeviceAuthorizationsTable).values({\n\t\t\tclient_id: deviceAuthorization.clientId,\n\t\t\tcreated_at_ms: deviceAuthorization.createdAt,\n\t\t\tdevice_code_hash: deviceAuthorization.deviceCodeHash,\n\t\t\texpires_at_ms: deviceAuthorization.expiresAt,\n\t\t\tinterval_seconds: deviceAuthorization.intervalSeconds,\n\t\t\tscopes: deviceAuthorization.scopes,\n\t\t\tstatus: deviceAuthorization.status,\n\t\t\tuser_code: deviceAuthorization.userCode,\n\t\t\tuser_sub: deviceAuthorization.userSub ?? null\n\t\t});\n\t},\n\tupdateStatus: async (deviceCodeHash, status, userSub) => {\n\t\tawait db\n\t\t\t.update(oauthDeviceAuthorizationsTable)\n\t\t\t.set({ status, user_sub: userSub ?? null })\n\t\t\t.where(\n\t\t\t\teq(\n\t\t\t\t\toauthDeviceAuthorizationsTable.device_code_hash,\n\t\t\t\t\tdeviceCodeHash\n\t\t\t\t)\n\t\t\t);\n\t}\n});\nexport const createPostgresInitialAccessTokenStore = (\n\tdb: AnyPgDatabase\n): InitialAccessTokenStore => ({\n\tconsumeToken: async (tokenHash) => {\n\t\tconst deleted = await db\n\t\t\t.delete(oauthInitialAccessTokensTable)\n\t\t\t.where(eq(oauthInitialAccessTokensTable.token_hash, tokenHash))\n\t\t\t.returning({ token_hash: oauthInitialAccessTokensTable.token_hash });\n\n\t\treturn deleted.length > 0;\n\t}\n});\nexport const createPostgresLogoutDeliveryStore = (\n\tdb: AnyPgDatabase\n): LogoutDeliveryStore => ({\n\tlistFailed: async (limit = DEFAULT_LIST_LIMIT) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(oauthLogoutDeliveriesTable)\n\t\t\t.orderBy(desc(oauthLogoutDeliveriesTable.created_at_ms))\n\t\t\t.limit(limit);\n\n\t\treturn rows.map(toLogoutDelivery);\n\t},\n\trecordFailure: async (delivery) => {\n\t\tawait db.insert(oauthLogoutDeliveriesTable).values({\n\t\t\tattempts: delivery.attempts,\n\t\t\tclient_id: delivery.clientId,\n\t\t\tcreated_at_ms: delivery.createdAt,\n\t\t\tendpoint_url: delivery.endpointUrl,\n\t\t\tid: delivery.id,\n\t\t\tlast_error: delivery.lastError ?? null,\n\t\t\tlast_status: delivery.lastStatus ?? null,\n\t\t\tlogout_token: delivery.logoutToken,\n\t\t\tuser_id: delivery.userId\n\t\t});\n\t},\n\tremoveFailure: async (deliveryId) => {\n\t\tawait db\n\t\t\t.delete(oauthLogoutDeliveriesTable)\n\t\t\t.where(eq(oauthLogoutDeliveriesTable.id, deliveryId));\n\t}\n});\n// Maps an OAuthClient domain object to the row shape (used by saveClient + updateClient).\nconst toClientValues = (\n\tclient: OAuthClient\n): typeof oauthClientsTable.$inferInsert => ({\n\tbackchannel_logout_uri: client.backchannelLogoutUri ?? null,\n\tclient_id: client.clientId,\n\thashed_secret: client.hashedSecret ?? null,\n\tjwks_json: client.jwks ?? null,\n\tjwks_uri: client.jwksUri ?? null,\n\tname: client.name,\n\tpost_logout_redirect_uris: client.postLogoutRedirectUris ?? null,\n\tredirect_uris: client.redirectUris,\n\trequire_pushed_authorization_requests:\n\t\tclient.requirePushedAuthorizationRequests ?? null,\n\trequire_signed_request_object: client.requireSignedRequestObject ?? null,\n\tscopes: client.scopes\n});\n\nexport const createPostgresOAuthClientStore = (\n\tdb: AnyPgDatabase\n): OAuthClientStore => ({\n\tdeleteClient: async (clientId) => {\n\t\tawait db\n\t\t\t.delete(oauthClientsTable)\n\t\t\t.where(eq(oauthClientsTable.client_id, clientId));\n\t},\n\tfindClient: async (clientId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(oauthClientsTable)\n\t\t\t.where(eq(oauthClientsTable.client_id, clientId))\n\t\t\t.limit(1);\n\n\t\treturn row ? toClient(row) : undefined;\n\t},\n\tsaveClient: async (client) => {\n\t\tawait db.insert(oauthClientsTable).values(toClientValues(client));\n\t},\n\tupdateClient: async (clientId, client) => {\n\t\tawait db\n\t\t\t.update(oauthClientsTable)\n\t\t\t.set(toClientValues(client))\n\t\t\t.where(eq(oauthClientsTable.client_id, clientId));\n\t}\n});\nexport const createPostgresOidcRefreshTokenStore = (\n\tdb: AnyPgDatabase\n): OidcRefreshTokenStore => ({\n\tconsumeToken: async (tokenHash) => {\n\t\tconst [row] = await db\n\t\t\t.delete(oauthRefreshTokensTable)\n\t\t\t.where(eq(oauthRefreshTokensTable.token_hash, tokenHash))\n\t\t\t.returning();\n\n\t\treturn row ? toRefresh(row) : undefined;\n\t},\n\tdeleteForUser: async (userId) => {\n\t\tawait db\n\t\t\t.delete(oauthRefreshTokensTable)\n\t\t\t.where(eq(oauthRefreshTokensTable.user_id, userId));\n\t},\n\tgetToken: async (tokenHash) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(oauthRefreshTokensTable)\n\t\t\t.where(eq(oauthRefreshTokensTable.token_hash, tokenHash))\n\t\t\t.limit(1);\n\n\t\treturn row ? toRefresh(row) : undefined;\n\t},\n\tlistClientIdsForUser: async (userId) => {\n\t\tconst rows = await db\n\t\t\t.selectDistinct({ client_id: oauthRefreshTokensTable.client_id })\n\t\t\t.from(oauthRefreshTokensTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(oauthRefreshTokensTable.user_id, userId),\n\t\t\t\t\tgt(oauthRefreshTokensTable.expires_at_ms, Date.now())\n\t\t\t\t)\n\t\t\t);\n\n\t\treturn rows.map((row) => row.client_id);\n\t},\n\tsaveToken: async (token) => {\n\t\tawait db.insert(oauthRefreshTokensTable).values(toRefreshValues(token));\n\t}\n});\nexport const createPostgresPushedAuthorizationRequestStore = (\n\tdb: AnyPgDatabase\n): PushedAuthorizationRequestStore => ({\n\tconsumeRequest: async (requestUriHash) => {\n\t\tconst [row] = await db\n\t\t\t.delete(oauthPushedAuthorizationRequestsTable)\n\t\t\t.where(\n\t\t\t\teq(\n\t\t\t\t\toauthPushedAuthorizationRequestsTable.request_uri_hash,\n\t\t\t\t\trequestUriHash\n\t\t\t\t)\n\t\t\t)\n\t\t\t.returning();\n\t\tif (!row) return undefined;\n\t\t// Lazy GC of expired rows from prior writes — keeps the table thin without a\n\t\t// dedicated cron. Same call returns undefined if THIS request was already expired.\n\t\tawait db\n\t\t\t.delete(oauthPushedAuthorizationRequestsTable)\n\t\t\t.where(\n\t\t\t\tlt(\n\t\t\t\t\toauthPushedAuthorizationRequestsTable.expires_at_ms,\n\t\t\t\t\tDate.now()\n\t\t\t\t)\n\t\t\t);\n\t\tif (row.expires_at_ms < Date.now()) return undefined;\n\t\tconst request: PushedAuthorizationRequest = {\n\t\t\tclientId: row.client_id,\n\t\t\tcreatedAt: row.created_at_ms,\n\t\t\texpiresAt: row.expires_at_ms,\n\t\t\tparams: row.params_json,\n\t\t\trequestUriHash: row.request_uri_hash\n\t\t};\n\n\t\treturn request;\n\t},\n\tsaveRequest: async (request) => {\n\t\tawait db.insert(oauthPushedAuthorizationRequestsTable).values({\n\t\t\tclient_id: request.clientId,\n\t\t\tcreated_at_ms: request.createdAt,\n\t\t\texpires_at_ms: request.expiresAt,\n\t\t\tparams_json: request.params,\n\t\t\trequest_uri_hash: request.requestUriHash\n\t\t});\n\t}\n});\n",
|
|
16
|
+
"import { and, eq } from 'drizzle-orm';\nimport {\n\tbigint,\n\tjsonb,\n\tpgTable,\n\tprimaryKey,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tInvitationState,\n\tMembershipStatus,\n\tOrganization,\n\tOrganizationInvitation,\n\tOrganizationMembership,\n\tOrganizationStore\n} from './types';\n\nconst ID_LENGTH = 255;\nconst NAME_LENGTH = 255;\nconst STATE_LENGTH = 16;\n\nexport const organizationInvitationsTable = pgTable(\n\t'auth_organization_invitations',\n\t{\n\t\taccepted_at_ms: bigint('accepted_at_ms', { mode: 'number' }),\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\temail: varchar('email', { length: ID_LENGTH }).notNull(),\n\t\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\t\tinvitation_id: varchar('invitation_id', {\n\t\t\tlength: ID_LENGTH\n\t\t}).primaryKey(),\n\t\tinviter_user_id: varchar('inviter_user_id', { length: ID_LENGTH }),\n\t\torganization_id: varchar('organization_id', {\n\t\t\tlength: ID_LENGTH\n\t\t}).notNull(),\n\t\troles: jsonb('roles').$type<string[]>().notNull().default([]),\n\t\tstate: varchar('state', { length: STATE_LENGTH })\n\t\t\t.$type<InvitationState>()\n\t\t\t.notNull()\n\t\t\t.default('pending'),\n\t\ttoken_hash: varchar('token_hash', { length: ID_LENGTH })\n\t\t\t.notNull()\n\t\t\t.unique()\n\t}\n);\nexport const organizationMembershipsTable = pgTable(\n\t'auth_organization_memberships',\n\t{\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\torganization_id: varchar('organization_id', {\n\t\t\tlength: ID_LENGTH\n\t\t}).notNull(),\n\t\troles: jsonb('roles').$type<string[]>().notNull().default([]),\n\t\tstatus: varchar('status', { length: STATE_LENGTH })\n\t\t\t.$type<MembershipStatus>()\n\t\t\t.notNull()\n\t\t\t.default('active'),\n\t\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull(),\n\t\tuser_id: varchar('user_id', { length: ID_LENGTH }).notNull()\n\t},\n\t(table) => [primaryKey({ columns: [table.organization_id, table.user_id] })]\n);\nexport const organizationsTable = pgTable('auth_organizations', {\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tmetadata: jsonb('metadata').$type<Record<string, unknown>>(),\n\tname: varchar('name', { length: NAME_LENGTH }).notNull(),\n\torganization_id: varchar('organization_id', {\n\t\tlength: ID_LENGTH\n\t}).primaryKey(),\n\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull()\n});\n\ntype OrganizationRow = typeof organizationsTable.$inferSelect;\ntype MembershipRow = typeof organizationMembershipsTable.$inferSelect;\ntype InvitationRow = typeof organizationInvitationsTable.$inferSelect;\ntype OrganizationInsert = typeof organizationsTable.$inferInsert;\ntype MembershipInsert = typeof organizationMembershipsTable.$inferInsert;\ntype InvitationInsert = typeof organizationInvitationsTable.$inferInsert;\n\nconst toOrganization = (row: OrganizationRow): Organization => ({\n\tcreatedAt: row.created_at_ms,\n\tmetadata: row.metadata ?? undefined,\n\tname: row.name,\n\torganizationId: row.organization_id,\n\tupdatedAt: row.updated_at_ms\n});\n\nconst toMembership = (row: MembershipRow): OrganizationMembership => ({\n\tcreatedAt: row.created_at_ms,\n\torganizationId: row.organization_id,\n\troles: row.roles,\n\tstatus: row.status,\n\tupdatedAt: row.updated_at_ms,\n\tuserId: row.user_id\n});\n\nconst toInvitation = (row: InvitationRow): OrganizationInvitation => ({\n\tacceptedAt: row.accepted_at_ms ?? undefined,\n\tcreatedAt: row.created_at_ms,\n\temail: row.email,\n\texpiresAt: row.expires_at_ms,\n\tinvitationId: row.invitation_id,\n\tinviterUserId: row.inviter_user_id ?? undefined,\n\torganizationId: row.organization_id,\n\troles: row.roles,\n\tstate: row.state,\n\ttokenHash: row.token_hash\n});\n\nexport const createNeonOrganizationStore = (databaseUrl: string) =>\n\tcreatePostgresOrganizationStore(createNeonDatabase(databaseUrl));\nexport const createPostgresOrganizationStore = (\n\tdb: AnyPgDatabase\n): OrganizationStore => ({\n\tdeleteOrganization: async (organizationId) => {\n\t\tawait db\n\t\t\t.delete(organizationsTable)\n\t\t\t.where(eq(organizationsTable.organization_id, organizationId));\n\t},\n\tgetInvitation: async (invitationId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(organizationInvitationsTable)\n\t\t\t.where(eq(organizationInvitationsTable.invitation_id, invitationId))\n\t\t\t.limit(1);\n\n\t\treturn row ? toInvitation(row) : undefined;\n\t},\n\tgetInvitationByTokenHash: async (tokenHash) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(organizationInvitationsTable)\n\t\t\t.where(eq(organizationInvitationsTable.token_hash, tokenHash))\n\t\t\t.limit(1);\n\n\t\treturn row ? toInvitation(row) : undefined;\n\t},\n\tgetMembership: async (organizationId, userId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(organizationMembershipsTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(\n\t\t\t\t\t\torganizationMembershipsTable.organization_id,\n\t\t\t\t\t\torganizationId\n\t\t\t\t\t),\n\t\t\t\t\teq(organizationMembershipsTable.user_id, userId)\n\t\t\t\t)\n\t\t\t)\n\t\t\t.limit(1);\n\n\t\treturn row ? toMembership(row) : undefined;\n\t},\n\tgetOrganization: async (organizationId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(organizationsTable)\n\t\t\t.where(eq(organizationsTable.organization_id, organizationId))\n\t\t\t.limit(1);\n\n\t\treturn row ? toOrganization(row) : undefined;\n\t},\n\tlistInvitationsByOrganization: async (organizationId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(organizationInvitationsTable)\n\t\t\t.where(\n\t\t\t\teq(organizationInvitationsTable.organization_id, organizationId)\n\t\t\t);\n\n\t\treturn rows.map(toInvitation);\n\t},\n\tlistMembershipsByOrganization: async (organizationId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(organizationMembershipsTable)\n\t\t\t.where(\n\t\t\t\teq(organizationMembershipsTable.organization_id, organizationId)\n\t\t\t);\n\n\t\treturn rows.map(toMembership);\n\t},\n\tlistMembershipsByUser: async (userId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(organizationMembershipsTable)\n\t\t\t.where(eq(organizationMembershipsTable.user_id, userId));\n\n\t\treturn rows.map(toMembership);\n\t},\n\tremoveMembership: async (organizationId, userId) => {\n\t\tawait db\n\t\t\t.delete(organizationMembershipsTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(\n\t\t\t\t\t\torganizationMembershipsTable.organization_id,\n\t\t\t\t\t\torganizationId\n\t\t\t\t\t),\n\t\t\t\t\teq(organizationMembershipsTable.user_id, userId)\n\t\t\t\t)\n\t\t\t);\n\t},\n\tsaveInvitation: async (invitation) => {\n\t\tconst values: InvitationInsert = {\n\t\t\taccepted_at_ms: invitation.acceptedAt ?? null,\n\t\t\tcreated_at_ms: invitation.createdAt,\n\t\t\temail: invitation.email,\n\t\t\texpires_at_ms: invitation.expiresAt,\n\t\t\tinvitation_id: invitation.invitationId,\n\t\t\tinviter_user_id: invitation.inviterUserId ?? null,\n\t\t\torganization_id: invitation.organizationId,\n\t\t\troles: invitation.roles,\n\t\t\tstate: invitation.state,\n\t\t\ttoken_hash: invitation.tokenHash\n\t\t};\n\t\tawait db\n\t\t\t.insert(organizationInvitationsTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: values,\n\t\t\t\ttarget: organizationInvitationsTable.invitation_id\n\t\t\t});\n\t},\n\tsaveMembership: async (membership) => {\n\t\tconst values: MembershipInsert = {\n\t\t\tcreated_at_ms: membership.createdAt,\n\t\t\torganization_id: membership.organizationId,\n\t\t\troles: membership.roles,\n\t\t\tstatus: membership.status,\n\t\t\tupdated_at_ms: membership.updatedAt,\n\t\t\tuser_id: membership.userId\n\t\t};\n\t\tawait db\n\t\t\t.insert(organizationMembershipsTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: values,\n\t\t\t\ttarget: [\n\t\t\t\t\torganizationMembershipsTable.organization_id,\n\t\t\t\t\torganizationMembershipsTable.user_id\n\t\t\t\t]\n\t\t\t});\n\t},\n\tsaveOrganization: async (organization) => {\n\t\tconst values: OrganizationInsert = {\n\t\t\tcreated_at_ms: organization.createdAt,\n\t\t\tmetadata: organization.metadata ?? null,\n\t\t\tname: organization.name,\n\t\t\torganization_id: organization.organizationId,\n\t\t\tupdated_at_ms: organization.updatedAt\n\t\t};\n\t\tawait db.insert(organizationsTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: organizationsTable.organization_id\n\t\t});\n\t}\n});\n",
|
|
17
|
+
"import { eq } from 'drizzle-orm';\nimport { bigint, pgTable, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { PasswordlessToken, PasswordlessTokenStore } from './types';\n\nconst ID_LENGTH = 255;\n\nexport const passwordlessTokensTable = pgTable('auth_passwordless_tokens', {\n\temail: varchar('email', { length: ID_LENGTH }).notNull(),\n\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\ttoken_hash: varchar('token_hash', { length: ID_LENGTH }).primaryKey()\n});\n\ntype PasswordlessRow = typeof passwordlessTokensTable.$inferSelect;\ntype PasswordlessInsert = typeof passwordlessTokensTable.$inferInsert;\n\nconst toToken = (row: PasswordlessRow): PasswordlessToken => ({\n\temail: row.email,\n\texpiresAt: row.expires_at_ms,\n\ttokenHash: row.token_hash\n});\n\nexport const createNeonPasswordlessTokenStore = (databaseUrl: string) =>\n\tcreatePostgresPasswordlessTokenStore(createNeonDatabase(databaseUrl));\nexport const createPostgresPasswordlessTokenStore = (\n\tdb: AnyPgDatabase\n): PasswordlessTokenStore => ({\n\tconsumeToken: async (tokenHash) => {\n\t\tconst [row] = await db\n\t\t\t.delete(passwordlessTokensTable)\n\t\t\t.where(eq(passwordlessTokensTable.token_hash, tokenHash))\n\t\t\t.returning();\n\n\t\treturn row ? toToken(row) : undefined;\n\t},\n\tsaveToken: async (token) => {\n\t\tconst values: PasswordlessInsert = {\n\t\t\temail: token.email,\n\t\t\texpires_at_ms: token.expiresAt,\n\t\t\ttoken_hash: token.tokenHash\n\t\t};\n\t\tawait db\n\t\t\t.insert(passwordlessTokensTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: values,\n\t\t\t\ttarget: passwordlessTokensTable.token_hash\n\t\t\t});\n\t}\n});\n",
|
|
18
|
+
"import { eq } from 'drizzle-orm';\nimport { bigint, jsonb, pgTable, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { SetupCapability, SetupSession, SetupSessionStore } from './types';\n\nconst ID_LENGTH = 255;\n\nexport const setupSessionsTable = pgTable('auth_setup_sessions', {\n\tcapabilities: jsonb('capabilities')\n\t\t.$type<SetupCapability[]>()\n\t\t.notNull()\n\t\t.default([]),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tcreated_by: varchar('created_by', { length: ID_LENGTH }),\n\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\torganization_id: varchar('organization_id', {\n\t\tlength: ID_LENGTH\n\t}).notNull(),\n\tsetup_session_id: varchar('setup_session_id', {\n\t\tlength: ID_LENGTH\n\t}).primaryKey(),\n\ttoken_hash: varchar('token_hash', { length: ID_LENGTH }).notNull().unique()\n});\n\ntype SetupRow = typeof setupSessionsTable.$inferSelect;\ntype SetupInsert = typeof setupSessionsTable.$inferInsert;\n\nconst toSession = (row: SetupRow): SetupSession => ({\n\tcapabilities: row.capabilities,\n\tcreatedAt: row.created_at_ms,\n\tcreatedBy: row.created_by ?? undefined,\n\texpiresAt: row.expires_at_ms,\n\torganizationId: row.organization_id,\n\tsetupSessionId: row.setup_session_id,\n\ttokenHash: row.token_hash\n});\n\nexport const createNeonSetupSessionStore = (databaseUrl: string) =>\n\tcreatePostgresSetupSessionStore(createNeonDatabase(databaseUrl));\nexport const createPostgresSetupSessionStore = (\n\tdb: AnyPgDatabase\n): SetupSessionStore => ({\n\tdeleteSetupSession: async (setupSessionId) => {\n\t\tawait db\n\t\t\t.delete(setupSessionsTable)\n\t\t\t.where(eq(setupSessionsTable.setup_session_id, setupSessionId));\n\t},\n\tgetSetupSessionByTokenHash: async (tokenHash) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(setupSessionsTable)\n\t\t\t.where(eq(setupSessionsTable.token_hash, tokenHash))\n\t\t\t.limit(1);\n\n\t\treturn row ? toSession(row) : undefined;\n\t},\n\tsaveSetupSession: async (session) => {\n\t\tconst values: SetupInsert = {\n\t\t\tcapabilities: session.capabilities,\n\t\t\tcreated_at_ms: session.createdAt,\n\t\t\tcreated_by: session.createdBy ?? null,\n\t\t\texpires_at_ms: session.expiresAt,\n\t\t\torganization_id: session.organizationId,\n\t\t\tsetup_session_id: session.setupSessionId,\n\t\t\ttoken_hash: session.tokenHash\n\t\t};\n\t\tawait db.insert(setupSessionsTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: setupSessionsTable.setup_session_id\n\t\t});\n\t}\n});\n",
|
|
19
|
+
"import { and, eq } from 'drizzle-orm';\nimport {\n\tbigint,\n\tjsonb,\n\tpgTable,\n\tprimaryKey,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { Role, RoleStore } from './types';\n\nconst ID_LENGTH = 255;\nconst SLUG_LENGTH = 128;\n// Global roles (no organizationId) live under the empty-string scope so the composite PK stays\n// NOT NULL (a real organizationId is never the empty string).\nconst GLOBAL_SCOPE = '';\n\nexport const rolesTable = pgTable(\n\t'auth_roles',\n\t{\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\torganization_id: varchar('organization_id', { length: ID_LENGTH })\n\t\t\t.notNull()\n\t\t\t.default(GLOBAL_SCOPE),\n\t\tpermissions: jsonb('permissions')\n\t\t\t.$type<string[]>()\n\t\t\t.notNull()\n\t\t\t.default([]),\n\t\tslug: varchar('slug', { length: SLUG_LENGTH }).notNull(),\n\t\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull()\n\t},\n\t(table) => [primaryKey({ columns: [table.organization_id, table.slug] })]\n);\n\ntype RoleRow = typeof rolesTable.$inferSelect;\ntype RoleInsert = typeof rolesTable.$inferInsert;\n\nconst toRole = (row: RoleRow): Role => ({\n\tcreatedAt: row.created_at_ms,\n\torganizationId:\n\t\trow.organization_id === GLOBAL_SCOPE ? undefined : row.organization_id,\n\tpermissions: row.permissions,\n\tslug: row.slug,\n\tupdatedAt: row.updated_at_ms\n});\n\nexport const createNeonRoleStore = (databaseUrl: string) =>\n\tcreatePostgresRoleStore(createNeonDatabase(databaseUrl));\nexport const createPostgresRoleStore = (db: AnyPgDatabase): RoleStore => ({\n\tdeleteRole: async (slug, organizationId) => {\n\t\tawait db\n\t\t\t.delete(rolesTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(\n\t\t\t\t\t\trolesTable.organization_id,\n\t\t\t\t\t\torganizationId ?? GLOBAL_SCOPE\n\t\t\t\t\t),\n\t\t\t\t\teq(rolesTable.slug, slug)\n\t\t\t\t)\n\t\t\t);\n\t},\n\tgetRole: async (slug, organizationId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(rolesTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(\n\t\t\t\t\t\trolesTable.organization_id,\n\t\t\t\t\t\torganizationId ?? GLOBAL_SCOPE\n\t\t\t\t\t),\n\t\t\t\t\teq(rolesTable.slug, slug)\n\t\t\t\t)\n\t\t\t)\n\t\t\t.limit(1);\n\n\t\treturn row ? toRole(row) : undefined;\n\t},\n\tlistRoles: async (organizationId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(rolesTable)\n\t\t\t.where(\n\t\t\t\teq(rolesTable.organization_id, organizationId ?? GLOBAL_SCOPE)\n\t\t\t);\n\n\t\treturn rows.map(toRole);\n\t},\n\tsaveRole: async (role) => {\n\t\tconst values: RoleInsert = {\n\t\t\tcreated_at_ms: role.createdAt,\n\t\t\torganization_id: role.organizationId ?? GLOBAL_SCOPE,\n\t\t\tpermissions: role.permissions,\n\t\t\tslug: role.slug,\n\t\t\tupdated_at_ms: role.updatedAt\n\t\t};\n\t\tawait db\n\t\t\t.insert(rolesTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: values,\n\t\t\t\ttarget: [rolesTable.organization_id, rolesTable.slug]\n\t\t\t});\n\t}\n});\n",
|
|
20
|
+
"import { desc, eq } from 'drizzle-orm';\nimport { bigint, pgTable, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { ScimToken, ScimTokenStore } from './types';\n\nconst ID_LENGTH = 255;\n\nexport const scimTokensTable = pgTable('auth_scim_tokens', {\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\thashed_token: varchar('hashed_token', { length: ID_LENGTH }).notNull(),\n\tlast_used_at_ms: bigint('last_used_at_ms', { mode: 'number' }),\n\torganization_id: varchar('organization_id', {\n\t\tlength: ID_LENGTH\n\t}).notNull(),\n\ttoken_id: varchar('token_id', { length: ID_LENGTH }).primaryKey()\n});\n\ntype ScimTokenRow = typeof scimTokensTable.$inferSelect;\ntype ScimTokenInsert = typeof scimTokensTable.$inferInsert;\n\nconst toToken = (row: ScimTokenRow): ScimToken => ({\n\tcreatedAt: row.created_at_ms,\n\thashedToken: row.hashed_token,\n\tlastUsedAt: row.last_used_at_ms ?? undefined,\n\torganizationId: row.organization_id,\n\ttokenId: row.token_id\n});\n\nconst toValues = (token: ScimToken): ScimTokenInsert => ({\n\tcreated_at_ms: token.createdAt,\n\thashed_token: token.hashedToken,\n\tlast_used_at_ms: token.lastUsedAt ?? null,\n\torganization_id: token.organizationId,\n\ttoken_id: token.tokenId\n});\n\nexport const createNeonScimTokenStore = (databaseUrl: string) =>\n\tcreatePostgresScimTokenStore(createNeonDatabase(databaseUrl));\n\nexport const createPostgresScimTokenStore = (\n\tdb: AnyPgDatabase\n): ScimTokenStore => ({\n\tdeleteToken: async (tokenId) => {\n\t\tawait db\n\t\t\t.delete(scimTokensTable)\n\t\t\t.where(eq(scimTokensTable.token_id, tokenId));\n\t},\n\tfindByHashedToken: async (hashedToken) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(scimTokensTable)\n\t\t\t.where(eq(scimTokensTable.hashed_token, hashedToken))\n\t\t\t.limit(1);\n\n\t\treturn row ? toToken(row) : undefined;\n\t},\n\tlistTokens: async (organizationId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(scimTokensTable)\n\t\t\t.where(eq(scimTokensTable.organization_id, organizationId))\n\t\t\t.orderBy(desc(scimTokensTable.created_at_ms));\n\n\t\treturn rows.map(toToken);\n\t},\n\tsaveToken: async (token) => {\n\t\tconst values = toValues(token);\n\t\tawait db.insert(scimTokensTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: scimTokensTable.token_id\n\t\t});\n\t}\n});\n",
|
|
21
|
+
"import { neon } from '@neondatabase/serverless';\nimport { eq } from 'drizzle-orm';\nimport { drizzle, NeonHttpDatabase } from 'drizzle-orm/neon-http';\nimport {\n\ttype AnyPgTable,\n\tbigint,\n\tjsonb,\n\tpgTable,\n\ttext,\n\ttimestamp,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport { isUserSessionId } from '../typeGuards';\nimport type { SessionData, UnregisteredSessionData } from '../types';\nimport type { AuthSessionStore } from './types';\n\nexport const authSessionsTable = pgTable('auth_sessions', {\n\taccess_token: text('access_token'),\n\tauthenticated_at_ms: bigint('authenticated_at_ms', { mode: 'number' }),\n\tcreated_at: timestamp('created_at').notNull().defaultNow(),\n\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\tid: varchar('id', { length: 255 }).primaryKey(),\n\trefresh_token: text('refresh_token'),\n\tupdated_at: timestamp('updated_at').notNull().defaultNow(),\n\tuser_json: jsonb('user_json').$type<Record<string, unknown>>().notNull()\n});\n\nexport const authUnregisteredSessionsTable = pgTable(\n\t'auth_unregistered_sessions',\n\t{\n\t\taccess_token: text('access_token'),\n\t\tcreated_at: timestamp('created_at').notNull().defaultNow(),\n\t\texpires_at_ms: bigint('expires_at_ms', { mode: 'number' }).notNull(),\n\t\tid: varchar('id', { length: 255 }).primaryKey(),\n\t\trefresh_token: text('refresh_token'),\n\t\tsession_information_json: jsonb('session_information_json').$type<\n\t\t\tRecord<string, unknown>\n\t\t>(),\n\t\tupdated_at: timestamp('updated_at').notNull().defaultNow(),\n\t\tuser_identity_json:\n\t\t\tjsonb('user_identity_json').$type<Record<string, unknown>>()\n\t}\n);\n\nexport const authSessionSchema = {\n\tauthSessions: authSessionsTable,\n\tauthUnregisteredSessions: authUnregisteredSessionsTable\n} satisfies Record<string, AnyPgTable>;\n\nexport type AuthSessionSchema = typeof authSessionSchema;\n\ntype AuthSessionRow = typeof authSessionsTable.$inferSelect;\ntype AuthUnregisteredSessionRow =\n\ttypeof authUnregisteredSessionsTable.$inferSelect;\n\nconst cloneUser = <UserType>(value: UserType) => {\n\tif (value === null || value === undefined) return value;\n\n\treturn structuredClone(value);\n};\n\nconst cloneRecord = (value?: Record<string, unknown>) =>\n\tvalue ? structuredClone(value) : undefined;\n\nconst toSessionData = <UserType>(\n\trow: AuthSessionRow\n): SessionData<UserType> => ({\n\taccessToken: row.access_token ?? undefined,\n\tauthenticatedAt: row.authenticated_at_ms ?? undefined,\n\texpiresAt: row.expires_at_ms,\n\trefreshToken: row.refresh_token ?? undefined,\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- deserialization boundary: user_json was persisted from UserType, so reading it back as UserType is sound\n\tuser: cloneUser(row.user_json as UserType)\n});\n\nconst toUnregisteredSessionData = (\n\trow: AuthUnregisteredSessionRow\n): UnregisteredSessionData => ({\n\taccessToken: row.access_token ?? undefined,\n\texpiresAt: row.expires_at_ms,\n\trefreshToken: row.refresh_token ?? undefined,\n\tsessionInformation: cloneRecord(row.session_information_json ?? undefined),\n\tuserIdentity: cloneRecord(row.user_identity_json ?? undefined)\n});\n\nexport const createNeonAuthSessionStore = <UserType>(\n\tdatabaseUrl: string\n): AuthSessionStore<UserType> => {\n\tconst sql = neon(databaseUrl);\n\tconst db: NeonHttpDatabase<AuthSessionSchema> = drizzle(sql, {\n\t\tschema: authSessionSchema\n\t});\n\n\treturn {\n\t\tgetSession: async (id) => {\n\t\t\tconst [row] = await db\n\t\t\t\t.select()\n\t\t\t\t.from(authSessionsTable)\n\t\t\t\t.where(eq(authSessionsTable.id, id))\n\t\t\t\t.limit(1);\n\n\t\t\treturn row ? toSessionData<UserType>(row) : undefined;\n\t\t},\n\t\tgetUnregisteredSession: async (id) => {\n\t\t\tconst [row] = await db\n\t\t\t\t.select()\n\t\t\t\t.from(authUnregisteredSessionsTable)\n\t\t\t\t.where(eq(authUnregisteredSessionsTable.id, id))\n\t\t\t\t.limit(1);\n\n\t\t\treturn row ? toUnregisteredSessionData(row) : undefined;\n\t\t},\n\t\tlistSessionIds: async () => {\n\t\t\tconst rows = await db\n\t\t\t\t.select({ id: authSessionsTable.id })\n\t\t\t\t.from(authSessionsTable);\n\n\t\t\treturn rows.map((row) => row.id).filter(isUserSessionId);\n\t\t},\n\t\tlistUnregisteredSessionIds: async () => {\n\t\t\tconst rows = await db\n\t\t\t\t.select({ id: authUnregisteredSessionsTable.id })\n\t\t\t\t.from(authUnregisteredSessionsTable);\n\n\t\t\treturn rows.map((row) => row.id).filter(isUserSessionId);\n\t\t},\n\t\tremoveSession: async (id) => {\n\t\t\tawait db\n\t\t\t\t.delete(authSessionsTable)\n\t\t\t\t.where(eq(authSessionsTable.id, id));\n\t\t},\n\t\tremoveUnregisteredSession: async (id) => {\n\t\t\tawait db\n\t\t\t\t.delete(authUnregisteredSessionsTable)\n\t\t\t\t.where(eq(authUnregisteredSessionsTable.id, id));\n\t\t},\n\t\tsetSession: async (id, value) => {\n\t\t\tawait db\n\t\t\t\t.insert(authSessionsTable)\n\t\t\t\t.values({\n\t\t\t\t\taccess_token: value.accessToken ?? null,\n\t\t\t\t\tauthenticated_at_ms: value.authenticatedAt ?? null,\n\t\t\t\t\texpires_at_ms: value.expiresAt,\n\t\t\t\t\tid,\n\t\t\t\t\trefresh_token: value.refreshToken ?? null,\n\t\t\t\t\tupdated_at: new Date(),\n\t\t\t\t\tuser_json: value.user ?? {}\n\t\t\t\t})\n\t\t\t\t.onConflictDoUpdate({\n\t\t\t\t\tset: {\n\t\t\t\t\t\taccess_token: value.accessToken ?? null,\n\t\t\t\t\t\tauthenticated_at_ms: value.authenticatedAt ?? null,\n\t\t\t\t\t\texpires_at_ms: value.expiresAt,\n\t\t\t\t\t\trefresh_token: value.refreshToken ?? null,\n\t\t\t\t\t\tupdated_at: new Date(),\n\t\t\t\t\t\tuser_json: value.user ?? {}\n\t\t\t\t\t},\n\t\t\t\t\ttarget: authSessionsTable.id\n\t\t\t\t});\n\t\t},\n\t\tsetUnregisteredSession: async (id, value) => {\n\t\t\tawait db\n\t\t\t\t.insert(authUnregisteredSessionsTable)\n\t\t\t\t.values({\n\t\t\t\t\taccess_token: value.accessToken ?? null,\n\t\t\t\t\texpires_at_ms: value.expiresAt,\n\t\t\t\t\tid,\n\t\t\t\t\trefresh_token: value.refreshToken ?? null,\n\t\t\t\t\tsession_information_json: value.sessionInformation ?? null,\n\t\t\t\t\tupdated_at: new Date(),\n\t\t\t\t\tuser_identity_json: value.userIdentity ?? null\n\t\t\t\t})\n\t\t\t\t.onConflictDoUpdate({\n\t\t\t\t\tset: {\n\t\t\t\t\t\taccess_token: value.accessToken ?? null,\n\t\t\t\t\t\texpires_at_ms: value.expiresAt,\n\t\t\t\t\t\trefresh_token: value.refreshToken ?? null,\n\t\t\t\t\t\tsession_information_json:\n\t\t\t\t\t\t\tvalue.sessionInformation ?? null,\n\t\t\t\t\t\tupdated_at: new Date(),\n\t\t\t\t\t\tuser_identity_json: value.userIdentity ?? null\n\t\t\t\t\t},\n\t\t\t\t\ttarget: authUnregisteredSessionsTable.id\n\t\t\t\t});\n\t\t}\n\t};\n};\n",
|
|
22
|
+
"import { eq } from 'drizzle-orm';\nimport { bigint, pgTable, text, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tSamlServiceProvider,\n\tSamlServiceProviderStore\n} from './types';\n\nconst ID_LENGTH = 255;\nconst URL_LENGTH = 2048;\n\nexport const samlServiceProvidersTable = pgTable(\n\t'auth_saml_service_providers',\n\t{\n\t\tacs_url: varchar('acs_url', { length: URL_LENGTH }).notNull(),\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\tentity_id: varchar('entity_id', { length: URL_LENGTH }).primaryKey(),\n\t\tname_id_format: varchar('name_id_format', { length: ID_LENGTH }),\n\t\tsigning_cert: text('signing_cert'),\n\t\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull()\n\t}\n);\n\ntype Row = typeof samlServiceProvidersTable.$inferSelect;\n\nconst toServiceProvider = (row: Row): SamlServiceProvider => ({\n\tacsUrl: row.acs_url,\n\tcreatedAt: row.created_at_ms,\n\tentityId: row.entity_id,\n\tnameIdFormat: row.name_id_format ?? undefined,\n\tsigningCert: row.signing_cert ?? undefined,\n\tupdatedAt: row.updated_at_ms\n});\n\nconst toValues = (\n\tserviceProvider: SamlServiceProvider\n): typeof samlServiceProvidersTable.$inferInsert => ({\n\tacs_url: serviceProvider.acsUrl,\n\tcreated_at_ms: serviceProvider.createdAt,\n\tentity_id: serviceProvider.entityId,\n\tname_id_format: serviceProvider.nameIdFormat ?? null,\n\tsigning_cert: serviceProvider.signingCert ?? null,\n\tupdated_at_ms: serviceProvider.updatedAt\n});\n\nexport const createNeonSamlServiceProviderStore = (databaseUrl: string) =>\n\tcreatePostgresSamlServiceProviderStore(createNeonDatabase(databaseUrl));\n\nexport const createPostgresSamlServiceProviderStore = (\n\tdb: AnyPgDatabase\n): SamlServiceProviderStore => ({\n\tdeleteServiceProvider: async (entityId) => {\n\t\tawait db\n\t\t\t.delete(samlServiceProvidersTable)\n\t\t\t.where(eq(samlServiceProvidersTable.entity_id, entityId));\n\t},\n\tfindServiceProvider: async (entityId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(samlServiceProvidersTable)\n\t\t\t.where(eq(samlServiceProvidersTable.entity_id, entityId))\n\t\t\t.limit(1);\n\n\t\treturn row === undefined ? undefined : toServiceProvider(row);\n\t},\n\tlistServiceProviders: async () => {\n\t\tconst rows = await db.select().from(samlServiceProvidersTable);\n\n\t\treturn rows.map(toServiceProvider);\n\t},\n\tsaveServiceProvider: async (serviceProvider) => {\n\t\tawait db\n\t\t\t.insert(samlServiceProvidersTable)\n\t\t\t.values(toValues(serviceProvider))\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: toValues(serviceProvider),\n\t\t\t\ttarget: samlServiceProvidersTable.entity_id\n\t\t\t});\n\t}\n});\n",
|
|
23
|
+
"import { and, desc, eq } from 'drizzle-orm';\nimport { bigint, boolean, jsonb, pgTable, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tOidcConnection,\n\tOidcConnectionConfig,\n\tSamlConnection,\n\tSamlConnectionConfig,\n\tSSOConnection,\n\tSSOConnectionStore,\n\tSSOConnectionType\n} from './types';\n\nconst ID_LENGTH = 255;\nconst TYPE_LENGTH = 16;\n\nexport const ssoConnectionsTable = pgTable('auth_sso_connections', {\n\tconfig: jsonb('config')\n\t\t.$type<OidcConnectionConfig | SamlConnectionConfig>()\n\t\t.notNull(),\n\tconnection_id: varchar('connection_id', { length: ID_LENGTH }).primaryKey(),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tenabled: boolean('enabled').notNull().default(true),\n\torganization_id: varchar('organization_id', {\n\t\tlength: ID_LENGTH\n\t}).notNull(),\n\ttype: varchar('type', { length: TYPE_LENGTH })\n\t\t.$type<SSOConnectionType>()\n\t\t.notNull(),\n\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull()\n});\n\ntype SsoRow = typeof ssoConnectionsTable.$inferSelect;\ntype SsoInsert = typeof ssoConnectionsTable.$inferInsert;\n\nconst toStringArray = (value: unknown) =>\n\tArray.isArray(value)\n\t\t? value.filter((entry): entry is string => typeof entry === 'string')\n\t\t: [];\n\n// Validate the jsonb payload back into the typed config — never trust the column blindly\n// (and never `as`-cast it). Returns undefined for a malformed row.\nconst toOidcConfig = (value: object): OidcConnectionConfig | undefined => {\n\tconst clientId = Reflect.get(value, 'clientId');\n\tconst clientSecret = Reflect.get(value, 'clientSecret');\n\tconst issuer = Reflect.get(value, 'issuer');\n\tconst redirectUri = Reflect.get(value, 'redirectUri');\n\tif (\n\t\ttypeof clientId !== 'string' ||\n\t\ttypeof clientSecret !== 'string' ||\n\t\ttypeof issuer !== 'string' ||\n\t\ttypeof redirectUri !== 'string'\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tclientId,\n\t\tclientSecret,\n\t\tissuer,\n\t\tredirectUri,\n\t\tscopes: toStringArray(Reflect.get(value, 'scopes'))\n\t};\n};\n\nconst toSamlConfig = (value: object): SamlConnectionConfig | undefined => {\n\tconst idpEntityId = Reflect.get(value, 'idpEntityId');\n\tconst idpSsoUrl = Reflect.get(value, 'idpSsoUrl');\n\tconst idpX509Cert = Reflect.get(value, 'idpX509Cert');\n\tif (\n\t\ttypeof idpEntityId !== 'string' ||\n\t\ttypeof idpSsoUrl !== 'string' ||\n\t\ttypeof idpX509Cert !== 'string'\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst idpSloUrl = Reflect.get(value, 'idpSloUrl');\n\n\treturn {\n\t\tidpEntityId,\n\t\tidpSloUrl: typeof idpSloUrl === 'string' ? idpSloUrl : undefined,\n\t\tidpSsoUrl,\n\t\tidpX509Cert\n\t};\n};\n\nconst toConnection = (row: SsoRow) => {\n\tif (row.type === 'oidc') {\n\t\tconst config = toOidcConfig(row.config);\n\t\tif (config === undefined) return undefined;\n\n\t\tconst connection: OidcConnection = {\n\t\t\tconfig,\n\t\t\tconnectionId: row.connection_id,\n\t\t\tcreatedAt: row.created_at_ms,\n\t\t\tenabled: row.enabled,\n\t\t\torganizationId: row.organization_id,\n\t\t\ttype: 'oidc',\n\t\t\tupdatedAt: row.updated_at_ms\n\t\t};\n\n\t\treturn connection;\n\t}\n\n\tconst config = toSamlConfig(row.config);\n\tif (config === undefined) return undefined;\n\n\tconst connection: SamlConnection = {\n\t\tconfig,\n\t\tconnectionId: row.connection_id,\n\t\tcreatedAt: row.created_at_ms,\n\t\tenabled: row.enabled,\n\t\torganizationId: row.organization_id,\n\t\ttype: 'saml',\n\t\tupdatedAt: row.updated_at_ms\n\t};\n\n\treturn connection;\n};\n\nconst toValues = (connection: SSOConnection): SsoInsert => ({\n\tconfig: connection.config,\n\tconnection_id: connection.connectionId,\n\tcreated_at_ms: connection.createdAt,\n\tenabled: connection.enabled,\n\torganization_id: connection.organizationId,\n\ttype: connection.type,\n\tupdated_at_ms: connection.updatedAt\n});\n\nexport const createNeonSsoConnectionStore = (databaseUrl: string) =>\n\tcreatePostgresSsoConnectionStore(createNeonDatabase(databaseUrl));\n\nexport const createPostgresSsoConnectionStore = (\n\tdb: AnyPgDatabase\n): SSOConnectionStore => ({\n\tdeleteConnection: async (connectionId) => {\n\t\tawait db\n\t\t\t.delete(ssoConnectionsTable)\n\t\t\t.where(eq(ssoConnectionsTable.connection_id, connectionId));\n\t},\n\tgetConnection: async (connectionId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(ssoConnectionsTable)\n\t\t\t.where(eq(ssoConnectionsTable.connection_id, connectionId))\n\t\t\t.limit(1);\n\n\t\treturn row ? toConnection(row) : undefined;\n\t},\n\tgetConnectionByOrganization: async (organizationId, type) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(ssoConnectionsTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(ssoConnectionsTable.organization_id, organizationId),\n\t\t\t\t\teq(ssoConnectionsTable.enabled, true),\n\t\t\t\t\ttype === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: eq(ssoConnectionsTable.type, type)\n\t\t\t\t)\n\t\t\t)\n\t\t\t.orderBy(desc(ssoConnectionsTable.updated_at_ms))\n\t\t\t.limit(1);\n\n\t\treturn row ? toConnection(row) : undefined;\n\t},\n\tlistConnectionsByOrganization: async (organizationId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(ssoConnectionsTable)\n\t\t\t.where(eq(ssoConnectionsTable.organization_id, organizationId))\n\t\t\t.orderBy(desc(ssoConnectionsTable.updated_at_ms));\n\n\t\treturn rows.flatMap((row) => {\n\t\t\tconst connection = toConnection(row);\n\n\t\t\treturn connection === undefined ? [] : [connection];\n\t\t});\n\t},\n\tsaveConnection: async (connection) => {\n\t\tconst values = toValues(connection);\n\t\tawait db.insert(ssoConnectionsTable).values(values).onConflictDoUpdate({\n\t\t\tset: values,\n\t\t\ttarget: ssoConnectionsTable.connection_id\n\t\t});\n\t}\n});\n",
|
|
24
|
+
"import { and, eq } from 'drizzle-orm';\nimport { bigint, pgTable, primaryKey, text, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { VaultEntry, VaultStore } from './types';\n\nconst ID_LENGTH = 255;\n\nexport const vaultEntriesTable = pgTable(\n\t'auth_vault_entries',\n\t{\n\t\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\t\tencrypted_value: text('encrypted_value').notNull(),\n\t\tname: varchar('name', { length: ID_LENGTH }).notNull(),\n\t\towner_id: varchar('owner_id', { length: ID_LENGTH }).notNull(),\n\t\tupdated_at_ms: bigint('updated_at_ms', { mode: 'number' }).notNull()\n\t},\n\t(table) => ({ pk: primaryKey({ columns: [table.owner_id, table.name] }) })\n);\n\ntype Row = typeof vaultEntriesTable.$inferSelect;\n\nconst toEntry = (row: Row): VaultEntry => ({\n\tcreatedAt: row.created_at_ms,\n\tencryptedValue: row.encrypted_value,\n\tname: row.name,\n\townerId: row.owner_id,\n\tupdatedAt: row.updated_at_ms\n});\n\nexport const createNeonVaultStore = (databaseUrl: string) =>\n\tcreatePostgresVaultStore(createNeonDatabase(databaseUrl));\nexport const createPostgresVaultStore = (db: AnyPgDatabase): VaultStore => ({\n\tdeleteEntry: async (ownerId, name) => {\n\t\tawait db\n\t\t\t.delete(vaultEntriesTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(vaultEntriesTable.owner_id, ownerId),\n\t\t\t\t\teq(vaultEntriesTable.name, name)\n\t\t\t\t)\n\t\t\t);\n\t},\n\tgetEntry: async (ownerId, name) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(vaultEntriesTable)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(vaultEntriesTable.owner_id, ownerId),\n\t\t\t\t\teq(vaultEntriesTable.name, name)\n\t\t\t\t)\n\t\t\t);\n\n\t\treturn row ? toEntry(row) : undefined;\n\t},\n\tlistAllEntries: async () => {\n\t\tconst rows = await db.select().from(vaultEntriesTable);\n\n\t\treturn rows.map(toEntry);\n\t},\n\tlistEntries: async (ownerId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(vaultEntriesTable)\n\t\t\t.where(eq(vaultEntriesTable.owner_id, ownerId));\n\n\t\treturn rows.map(toEntry);\n\t},\n\tsaveEntry: async (entry) => {\n\t\tawait db\n\t\t\t.insert(vaultEntriesTable)\n\t\t\t.values({\n\t\t\t\tcreated_at_ms: entry.createdAt,\n\t\t\t\tencrypted_value: entry.encryptedValue,\n\t\t\t\tname: entry.name,\n\t\t\t\towner_id: entry.ownerId,\n\t\t\t\tupdated_at_ms: entry.updatedAt\n\t\t\t})\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: {\n\t\t\t\t\tencrypted_value: entry.encryptedValue,\n\t\t\t\t\tupdated_at_ms: entry.updatedAt\n\t\t\t\t},\n\t\t\t\ttarget: [vaultEntriesTable.owner_id, vaultEntriesTable.name]\n\t\t\t});\n\t}\n});\n",
|
|
25
|
+
"import { eq } from 'drizzle-orm';\nimport {\n\tbigint,\n\tboolean,\n\tjsonb,\n\tpgTable,\n\ttext,\n\tvarchar\n} from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type { WebAuthnCredential, WebAuthnCredentialStore } from './types';\n\nconst ID_LENGTH = 255;\nconst DEVICE_TYPE_LENGTH = 32;\n\nexport const webauthnCredentialsTable = pgTable('auth_webauthn_credentials', {\n\tbacked_up: boolean('backed_up'),\n\tcounter: bigint('counter', { mode: 'number' }).notNull().default(0),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tcredential_id: varchar('credential_id', { length: ID_LENGTH }).primaryKey(),\n\tdevice_type: varchar('device_type', { length: DEVICE_TYPE_LENGTH }),\n\tlast_used_at_ms: bigint('last_used_at_ms', { mode: 'number' }),\n\tpublic_key: text('public_key').notNull(),\n\ttransports: jsonb('transports').$type<string[]>(),\n\tuser_id: varchar('user_id', { length: ID_LENGTH }).notNull()\n});\n\ntype WebAuthnRow = typeof webauthnCredentialsTable.$inferSelect;\ntype WebAuthnInsert = typeof webauthnCredentialsTable.$inferInsert;\n\nconst toCredential = (row: WebAuthnRow): WebAuthnCredential => ({\n\tbackedUp: row.backed_up ?? undefined,\n\tcounter: row.counter,\n\tcreatedAt: row.created_at_ms,\n\tcredentialId: row.credential_id,\n\tdeviceType: row.device_type ?? undefined,\n\tlastUsedAt: row.last_used_at_ms ?? undefined,\n\tpublicKey: row.public_key,\n\ttransports: row.transports ?? undefined,\n\tuserId: row.user_id\n});\n\nconst toValues = (credential: WebAuthnCredential): WebAuthnInsert => ({\n\tbacked_up: credential.backedUp ?? null,\n\tcounter: credential.counter,\n\tcreated_at_ms: credential.createdAt,\n\tcredential_id: credential.credentialId,\n\tdevice_type: credential.deviceType ?? null,\n\tlast_used_at_ms: credential.lastUsedAt ?? null,\n\tpublic_key: credential.publicKey,\n\ttransports: credential.transports ?? null,\n\tuser_id: credential.userId\n});\n\nexport const createNeonWebAuthnCredentialStore = (databaseUrl: string) =>\n\tcreatePostgresWebAuthnCredentialStore(createNeonDatabase(databaseUrl));\nexport const createPostgresWebAuthnCredentialStore = (\n\tdb: AnyPgDatabase\n): WebAuthnCredentialStore => ({\n\tgetCredential: async (credentialId) => {\n\t\tconst [row] = await db\n\t\t\t.select()\n\t\t\t.from(webauthnCredentialsTable)\n\t\t\t.where(eq(webauthnCredentialsTable.credential_id, credentialId))\n\t\t\t.limit(1);\n\n\t\treturn row ? toCredential(row) : undefined;\n\t},\n\tlistCredentialsByUser: async (userId) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(webauthnCredentialsTable)\n\t\t\t.where(eq(webauthnCredentialsTable.user_id, userId));\n\n\t\treturn rows.map(toCredential);\n\t},\n\tremoveCredential: async (credentialId) => {\n\t\tawait db\n\t\t\t.delete(webauthnCredentialsTable)\n\t\t\t.where(eq(webauthnCredentialsTable.credential_id, credentialId));\n\t},\n\tsaveCredential: async (credential) => {\n\t\tconst values = toValues(credential);\n\t\tawait db\n\t\t\t.insert(webauthnCredentialsTable)\n\t\t\t.values(values)\n\t\t\t.onConflictDoUpdate({\n\t\t\t\tset: values,\n\t\t\t\ttarget: webauthnCredentialsTable.credential_id\n\t\t\t});\n\t}\n});\n",
|
|
26
|
+
"import { desc, eq } from 'drizzle-orm';\nimport { bigint, jsonb, pgTable, text, varchar } from 'drizzle-orm/pg-core';\nimport { type AnyPgDatabase, createNeonDatabase } from '../stores/postgres';\nimport type {\n\tWebhookDelivery,\n\tWebhookDeliveryStore,\n\tWebhookEvent\n} from './types';\n\nconst ID_LENGTH = 255;\nconst URL_LENGTH = 2048;\nconst DEFAULT_LIST_LIMIT = 100;\n\nexport const webhookDeliveriesTable = pgTable('auth_webhook_deliveries', {\n\tattempts: bigint('attempts', { mode: 'number' }).notNull(),\n\tcreated_at_ms: bigint('created_at_ms', { mode: 'number' }).notNull(),\n\tendpoint_url: varchar('endpoint_url', { length: URL_LENGTH }).notNull(),\n\tenvelope_id: varchar('envelope_id', { length: ID_LENGTH }).primaryKey(),\n\tenvelope_json: jsonb('envelope_json').$type<WebhookEvent>().notNull(),\n\tlast_error: text('last_error'),\n\tlast_status: bigint('last_status', { mode: 'number' })\n});\n\ntype DeliveryRow = typeof webhookDeliveriesTable.$inferSelect;\n\nconst toDelivery = (row: DeliveryRow): WebhookDelivery => ({\n\tattempts: row.attempts,\n\tcreatedAt: row.created_at_ms,\n\tendpointUrl: row.endpoint_url,\n\tenvelope: row.envelope_json,\n\tlastError: row.last_error ?? undefined,\n\tlastStatus: row.last_status ?? undefined\n});\n\nexport const createNeonWebhookDeliveryStore = (databaseUrl: string) =>\n\tcreatePostgresWebhookDeliveryStore(createNeonDatabase(databaseUrl));\n\nexport const createPostgresWebhookDeliveryStore = (\n\tdb: AnyPgDatabase\n): WebhookDeliveryStore => ({\n\tlistFailed: async (limit = DEFAULT_LIST_LIMIT) => {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(webhookDeliveriesTable)\n\t\t\t.orderBy(desc(webhookDeliveriesTable.created_at_ms))\n\t\t\t.limit(limit);\n\n\t\treturn rows.map(toDelivery);\n\t},\n\trecordFailure: async (delivery) => {\n\t\tawait db.insert(webhookDeliveriesTable).values({\n\t\t\tattempts: delivery.attempts,\n\t\t\tcreated_at_ms: delivery.createdAt,\n\t\t\tendpoint_url: delivery.endpointUrl,\n\t\t\tenvelope_id: delivery.envelope.id,\n\t\t\tenvelope_json: delivery.envelope,\n\t\t\tlast_error: delivery.lastError ?? null,\n\t\t\tlast_status: delivery.lastStatus ?? null\n\t\t});\n\t},\n\tremoveFailure: async (envelopeId) => {\n\t\tawait db\n\t\t\t.delete(webhookDeliveriesTable)\n\t\t\t.where(eq(webhookDeliveriesTable.envelope_id, envelopeId));\n\t}\n});\n",
|
|
27
|
+
"// Translate the package's existing `pgTable` definitions into `CREATE TABLE IF NOT EXISTS`\n// SQL, so each block's migration is derived from the same drizzle schema the runtime store\n// already uses. Eliminates the transcription-drift risk of hand-writing CREATE TABLEs that\n// have to stay in sync with the table definitions in `src/<block>/postgresStores.ts`.\n//\n// What this covers: column name + type + nullability + default + primary key + unique +\n// composite primary key. Doesn't cover: foreign keys (none of the package's tables use\n// them across blocks — sub-keys are referenced by id without referential integrity),\n// indices (consumers can add their own per their workload), check constraints (none in\n// the schema). If a block ever needs any of those, hand-write that migration entry\n// alongside the auto-generated one.\n\nimport { is, SQL } from 'drizzle-orm';\nimport {\n\tgetTableConfig,\n\ttype PgColumn,\n\ttype PgTable\n} from 'drizzle-orm/pg-core';\n\n// Defaults declared with drizzle's `sql\\`...\\`` template are `SQL` objects; render them as\n// raw SQL expressions (e.g. `now()`) instead of letting them fall into the generic-object\n// JSON branch, which would emit a `{\"queryChunks\":[...]}::jsonb` literal.\nconst renderChunk = (chunk: unknown) => {\n\tif (chunk === null || typeof chunk !== 'object') return String(chunk);\n\tconst value = Reflect.get(chunk, 'value');\n\tif (Array.isArray(value)) return value.map((part) => String(part)).join('');\n\n\treturn '';\n};\n\nconst formatSqlTemplate = (value: SQL) =>\n\tvalue.queryChunks.map(renderChunk).join('');\n\nconst formatDefault = (value: unknown) => {\n\tif (value === null || value === undefined) return 'NULL';\n\tif (is(value, SQL)) return formatSqlTemplate(value);\n\tif (typeof value === 'string') return `'${value.replace(/'/gu, \"''\")}'`;\n\tif (typeof value === 'boolean') return value ? 'true' : 'false';\n\tif (typeof value === 'number') return String(value);\n\tif (Array.isArray(value) || typeof value === 'object') {\n\t\treturn `'${JSON.stringify(value)}'::jsonb`;\n\t}\n\n\treturn String(value);\n};\n\nconst columnSql = (column: PgColumn) => {\n\tconst parts = [`\"${column.name}\"`, column.getSQLType()];\n\tif (column.primary) parts.push('PRIMARY KEY');\n\tif (column.notNull && !column.primary) parts.push('NOT NULL');\n\tif (column.hasDefault && column.default !== undefined) {\n\t\tparts.push(`DEFAULT ${formatDefault(column.default)}`);\n\t}\n\tif (column.isUnique) parts.push('UNIQUE');\n\n\treturn parts.join(' ');\n};\n\nconst compositePkLine = (compositePk: readonly PgColumn[]) =>\n\t`PRIMARY KEY (${compositePk.map((column) => `\"${column.name}\"`).join(', ')})`;\n\n// Emit a single `CREATE TABLE IF NOT EXISTS` for one table. Idempotent — re-running is a\n// no-op even when the consumer already wired the table by hand. The composite-PK case is\n// handled separately because Drizzle splits it out of the column metadata.\nconst tableToCreateSql = (table: PgTable) => {\n\tconst cfg = getTableConfig(table);\n\tconst columnLines = cfg.columns.map(columnSql);\n\tconst singlePk = cfg.columns.find((column) => column.primary);\n\tconst compositePk = cfg.primaryKeys[0]?.columns ?? [];\n\tconst lines =\n\t\tsinglePk === undefined && compositePk.length > 0\n\t\t\t? [...columnLines, compositePkLine(compositePk)]\n\t\t\t: columnLines;\n\tconst body = lines.map((line) => `\\t${line}`).join(',\\n');\n\n\treturn `CREATE TABLE IF NOT EXISTS \"${cfg.name}\" (\\n${body}\\n);`;\n};\n\n// Block migrations are always declared as one `0001_init` covering every table the block\n// owns + (rare) hand-written follow-up ids for schema changes. This helper does the init\n// step — pass every table you want included.\nexport const tablesToInitSql = (tables: PgTable[]) =>\n\ttables.map(tableToCreateSql).join('\\n\\n');\n",
|
|
28
|
+
"// Migration runner. Uses `@neondatabase/serverless`'s Pool (already a package dep) so\n// consumers don't need to install drizzle-kit or a separate migrator. The Pool client\n// supports multi-statement queries (a block's init migration emits one CREATE TABLE per\n// table joined by `;`), which the HTTP `neon()` function does not.\n//\n// Tracks applied migrations in an `auth_migrations` table keyed by `${block}/${id}`.\n// Idempotent — re-running is a no-op when everything's been applied.\n//\n// Consumers can invoke programmatically (`await runMigrations({ databaseUrl })`) at boot\n// or via the bundled CLI (`bunx absolute-auth migrate --db $DATABASE_URL`).\n\nimport { Pool } from '@neondatabase/serverless';\nimport { blockMigrations, type BlockName } from './index';\n\nexport type RunMigrationsOptions = {\n\tdatabaseUrl: string;\n\t/** Subset of blocks to apply. Omit to apply every block the package ships. */\n\tblocks?: BlockName[];\n\t/** Optional logger; defaults to console.log. Pass `() => undefined` for silent mode. */\n\tlog?: (message: string) => void;\n};\n\nexport type MigrationRunResult = {\n\tapplied: string[];\n\tskipped: string[];\n};\n\nconst JOURNAL_DDL = `CREATE TABLE IF NOT EXISTS \"auth_migrations\" (\n\t\"id\" text PRIMARY KEY,\n\t\"applied_at_ms\" bigint NOT NULL\n);`;\n\ntype JournalRow = { id: string };\n\nconst isJournalRow = (value: unknown): value is JournalRow =>\n\ttypeof value === 'object' &&\n\tvalue !== null &&\n\ttypeof Reflect.get(value, 'id') === 'string';\n\nconst allBlockNames = () =>\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Object.keys widens to string[]; the values are typed BlockName by construction of the manifest\n\tObject.keys(blockMigrations) as BlockName[];\n\nconst applyOne = async (\n\tpool: Pool,\n\tid: string,\n\tsql: string,\n\tlog: (message: string) => void\n) => {\n\tawait pool.query(sql);\n\tawait pool.query(\n\t\t`INSERT INTO \"auth_migrations\" (\"id\", \"applied_at_ms\") VALUES ($1, $2)`,\n\t\t[id, Date.now()]\n\t);\n\tlog(`apply ${id}`);\n};\n\nconst runOne = async (\n\tpool: Pool,\n\tid: string,\n\tsql: string,\n\tapplied: Set<string>,\n\tresult: MigrationRunResult,\n\tlog: (message: string) => void\n) => {\n\tif (applied.has(id)) {\n\t\tresult.skipped.push(id);\n\t\tlog(`skip ${id}`);\n\n\t\treturn;\n\t}\n\tawait applyOne(pool, id, sql, log);\n\tresult.applied.push(id);\n};\n\nexport const runMigrations = async ({\n\tblocks,\n\tdatabaseUrl,\n\tlog = console.log\n}: RunMigrationsOptions) => {\n\tconst pool = new Pool({ connectionString: databaseUrl });\n\tconst result: MigrationRunResult = { applied: [], skipped: [] };\n\n\ttry {\n\t\tawait pool.query(JOURNAL_DDL);\n\t\tconst journal = await pool.query(`SELECT \"id\" FROM \"auth_migrations\"`);\n\t\tconst applied = new Set(\n\t\t\tjournal.rows.filter(isJournalRow).map((row) => row.id)\n\t\t);\n\n\t\tconst selected = blocks ?? allBlockNames();\n\t\tconst flat = selected.flatMap((block) =>\n\t\t\tblockMigrations[block].migrations.map((migration) => ({\n\t\t\t\tid: `${block}/${migration.id}`,\n\t\t\t\tsql: migration.sql\n\t\t\t}))\n\t\t);\n\n\t\tawait flat.reduce(async (prior, item) => {\n\t\t\tawait prior;\n\n\t\t\treturn runOne(pool, item.id, item.sql, applied, result, log);\n\t\t}, Promise.resolve());\n\t} finally {\n\t\tawait pool.end();\n\t}\n\n\treturn result;\n};\n",
|
|
29
|
+
"// Single export of every block's migrations. Consumers pick which blocks they enabled\n// in `auth()` and pass that subset to `runMigrations({ blocks: [...] })`, or omit `blocks`\n// to apply every migration the package ships. Adding a new block's migrations: import its\n// tables here + add to the `blockMigrations` map.\n\nimport { knownDevicesTable, loginHistoryTable } from '../adaptive/postgresStores';\nimport {\n\taccessTokensTable,\n\tapiClientsTable,\n\tapiKeysTable\n} from '../apikeys/postgresStores';\nimport { auditEventsTable } from '../audit/postgresAuditStore';\nimport {\n\tcredentialResetTokensTable,\n\tcredentialVerificationTokensTable,\n\tcredentialsTable\n} from '../credentials/postgresCredentialStore';\nimport { warrantsTable } from '../fga/postgresStores';\nimport {\n\tlinkedProviderBindingsTable,\n\tlinkedProviderGrantsTable\n} from '../linkedProviders/neonStores';\nimport { lockoutsTable } from '../lockout/postgresLockoutStore';\nimport { mfaEnrollmentsTable } from '../mfa/postgresMfaStore';\nimport {\n\toauthClientAssertionJtisTable,\n\toauthClientRegistrationTokensTable,\n\toauthClientsTable,\n\toauthCodesTable,\n\toauthDeviceAuthorizationsTable,\n\toauthInitialAccessTokensTable,\n\toauthLogoutDeliveriesTable,\n\toauthPushedAuthorizationRequestsTable,\n\toauthRefreshTokensTable\n} from '../oidc/postgresStores';\nimport {\n\torganizationInvitationsTable,\n\torganizationMembershipsTable,\n\torganizationsTable\n} from '../organizations/postgresOrganizationStore';\nimport { passwordlessTokensTable } from '../passwordless/postgresPasswordlessTokenStore';\nimport { setupSessionsTable } from '../portal/postgresSetupSessionStore';\nimport { rolesTable } from '../roles/postgresRoleStore';\nimport { scimTokensTable } from '../scim/postgresScimTokenStore';\nimport {\n\tauthSessionsTable,\n\tauthUnregisteredSessionsTable\n} from '../session/neonStore';\nimport { samlServiceProvidersTable } from '../sso/postgresSamlServiceProviderStore';\nimport { ssoConnectionsTable } from '../sso/postgresSsoConnectionStore';\nimport { vaultEntriesTable } from '../vault/postgresVaultStore';\nimport { webauthnCredentialsTable } from '../webauthn/postgresWebAuthnCredentialStore';\nimport { webhookDeliveriesTable } from '../webhooks/postgresStore';\nimport { tablesToInitSql } from './generate';\nimport type { BlockMigrations } from './types';\n\nexport type BlockName =\n\t| 'adaptive'\n\t| 'apikeys'\n\t| 'audit'\n\t| 'credentials'\n\t| 'fga'\n\t| 'linkedProviders'\n\t| 'lockout'\n\t| 'mfa'\n\t| 'oidc'\n\t| 'organizations'\n\t| 'passwordless'\n\t| 'portal'\n\t| 'roles'\n\t| 'scim'\n\t| 'sessions'\n\t| 'sso'\n\t| 'vault'\n\t| 'webauthn'\n\t| 'webhooks';\n\nconst initMigration = (block: BlockName, tables: Parameters<typeof tablesToInitSql>[0]): BlockMigrations => ({\n\tblock,\n\tmigrations: [{ id: '0001_init', sql: tablesToInitSql(tables) }]\n});\n\nexport const blockMigrations: Record<BlockName, BlockMigrations> = {\n\tadaptive: initMigration('adaptive', [knownDevicesTable, loginHistoryTable]),\n\tapikeys: initMigration('apikeys', [\n\t\taccessTokensTable,\n\t\tapiClientsTable,\n\t\tapiKeysTable\n\t]),\n\taudit: initMigration('audit', [auditEventsTable]),\n\tcredentials: initMigration('credentials', [\n\t\tcredentialsTable,\n\t\tcredentialResetTokensTable,\n\t\tcredentialVerificationTokensTable\n\t]),\n\tfga: initMigration('fga', [warrantsTable]),\n\tlinkedProviders: initMigration('linkedProviders', [\n\t\tlinkedProviderBindingsTable,\n\t\tlinkedProviderGrantsTable\n\t]),\n\tlockout: initMigration('lockout', [lockoutsTable]),\n\tmfa: initMigration('mfa', [mfaEnrollmentsTable]),\n\toidc: initMigration('oidc', [\n\t\toauthClientAssertionJtisTable,\n\t\toauthClientRegistrationTokensTable,\n\t\toauthClientsTable,\n\t\toauthCodesTable,\n\t\toauthDeviceAuthorizationsTable,\n\t\toauthInitialAccessTokensTable,\n\t\toauthLogoutDeliveriesTable,\n\t\toauthPushedAuthorizationRequestsTable,\n\t\toauthRefreshTokensTable\n\t]),\n\torganizations: initMigration('organizations', [\n\t\torganizationsTable,\n\t\torganizationMembershipsTable,\n\t\torganizationInvitationsTable\n\t]),\n\tpasswordless: initMigration('passwordless', [passwordlessTokensTable]),\n\tportal: initMigration('portal', [setupSessionsTable]),\n\troles: initMigration('roles', [rolesTable]),\n\tscim: initMigration('scim', [scimTokensTable]),\n\tsessions: initMigration('sessions', [\n\t\tauthSessionsTable,\n\t\tauthUnregisteredSessionsTable\n\t]),\n\tsso: initMigration('sso', [ssoConnectionsTable, samlServiceProvidersTable]),\n\tvault: initMigration('vault', [vaultEntriesTable]),\n\twebauthn: initMigration('webauthn', [webauthnCredentialsTable]),\n\twebhooks: initMigration('webhooks', [webhookDeliveriesTable])\n};\n\nexport { runMigrations } from './runner';\nexport type { Migration, BlockMigrations } from './types';\n",
|
|
30
|
+
"#!/usr/bin/env bun\n// CLI entry for the migration runner. Invocation:\n// bunx absolute-auth migrate --db $DATABASE_URL\n// bunx absolute-auth migrate --db $DATABASE_URL --blocks credentials,mfa,sessions\n// bunx absolute-auth migrate --help\n//\n// Resolves --db from --db / --database-url flags or the DATABASE_URL env var. --blocks is\n// an optional comma-separated list; omit to apply every block the package ships.\n\nimport { blockMigrations, type BlockName, runMigrations } from '../migrations';\n\nconst USAGE = `Usage:\n bunx absolute-auth migrate --db <url> [--blocks block1,block2,...]\n\nOptions:\n --db, --database-url Postgres connection string (falls back to DATABASE_URL env)\n --blocks Comma-separated subset of blocks to apply (default: all)\n --help Print this message\n\nAvailable blocks: ${Object.keys(blockMigrations).sort().join(', ')}\n`;\n\ntype ParsedArgs = {\n\tblocks: BlockName[] | undefined;\n\tdatabaseUrl: string | undefined;\n\thelp: boolean;\n};\n\nconst consumeFlag = (\n\tparsed: ParsedArgs,\n\tflag: string | undefined,\n\targs: string[]\n) => {\n\tif (flag === '--help' || flag === '-h') {\n\t\tparsed.help = true;\n\t} else if (flag === '--db' || flag === '--database-url') {\n\t\tparsed.databaseUrl = args.shift();\n\t} else if (flag === '--blocks') {\n\t\tconst list = args.shift() ?? '';\n\t\tparsed.blocks = list\n\t\t\t.split(',')\n\t\t\t.map((entry) => entry.trim())\n\t\t\t.filter((entry) => entry.length > 0)\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- validated against blockMigrations keys below\n\t\t\t.map((entry) => entry as BlockName);\n\t}\n};\n\nconst parseArgs = (argv: string[]) => {\n\tconst parsed: ParsedArgs = {\n\t\tblocks: undefined,\n\t\tdatabaseUrl: undefined,\n\t\thelp: false\n\t};\n\tconst args = [...argv];\n\twhile (args.length > 0) {\n\t\tconsumeFlag(parsed, args.shift(), args);\n\t}\n\n\treturn parsed;\n};\n\nconst die = (message: string) => {\n\tprocess.stderr.write(`error: ${message}\\n\\n`);\n\tprocess.stderr.write(USAGE);\n\tprocess.exit(1);\n};\n\nconst main = async () => {\n\tconst positional = process.argv.slice(2);\n\tif (positional[0] === 'migrate') positional.shift();\n\tconst { blocks, databaseUrl, help } = parseArgs(positional);\n\n\tif (help) {\n\t\tprocess.stdout.write(USAGE);\n\n\t\treturn;\n\t}\n\n\tconst resolved = databaseUrl ?? process.env['DATABASE_URL'];\n\tif (resolved === undefined || resolved.length === 0) {\n\t\tdie('a Postgres URL is required (--db or DATABASE_URL)');\n\n\t\treturn;\n\t}\n\n\tconst unknown = blocks?.filter((block) => !(block in blockMigrations)) ?? [];\n\tif (unknown.length > 0) {\n\t\tdie(`unknown block(s): ${unknown.join(', ')}`);\n\n\t\treturn;\n\t}\n\n\tconst result = await runMigrations({ blocks, databaseUrl: resolved });\n\tprocess.stdout.write(\n\t\t`\\n${result.applied.length} migration(s) applied, ${result.skipped.length} skipped.\\n`\n\t);\n};\n\nawait main();\n"
|
|
31
|
+
],
|
|
32
|
+
"mappings": "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",
|
|
33
|
+
"debugId": "562323D9670B702364756E2164756E21",
|
|
34
|
+
"names": []
|
|
35
|
+
}
|