@@ -8,9 +8,8 @@ import { env } from "@/env.mjs";
88import { OrgRole } from "@sourcebot/db" ;
99import { cookies } from "next/headers" ;
1010import { OPTIONAL_PROVIDERS_LINK_SKIPPED_COOKIE_NAME } from "@/lib/constants" ;
11- import { getTokenFromConfig } from '@sourcebot/crypto' ;
1211import { IntegrationIdentityProviderState } from "@/ee/features/permissionSyncing/types" ;
13- import { GitHubIdentityProviderConfig , GitLabIdentityProviderConfig } from "@sourcebot/schemas/v3/index.type " ;
12+ import { auth } from "@/auth " ;
1413
1514const logger = createLogger ( 'web-ee-permission-syncing-actions' ) ;
1615
@@ -32,6 +31,10 @@ export const getIntegrationProviderStates = async () => sew(() =>
3231 }
3332 } ) ;
3433
34+ // Fetch the session to get token errors
35+ const session = await auth ( ) ;
36+ const providerErrors = session ?. integrationProviderErrors ;
37+
3538 const integrationProviderState : IntegrationIdentityProviderState [ ] = [ ] ;
3639 for ( const integrationProviderConfig of integrationProviderConfigs ) {
3740 if ( integrationProviderConfig . purpose === "integration" ) {
@@ -41,11 +44,14 @@ export const getIntegrationProviderStates = async () => sew(() =>
4144
4245 const isLinked = ! ! linkedAccount ;
4346 const isRequired = integrationProviderConfig . required ?? true ;
47+ const providerError = providerErrors ?. [ integrationProviderConfig . provider ] ;
48+
4449 integrationProviderState . push ( {
4550 id : integrationProviderConfig . provider ,
4651 required : isRequired ,
4752 isLinked,
48- linkedAccountId : linkedAccount ?. providerAccountId
53+ linkedAccountId : linkedAccount ?. providerAccountId ,
54+ error : providerError
4955 } as IntegrationIdentityProviderState ) ;
5056 }
5157 }
@@ -99,90 +105,3 @@ export const skipOptionalProvidersLink = async () => sew(async () => {
99105 return true ;
100106} ) ;
101107
102- export const refreshOAuthToken = async (
103- provider : string ,
104- refreshToken : string ,
105- userId : string
106- ) : Promise < { accessToken : string ; refreshToken : string | null ; expiresAt : number } | null > => {
107- try {
108- // Load config and find the provider configuration
109- const config = await loadConfig ( env . CONFIG_PATH ) ;
110- const identityProviders = config ?. identityProviders ?? [ ] ;
111-
112- const providerConfig = identityProviders . find (
113- idp => idp . provider === provider
114- ) as GitHubIdentityProviderConfig | GitLabIdentityProviderConfig ;
115-
116- if ( ! providerConfig || ! ( 'clientId' in providerConfig ) || ! ( 'clientSecret' in providerConfig ) ) {
117- logger . error ( `Provider config not found or invalid for: ${ provider } ` ) ;
118- return null ;
119- }
120-
121- // Get client credentials from config
122- const clientId = await getTokenFromConfig ( providerConfig . clientId ) ;
123- const clientSecret = await getTokenFromConfig ( providerConfig . clientSecret ) ;
124- const baseUrl = 'baseUrl' in providerConfig && providerConfig . baseUrl
125- ? await getTokenFromConfig ( providerConfig . baseUrl )
126- : undefined ;
127-
128- let url : string ;
129- if ( baseUrl ) {
130- url = provider === 'github'
131- ? `${ baseUrl } /login/oauth/access_token`
132- : `${ baseUrl } /oauth/token` ;
133- } else if ( provider === 'github' ) {
134- url = 'https://github.com/login/oauth/access_token' ;
135- } else if ( provider === 'gitlab' ) {
136- url = 'https://gitlab.com/oauth/token' ;
137- } else {
138- logger . error ( `Unsupported provider for token refresh: ${ provider } ` ) ;
139- return null ;
140- }
141-
142- const response = await fetch ( url , {
143- method : 'POST' ,
144- headers : {
145- 'Content-Type' : 'application/x-www-form-urlencoded' ,
146- 'Accept' : 'application/json' ,
147- } ,
148- body : new URLSearchParams ( {
149- client_id : clientId ,
150- client_secret : clientSecret ,
151- grant_type : 'refresh_token' ,
152- refresh_token : refreshToken ,
153- } ) ,
154- } ) ;
155-
156- if ( ! response . ok ) {
157- const errorText = await response . text ( ) ;
158- logger . error ( `Failed to refresh ${ provider } token: ${ response . status } ${ errorText } ` ) ;
159- return null ;
160- }
161-
162- const data = await response . json ( ) ;
163-
164- const result = {
165- accessToken : data . access_token ,
166- refreshToken : data . refresh_token ?? null ,
167- expiresAt : data . expires_in ? Math . floor ( Date . now ( ) / 1000 ) + data . expires_in : 0 ,
168- } ;
169-
170- const { prisma } = await import ( '@/prisma' ) ;
171- await prisma . account . updateMany ( {
172- where : {
173- userId : userId ,
174- provider : provider ,
175- } ,
176- data : {
177- access_token : result . accessToken ,
178- refresh_token : result . refreshToken ,
179- expires_at : result . expiresAt ,
180- } ,
181- } ) ;
182-
183- return result ;
184- } catch ( error ) {
185- logger . error ( `Error refreshing ${ provider } token:` , error ) ;
186- return null ;
187- }
188- } ;
0 commit comments