Skip to content

Commit 01a663a

Browse files
authored
Fix auth validation (#6)
1 parent d404815 commit 01a663a

File tree

2 files changed

+18
-43
lines changed

2 files changed

+18
-43
lines changed

src/authentication.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,15 @@ export default class GitpodAuthenticationProvider extends Disposable implements
136136
const scopesStr = sortedScopes.join(' ');
137137

138138
let userInfo: { id: string; accountName: string } | undefined;
139-
if (!session.account) {
140-
try {
141-
userInfo = await this._gitpodServer.getUserInfo(session.accessToken);
142-
this._logger.info(`Verified session with the following scopes: ${scopesStr}`);
143-
} catch (e) {
144-
// Remove sessions that return unauthorized response
145-
if (e.message === 'Unauthorized') {
146-
return undefined;
147-
}
139+
try {
140+
userInfo = await this._gitpodServer.getUserInfo(session.accessToken);
141+
this._logger.info(`Verified session with the following scopes: ${scopesStr}`);
142+
} catch (e) {
143+
// Remove sessions that return unauthorized response
144+
if (e.message === 'Unexpected server response: 401') {
145+
return undefined;
148146
}
147+
this._logger.error(`Error while verifying session with the following scopes: ${scopesStr}`, e);
149148
}
150149

151150
this._logger.trace(`Read the following session from the keychain with the following scopes: ${scopesStr}`);

src/internalApi.ts

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { GitpodClient, GitpodServer, GitpodServiceImpl } from '@gitpod/gitpod-protocol/lib/gitpod-service';
77
import { JsonRpcProxyFactory } from '@gitpod/gitpod-protocol/lib/messaging/proxy-factory';
88
import { listen as doListen } from 'vscode-ws-jsonrpc';
9-
import WebSocket from 'ws';
9+
import WebSocket, { ErrorEvent } from 'ws';
1010
import ReconnectingWebSocket from 'reconnecting-websocket';
1111
import * as vscode from 'vscode';
1212
import Log from './common/logger';
@@ -22,9 +22,9 @@ export const unauthorizedErr = 'unauthorized';
2222
class GitpodServerApi extends vscode.Disposable {
2323

2424
readonly service: GitpodConnection;
25-
private readonly webSocket: any;
26-
private readonly onWillCloseEmitter = new vscode.EventEmitter<number | undefined>();
27-
readonly onWillClose = this.onWillCloseEmitter.event;
25+
private readonly webSocket: ReconnectingWebSocket;
26+
private readonly onErrorEmitter = new vscode.EventEmitter<Error>();
27+
readonly onError = this.onErrorEmitter.event;
2828

2929
constructor(accessToken: string, serviceUrl: string, private readonly logger: Log) {
3030
super(() => this.internalDispose());
@@ -34,14 +34,12 @@ class GitpodServerApi extends vscode.Disposable {
3434
const factory = new JsonRpcProxyFactory<GitpodServer>();
3535
this.service = new GitpodServiceImpl<GitpodClient, GitpodServer>(factory.createProxy());
3636

37-
let retry = 1;
38-
const maxRetries = 3;
3937
const webSocket = new ReconnectingWebSocket(`${serviceUrl.replace('https', 'wss')}/api/v1`, undefined, {
4038
maxReconnectionDelay: 10000,
4139
minReconnectionDelay: 1000,
4240
reconnectionDelayGrowFactor: 1.5,
4341
connectionTimeout: 10000,
44-
maxRetries: Infinity,
42+
maxRetries: 3,
4543
debug: false,
4644
startClosed: false,
4745
WebSocket: class extends WebSocket {
@@ -54,19 +52,10 @@ class GitpodServerApi extends vscode.Disposable {
5452
'X-Client-Version': vscode.version
5553
}
5654
});
57-
this.on('unexpected-response', (_, resp) => {
58-
this.terminate();
59-
60-
// if mal-formed handshake request (unauthorized, forbidden) or client actions (redirect) are required then fail immediately
61-
// otherwise try several times and fail, maybe temporarily unavailable, like server restart
62-
if (retry++ >= maxRetries || (typeof resp.statusCode === 'number' && 300 <= resp.statusCode && resp.statusCode < 500)) {
63-
webSocket.close(resp.statusCode);
64-
}
65-
});
6655
}
6756
}
6857
});
69-
webSocket.onerror = (e: any) => logger.error('internal server api: failed to open socket', e);
58+
webSocket.onerror = (e: ErrorEvent) => this.onErrorEmitter.fire(e.error);
7059

7160
doListen({
7261
webSocket: (webSocket as any),
@@ -76,31 +65,18 @@ class GitpodServerApi extends vscode.Disposable {
7665
this.webSocket = webSocket;
7766
}
7867

79-
private close(statusCode?: number): void {
80-
this.onWillCloseEmitter.fire(statusCode);
81-
try {
82-
this.webSocket.close();
83-
} catch (e) {
84-
this.logger.error('internal server api: failed to close socket', e);
85-
}
86-
}
87-
8868
internalDispose() {
89-
this.close();
90-
this.onWillCloseEmitter.dispose();
69+
this.webSocket.close();
70+
this.onErrorEmitter.dispose();
9171
}
9272
}
9373

9474
export function withServerApi<T>(accessToken: string, serviceUrl: string, cb: (service: GitpodConnection) => Promise<T>, logger: Log): Promise<T> {
9575
const api = new GitpodServerApi(accessToken, serviceUrl, logger);
9676
return Promise.race([
9777
cb(api.service),
98-
new Promise<T>((_, reject) => api.onWillClose(statusCode => {
99-
if (statusCode === 401) {
100-
reject(new Error(unauthorizedErr));
101-
} else {
102-
reject(new Error('closed'));
103-
}
78+
new Promise<T>((_, reject) => api.onError(error => {
79+
reject(error);
10480
}))
10581
]).finally(() => api.dispose());
10682
}

0 commit comments

Comments
 (0)