Files
simstudioai--sim/packages/db/scripts/deregister-sso-provider.ts
T
wehub-resource-sync d25d482dc2
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:20:55 +08:00

172 lines
5.1 KiB
TypeScript

#!/usr/bin/env bun
/**
* Deregister SSO Provider Script
*
* This script removes an SSO provider from the database for a specific user.
*
* Usage: bun run packages/db/scripts/deregister-sso-provider.ts
*
* Required Environment Variables:
* DATABASE_URL=your-database-url
* SSO_USER_EMAIL=user@domain.com (user whose SSO provider to remove)
* SSO_PROVIDER_ID=provider-id (optional, if not provided will remove all providers for user)
*/
import { getErrorMessage } from '@sim/utils/errors'
import { and, eq } from 'drizzle-orm'
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import { ssoProvider, user } from '../schema'
const logger = {
info: (message: string, meta?: any) => {
const timestamp = new Date().toISOString()
console.log(
`[${timestamp}] [INFO] [DeregisterSSODB] ${message}`,
meta ? JSON.stringify(meta, null, 2) : ''
)
},
error: (message: string, meta?: any) => {
const timestamp = new Date().toISOString()
console.error(
`[${timestamp}] [ERROR] [DeregisterSSODB] ${message}`,
meta ? JSON.stringify(meta, null, 2) : ''
)
},
warn: (message: string, meta?: any) => {
const timestamp = new Date().toISOString()
console.warn(
`[${timestamp}] [WARN] [DeregisterSSODB] ${message}`,
meta ? JSON.stringify(meta, null, 2) : ''
)
},
}
const CONNECTION_STRING = process.env.POSTGRES_URL ?? process.env.DATABASE_URL
if (!CONNECTION_STRING) {
console.error('❌ POSTGRES_URL or DATABASE_URL environment variable is required')
process.exit(1)
}
const postgresClient = postgres(CONNECTION_STRING, {
prepare: false,
idle_timeout: 20,
connect_timeout: 30,
max: 10,
onnotice: () => {},
})
const db = drizzle(postgresClient)
async function getUser(email: string): Promise<{ id: string; email: string } | null> {
try {
const users = await db.select().from(user).where(eq(user.email, email))
if (users.length === 0) {
logger.error(`No user found with email: ${email}`)
return null
}
return { id: users[0].id, email: users[0].email }
} catch (error) {
logger.error('Failed to query user:', error)
return null
}
}
async function deregisterSSOProvider(): Promise<boolean> {
try {
const userEmail = process.env.SSO_USER_EMAIL
if (!userEmail) {
logger.error('❌ SSO_USER_EMAIL environment variable is required')
logger.error('')
logger.error('Example usage:')
logger.error(
' SSO_USER_EMAIL=admin@company.com bun run packages/db/scripts/deregister-sso-provider.ts'
)
logger.error('')
logger.error('Optional: SSO_PROVIDER_ID=provider-id (to remove specific provider)')
return false
}
const targetUser = await getUser(userEmail)
if (!targetUser) {
return false
}
logger.info(`Found user: ${targetUser.email} (ID: ${targetUser.id})`)
const providers = await db
.select()
.from(ssoProvider)
.where(eq(ssoProvider.userId, targetUser.id))
if (providers.length === 0) {
logger.warn(`No SSO providers found for user: ${targetUser.email}`)
return false
}
logger.info(`Found ${providers.length} SSO provider(s) for user ${targetUser.email}`)
for (const provider of providers) {
logger.info(` - Provider ID: ${provider.providerId}, Domain: ${provider.domain}`)
}
const specificProviderId = process.env.SSO_PROVIDER_ID
if (specificProviderId) {
const providerToDelete = providers.find((p) => p.providerId === specificProviderId)
if (!providerToDelete) {
logger.error(`Provider '${specificProviderId}' not found for user ${targetUser.email}`)
return false
}
await db
.delete(ssoProvider)
.where(
and(eq(ssoProvider.userId, targetUser.id), eq(ssoProvider.providerId, specificProviderId))
)
logger.info(
`✅ Successfully deleted SSO provider '${specificProviderId}' for user ${targetUser.email}`
)
} else {
await db.delete(ssoProvider).where(eq(ssoProvider.userId, targetUser.id))
logger.info(
`✅ Successfully deleted all ${providers.length} SSO provider(s) for user ${targetUser.email}`
)
}
return true
} catch (error) {
logger.error('❌ Failed to deregister SSO provider:', {
error: getErrorMessage(error, 'Unknown error'),
stack: error instanceof Error ? error.stack : undefined,
})
return false
} finally {
try {
await postgresClient.end({ timeout: 5 })
} catch {}
}
}
async function main() {
console.log('🗑️ Deregister SSO Provider Script')
console.log('====================================')
console.log('This script removes SSO provider records from the database.\n')
const success = await deregisterSSOProvider()
if (success) {
console.log('\n🎉 SSO provider deregistration completed successfully!')
process.exit(0)
} else {
console.log('\n💥 SSO deregistration failed. Check the logs above for details.')
process.exit(1)
}
}
main().catch((error) => {
logger.error('Script execution failed:', { error })
process.exit(1)
})