mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
chore(oauth): remove unused github-repo generic OAuth provider (#3543)
This commit is contained in:
@@ -492,7 +492,7 @@ export const auth = betterAuth({
|
||||
'google-meet',
|
||||
'google-tasks',
|
||||
'vertex-ai',
|
||||
'github-repo',
|
||||
|
||||
'microsoft-dataverse',
|
||||
'microsoft-teams',
|
||||
'microsoft-excel',
|
||||
@@ -754,83 +754,6 @@ export const auth = betterAuth({
|
||||
}),
|
||||
genericOAuth({
|
||||
config: [
|
||||
{
|
||||
providerId: 'github-repo',
|
||||
clientId: env.GITHUB_REPO_CLIENT_ID as string,
|
||||
clientSecret: env.GITHUB_REPO_CLIENT_SECRET as string,
|
||||
authorizationUrl: 'https://github.com/login/oauth/authorize',
|
||||
accessType: 'offline',
|
||||
prompt: 'consent',
|
||||
tokenUrl: 'https://github.com/login/oauth/access_token',
|
||||
userInfoUrl: 'https://api.github.com/user',
|
||||
scopes: getCanonicalScopesForProvider('github-repo'),
|
||||
redirectURI: `${getBaseUrl()}/api/auth/oauth2/callback/github-repo`,
|
||||
getUserInfo: async (tokens) => {
|
||||
try {
|
||||
const profileResponse = await fetch('https://api.github.com/user', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens.accessToken}`,
|
||||
'User-Agent': 'sim-studio',
|
||||
},
|
||||
})
|
||||
|
||||
if (!profileResponse.ok) {
|
||||
await profileResponse.text().catch(() => {})
|
||||
logger.error('Failed to fetch GitHub profile', {
|
||||
status: profileResponse.status,
|
||||
statusText: profileResponse.statusText,
|
||||
})
|
||||
throw new Error(`Failed to fetch GitHub profile: ${profileResponse.statusText}`)
|
||||
}
|
||||
|
||||
const profile = await profileResponse.json()
|
||||
|
||||
if (!profile.email) {
|
||||
const emailsResponse = await fetch('https://api.github.com/user/emails', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens.accessToken}`,
|
||||
'User-Agent': 'sim-studio',
|
||||
},
|
||||
})
|
||||
|
||||
if (emailsResponse.ok) {
|
||||
const emails = await emailsResponse.json()
|
||||
|
||||
const primaryEmail =
|
||||
emails.find(
|
||||
(email: { primary: boolean; email: string; verified: boolean }) =>
|
||||
email.primary
|
||||
) || emails[0]
|
||||
if (primaryEmail) {
|
||||
profile.email = primaryEmail.email
|
||||
profile.emailVerified = primaryEmail.verified || false
|
||||
}
|
||||
} else {
|
||||
logger.warn('Failed to fetch GitHub emails', {
|
||||
status: emailsResponse.status,
|
||||
statusText: emailsResponse.statusText,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const now = new Date()
|
||||
|
||||
return {
|
||||
id: `${profile.id.toString()}-${crypto.randomUUID()}`,
|
||||
name: profile.name || profile.login,
|
||||
email: profile.email,
|
||||
image: profile.avatar_url,
|
||||
emailVerified: profile.emailVerified || false,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error in GitHub getUserInfo', { error })
|
||||
throw error
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// Google providers
|
||||
{
|
||||
providerId: 'google-email',
|
||||
|
||||
@@ -230,8 +230,7 @@ export const env = createEnv({
|
||||
GOOGLE_CLIENT_SECRET: z.string().optional(), // Google OAuth client secret
|
||||
GITHUB_CLIENT_ID: z.string().optional(), // GitHub OAuth client ID for GitHub integration
|
||||
GITHUB_CLIENT_SECRET: z.string().optional(), // GitHub OAuth client secret
|
||||
GITHUB_REPO_CLIENT_ID: z.string().optional(), // GitHub OAuth client ID for repo access
|
||||
GITHUB_REPO_CLIENT_SECRET: z.string().optional(), // GitHub OAuth client secret for repo access
|
||||
|
||||
X_CLIENT_ID: z.string().optional(), // X (Twitter) OAuth client ID
|
||||
X_CLIENT_SECRET: z.string().optional(), // X (Twitter) OAuth client secret
|
||||
CONFLUENCE_CLIENT_ID: z.string().optional(), // Atlassian Confluence OAuth client ID
|
||||
|
||||
@@ -170,11 +170,6 @@ describe('OAuth Token Refresh', () => {
|
||||
describe('Body Credential Providers', () => {
|
||||
const bodyCredentialProviders = [
|
||||
{ name: 'Google', providerId: 'google', endpoint: 'https://oauth2.googleapis.com/token' },
|
||||
{
|
||||
name: 'GitHub',
|
||||
providerId: 'github',
|
||||
endpoint: 'https://github.com/login/oauth/access_token',
|
||||
},
|
||||
{
|
||||
name: 'Microsoft',
|
||||
providerId: 'microsoft',
|
||||
@@ -279,19 +274,6 @@ describe('OAuth Token Refresh', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it.concurrent('should include Accept header for GitHub requests', async () => {
|
||||
const mockFetch = createMockFetch(defaultOAuthResponse)
|
||||
const refreshToken = 'test_refresh_token'
|
||||
|
||||
await withMockFetch(mockFetch, () => refreshOAuthToken('github', refreshToken))
|
||||
|
||||
const [, requestOptions] = mockFetch.mock.calls[0] as [
|
||||
string,
|
||||
{ headers: Record<string, string>; body: string },
|
||||
]
|
||||
expect(requestOptions.headers.Accept).toBe('application/json')
|
||||
})
|
||||
|
||||
it.concurrent('should include User-Agent header for Reddit requests', async () => {
|
||||
const mockFetch = createMockFetch(defaultOAuthResponse)
|
||||
const refreshToken = 'test_refresh_token'
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
CalComIcon,
|
||||
ConfluenceIcon,
|
||||
DropboxIcon,
|
||||
GithubIcon,
|
||||
GmailIcon,
|
||||
GoogleBigQueryIcon,
|
||||
GoogleCalendarIcon,
|
||||
@@ -340,21 +339,6 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
|
||||
},
|
||||
defaultService: 'outlook',
|
||||
},
|
||||
github: {
|
||||
name: 'GitHub',
|
||||
icon: GithubIcon,
|
||||
services: {
|
||||
github: {
|
||||
name: 'GitHub',
|
||||
description: 'Manage repositories, issues, and pull requests.',
|
||||
providerId: 'github-repo',
|
||||
icon: GithubIcon,
|
||||
baseProviderIcon: GithubIcon,
|
||||
scopes: ['repo', 'user:email', 'read:user', 'workflow'],
|
||||
},
|
||||
},
|
||||
defaultService: 'github',
|
||||
},
|
||||
x: {
|
||||
name: 'X',
|
||||
icon: xIcon,
|
||||
@@ -988,19 +972,6 @@ function getProviderAuthConfig(provider: string): ProviderAuthConfig {
|
||||
useBasicAuth: false,
|
||||
}
|
||||
}
|
||||
case 'github': {
|
||||
const { clientId, clientSecret } = getCredentials(
|
||||
env.GITHUB_CLIENT_ID,
|
||||
env.GITHUB_CLIENT_SECRET
|
||||
)
|
||||
return {
|
||||
tokenEndpoint: 'https://github.com/login/oauth/access_token',
|
||||
clientId,
|
||||
clientSecret,
|
||||
useBasicAuth: false,
|
||||
additionalHeaders: { Accept: 'application/json' },
|
||||
}
|
||||
}
|
||||
case 'x': {
|
||||
const { clientId, clientSecret } = getCredentials(env.X_CLIENT_ID, env.X_CLIENT_SECRET)
|
||||
return {
|
||||
|
||||
@@ -15,8 +15,6 @@ export type OAuthProvider =
|
||||
| 'google-groups'
|
||||
| 'google-meet'
|
||||
| 'vertex-ai'
|
||||
| 'github'
|
||||
| 'github-repo'
|
||||
| 'x'
|
||||
| 'confluence'
|
||||
| 'airtable'
|
||||
@@ -64,7 +62,6 @@ export type OAuthService =
|
||||
| 'google-groups'
|
||||
| 'google-meet'
|
||||
| 'vertex-ai'
|
||||
| 'github'
|
||||
| 'x'
|
||||
| 'confluence'
|
||||
| 'airtable'
|
||||
|
||||
@@ -66,11 +66,6 @@ describe('getAllOAuthServices', () => {
|
||||
it.concurrent('should include single-service providers', () => {
|
||||
const services = getAllOAuthServices()
|
||||
|
||||
const githubService = services.find((s) => s.providerId === 'github-repo')
|
||||
expect(githubService).toBeDefined()
|
||||
expect(githubService?.name).toBe('GitHub')
|
||||
expect(githubService?.baseProvider).toBe('github')
|
||||
|
||||
const slackService = services.find((s) => s.providerId === 'slack')
|
||||
expect(slackService).toBeDefined()
|
||||
expect(slackService?.name).toBe('Slack')
|
||||
@@ -145,14 +140,6 @@ describe('getServiceByProviderAndId', () => {
|
||||
expect(service.name).toBe('Microsoft Excel')
|
||||
})
|
||||
|
||||
it.concurrent('should work with single-service providers', () => {
|
||||
const service = getServiceByProviderAndId('github')
|
||||
|
||||
expect(service).toBeDefined()
|
||||
expect(service.providerId).toBe('github-repo')
|
||||
expect(service.name).toBe('GitHub')
|
||||
})
|
||||
|
||||
it.concurrent('should include scopes in returned service config', () => {
|
||||
const service = getServiceByProviderAndId('google', 'gmail')
|
||||
|
||||
@@ -182,12 +169,6 @@ describe('getProviderIdFromServiceId', () => {
|
||||
expect(providerId).toBe('outlook')
|
||||
})
|
||||
|
||||
it.concurrent('should return correct providerId for GitHub', () => {
|
||||
const providerId = getProviderIdFromServiceId('github')
|
||||
|
||||
expect(providerId).toBe('github-repo')
|
||||
})
|
||||
|
||||
it.concurrent('should return correct providerId for Microsoft Excel', () => {
|
||||
const providerId = getProviderIdFromServiceId('microsoft-excel')
|
||||
|
||||
@@ -262,14 +243,6 @@ describe('getServiceConfigByProviderId', () => {
|
||||
expect(excelService?.name).toBe('Microsoft Excel')
|
||||
})
|
||||
|
||||
it.concurrent('should work for GitHub', () => {
|
||||
const service = getServiceConfigByProviderId('github-repo')
|
||||
|
||||
expect(service).toBeDefined()
|
||||
expect(service?.providerId).toBe('github-repo')
|
||||
expect(service?.name).toBe('GitHub')
|
||||
})
|
||||
|
||||
it.concurrent('should work for Slack', () => {
|
||||
const service = getServiceConfigByProviderId('slack')
|
||||
|
||||
@@ -338,14 +311,6 @@ describe('getCanonicalScopesForProvider', () => {
|
||||
expect(excelScopes).toContain('Files.Read')
|
||||
})
|
||||
|
||||
it.concurrent('should return scopes for GitHub', () => {
|
||||
const scopes = getCanonicalScopesForProvider('github-repo')
|
||||
|
||||
expect(scopes.length).toBeGreaterThan(0)
|
||||
expect(scopes).toContain('repo')
|
||||
expect(scopes).toContain('user:email')
|
||||
})
|
||||
|
||||
it.concurrent('should handle providers with empty scopes array', () => {
|
||||
const scopes = getCanonicalScopesForProvider('notion')
|
||||
|
||||
@@ -397,13 +362,6 @@ describe('parseProvider', () => {
|
||||
expect(teamsConfig.featureType).toBe('microsoft-teams')
|
||||
})
|
||||
|
||||
it.concurrent('should parse GitHub provider', () => {
|
||||
const config = parseProvider('github-repo' as OAuthProvider)
|
||||
|
||||
expect(config.baseProvider).toBe('github')
|
||||
expect(config.featureType).toBe('github')
|
||||
})
|
||||
|
||||
it.concurrent('should parse Slack provider', () => {
|
||||
const config = parseProvider('slack' as OAuthProvider)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user