@@ -17,7 +17,7 @@ import type { DeviceAuthentication } from './device-authentication';
1717import { ErrorHandler } from './error-handler' ;
1818import { ExtensionContext } from './extension-context' ;
1919import { Logger } from './logger' ;
20- import { arrayEquals , getMatchingHydrationScopeBundles , hasAllScopes , isUnauthorizedError } from './utils' ;
20+ import { getMatchingHydrationScopeBundles , hasAllScopes , isUnauthorizedError , isWorkspacePatSession , sessionMatchesRequestedScopes , WORKSPACE_PAT_SCOPE } from './utils' ;
2121
2222export interface GithubUser {
2323 login : string ;
@@ -32,6 +32,7 @@ export interface GithubService {
3232 removeDeviceAuthToken ( ) : Promise < void > ;
3333 getUser ( ) : Promise < GithubUser > ;
3434 getTokenScopes ( token : string ) : Promise < string [ ] > ;
35+ isDeviceAuthToken ( ) : Promise < boolean > ;
3536}
3637
3738@injectable ( )
@@ -64,8 +65,15 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
6465 if ( sessions . length > 0 ) {
6566 try {
6667 await this . githubService . getTokenScopes ( sessions [ 0 ] . accessToken ) ;
67- this . logger . trace ( 'GitHubAuthProvider: existing session token is valid' ) ;
68- return ;
68+ const isDeviceAuthToken = await this . githubService . isDeviceAuthToken ( ) ;
69+ const sessionsNeedRetag = isDeviceAuthToken
70+ ? sessions . some ( session => isWorkspacePatSession ( session . scopes ) )
71+ : sessions . some ( session => ! isWorkspacePatSession ( session . scopes ) ) ;
72+ if ( ! sessionsNeedRetag ) {
73+ this . logger . trace ( 'GitHubAuthProvider: existing session token is valid' ) ;
74+ return ;
75+ }
76+ this . logger . info ( 'GitHubAuthProvider: re-hydrating sessions to match current token source' ) ;
6977 } catch ( error ) {
7078 if ( isUnauthorizedError ( error ) ) {
7179 this . logger . warn ( 'GitHubAuthProvider: existing session token is not valid, clearing sessions' ) ;
@@ -95,17 +103,19 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
95103 return ;
96104 }
97105
106+ const isDeviceAuthToken = await this . githubService . isDeviceAuthToken ( ) ;
98107 const account = { label : githubUser . login , id : githubUser . id . toString ( ) } ;
99108 const hydratedSessions = matchingBundles . map ( scopes => ( {
100109 id : v4 ( ) ,
101110 accessToken : token ,
102111 account,
103- scopes,
112+ scopes : isDeviceAuthToken ? scopes : [ ... scopes , WORKSPACE_PAT_SCOPE ] ,
104113 } ) ) ;
105114
106115 await this . storeSessions ( hydratedSessions ) ;
107116 this . sessionChangeEmitter . fire ( { added : hydratedSessions , removed : [ ] , changed : [ ] } ) ;
108- this . logger . info ( `GitHubAuthProvider: hydrated ${ hydratedSessions . length } session(s) from K8s token` ) ;
117+ const tokenSource = isDeviceAuthToken ? 'device authentication' : 'workspace PAT' ;
118+ this . logger . info ( `GitHubAuthProvider: hydrated ${ hydratedSessions . length } session(s) from K8s ${ tokenSource } ` ) ;
109119 } catch ( error ) {
110120 if ( isUnauthorizedError ( error ) ) {
111121 this . logger . warn ( 'GitHubAuthProvider: hydrate failed, token is not valid' ) ;
@@ -121,7 +131,7 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
121131 const sessions = await this . sessionsPromise ;
122132 const sortedScopes = sessionScopes ? [ ...sessionScopes ] . sort ( ) : [ ] ;
123133 const filteredSessions = sortedScopes . length
124- ? sessions . filter ( session => arrayEquals ( [ ... session . scopes ] . sort ( ) , sortedScopes ) )
134+ ? sessions . filter ( session => sessionMatchesRequestedScopes ( session . scopes , sortedScopes ) )
125135 : [ ...sessions ] ;
126136
127137 this . logger . trace ( `GitHubAuthProvider: GET sessions - found ${ filteredSessions . length } sessions for scopes: ${ sessionScopes } ` ) ;
@@ -160,14 +170,15 @@ export class GitHubAuthProvider implements vscode.AuthenticationProvider {
160170 }
161171
162172 const sessions = await this . sessionsPromise ;
173+ const isDeviceAuthToken = await this . githubService . isDeviceAuthToken ( ) ;
163174 const session : vscode . AuthenticationSession = {
164175 id : v4 ( ) ,
165176 accessToken : token ,
166177 account : { label : githubUser . login , id : githubUser . id . toString ( ) } ,
167- scopes,
178+ scopes : isDeviceAuthToken ? scopes : [ ... scopes , WORKSPACE_PAT_SCOPE ] ,
168179 } ;
169180
170- const sessionIndex = sessions . findIndex ( s => arrayEquals ( [ ... s . scopes ] . sort ( ) , sortedScopes ) ) ;
181+ const sessionIndex = sessions . findIndex ( s => sessionMatchesRequestedScopes ( s . scopes , sortedScopes ) ) ;
171182 const removed : vscode . AuthenticationSession [ ] = [ ] ;
172183 const updatedSessions = [ ...sessions ] ;
173184 if ( sessionIndex > - 1 ) {
0 commit comments