Skip to content

Instantly share code, notes, and snippets.

@zouhir
Created February 7, 2025 06:20
Show Gist options
  • Save zouhir/9941681b6d70d9e8a711bd9eaa6e6ec6 to your computer and use it in GitHub Desktop.
Save zouhir/9941681b6d70d9e8a711bd9eaa6e6ec6 to your computer and use it in GitHub Desktop.
private async getGitHubToken(scopes: readonly string[]): Promise<[string, string]> {
return window.withProgress<[string, string]>({
location: ProgressLocation.Notification,
title: "Signing in to GitHub...",
cancellable: true
}, async (_, token) => {
const state = uuid();
const scopeString = scopes.join(' ');
const authUrl = `${GITHUB_AUTH_URL}` +
`?client_id=${config.githubClientId}` +
`&redirect_uri=${encodeURIComponent(CALLBACK_URI)}` +
`&scope=${encodeURIComponent(scopeString)}` +
`&state=vscode-${state}`;
return new Promise<[string, string]>((resolve, reject) => {
this._pendingStates.set(state, resolve);
env.openExternal(Uri.parse(authUrl));
token.onCancellationRequested(() => {
this._pendingStates.delete(state);
reject(new Error('User cancelled login'));
});
setTimeout(() => {
this._pendingStates.delete(state);
reject(new Error('Login timed out'));
}, 300000);
});
});
}
private async exchangeCodeForToken(code: string, state: string): Promise<string> {
const response = await fetch(GITHUB_TOKEN_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
client_id: config.githubClientId,
client_secret: config.githubClientSecret,
code: code,
redirect_uri: CALLBACK_URI,
state: `vscode-${state}`
})
});
const data = await response.json() as GitHubOAuthResponse;
if (!response.ok || data.error) {
throw new Error(`Token exchange error: ${data.error || 'Unknown error'}`);
}
return data.access_token;
}
private async exchangeGitHubTokenForGCPToken(githubToken: string): Promise<TokenResponse> {
const credential = GithubAuthProvider.credential(githubToken);
try {
const result = await signInWithCredential(this.auth, credential);
const user = result.user;
const idTokenResult = await user.getIdTokenResult();
return {
accessToken: idTokenResult.token,
refreshToken: user.refreshToken,
expiresAt: new Date(idTokenResult.expirationTime).getTime()
};
} catch (error) {
this.outputChannel.appendLine(`Error signing in with credential: ${error}`);
throw error;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment