@@ -211,24 +211,47 @@ export class GithubServiceImpl implements GithubService {
211211 throw new Error ( 'device-authentication secret not found' ) ;
212212 }
213213
214- for ( const secret of deviceAuthSecrets ) {
214+ await this . deleteDeviceAuthSecrets ( deviceAuthSecrets ) ;
215+
216+ // another token should be used by the Github Service after removing the Device Authentication token
217+ this . initializeToken ( ) ;
218+ }
219+
220+ private async deleteDeviceAuthSecrets ( secrets ?: k8s . V1Secret [ ] ) : Promise < void > {
221+ const toDelete = secrets ?? await this . k8sService . getSecret ( DEVICE_AUTHENTICATION_LABEL_SELECTOR ) ;
222+ for ( const secret of toDelete ) {
215223 this . logger . info ( `Github Service: removing device-authentication secret with ${ secret . metadata ?. name } name...` ) ;
216224 await this . k8sService . deleteNamespacedSecret ( secret ) ;
217225 this . logger . info ( `Github Service: device-authentication secret with ${ secret . metadata ?. name } name was deleted successfully!` ) ;
218226 }
227+ }
219228
220- // another token should be used by the Github Service after removing the Device Authentication token
221- this . initializeToken ( ) ;
229+ /**
230+ * Legacy device-auth tokens were created with only 'user:email' scope by the old flow.
231+ * They should be removed so the PAT (if available) can be used instead.
232+ */
233+ private async isLegacyDeviceAuthToken ( token : string ) : Promise < boolean > {
234+ try {
235+ const { scopes } = await this . fetchGithubUser ( token ) ;
236+ return scopes . length === 1 && scopes [ 0 ] === 'user:email' ;
237+ } catch {
238+ return false ;
239+ }
222240 }
223241
224242 private async initializeToken ( ) : Promise < void > {
225243 this . logger . info ( 'Github Service: extracting token...' ) ;
226244
227245 const deviceAuthToken = await this . getDeviceAuthToken ( ) ;
228246 if ( deviceAuthToken ) {
229- this . tokenInfo = { value : deviceAuthToken , source : 'device-auth' } ;
230- this . logger . info ( 'Github Service: Device Authentication token is used' ) ;
231- return ;
247+ if ( await this . isLegacyDeviceAuthToken ( deviceAuthToken ) ) {
248+ this . logger . info ( 'Github Service: legacy device-auth token detected (user:email only), removing and falling through to PAT' ) ;
249+ await this . deleteDeviceAuthSecrets ( ) ;
250+ } else {
251+ this . tokenInfo = { value : deviceAuthToken , source : 'device-auth' } ;
252+ this . logger . info ( 'Github Service: Device Authentication token is used' ) ;
253+ return ;
254+ }
232255 }
233256
234257 const gitCredentialTokens = await this . getGitCredentialTokens ( ) ;
0 commit comments