1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

Persist API key creds for token refresh. (#414)

* Persist API key creds for token refresh.

* Linter fixes
This commit is contained in:
Matt Gibson
2021-06-21 18:48:06 -04:00
committed by GitHub
parent 5e24a70a87
commit 78ae9383fb
3 changed files with 63 additions and 43 deletions

View File

@@ -1312,8 +1312,8 @@ export class ApiService implements ApiServiceAbstraction {
async getActiveBearerToken(): Promise<string> {
let accessToken = await this.tokenService.getToken();
if (this.tokenService.tokenNeedsRefresh()) {
const tokenResponse = await this.doRefreshToken();
accessToken = tokenResponse.accessToken;
await this.doRefreshToken();
accessToken = await this.tokenService.getToken();
}
return accessToken;
}
@@ -1358,6 +1358,43 @@ export class ApiService implements ApiServiceAbstraction {
}
}
protected async doRefreshToken(): Promise<void> {
const refreshToken = await this.tokenService.getRefreshToken();
if (refreshToken == null || refreshToken === '') {
throw new Error();
}
const headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Accept': 'application/json',
'Device-Type': this.deviceType,
});
if (this.customUserAgent != null) {
headers.set('User-Agent', this.customUserAgent);
}
const decodedToken = this.tokenService.decodeToken();
const response = await this.fetch(new Request(this.identityBaseUrl + '/connect/token', {
body: this.qsStringify({
grant_type: 'refresh_token',
client_id: decodedToken.client_id,
refresh_token: refreshToken,
}),
cache: 'no-store',
credentials: this.getCredentials(),
headers: headers,
method: 'POST',
}));
if (response.status === 200) {
const responseJson = await response.json();
const tokenResponse = new IdentityTokenResponse(responseJson);
await this.tokenService.setTokens(tokenResponse.accessToken, tokenResponse.refreshToken);
} else {
const error = await this.handleError(response, true, true);
return Promise.reject(error);
}
}
private async send(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, body: any,
authed: boolean, hasResponse: boolean, apiUrl?: string,
alterHeaders?: (headers: Headers) => void): Promise<any> {
@@ -1427,44 +1464,6 @@ export class ApiService implements ApiServiceAbstraction {
return new ErrorResponse(responseJson, response.status, tokenError);
}
private async doRefreshToken(): Promise<IdentityTokenResponse> {
const refreshToken = await this.tokenService.getRefreshToken();
if (refreshToken == null || refreshToken === '') {
throw new Error();
}
const headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Accept': 'application/json',
'Device-Type': this.deviceType,
});
if (this.customUserAgent != null) {
headers.set('User-Agent', this.customUserAgent);
}
const decodedToken = this.tokenService.decodeToken();
const response = await this.fetch(new Request(this.identityBaseUrl + '/connect/token', {
body: this.qsStringify({
grant_type: 'refresh_token',
client_id: decodedToken.client_id,
refresh_token: refreshToken,
}),
cache: 'no-store',
credentials: this.getCredentials(),
headers: headers,
method: 'POST',
}));
if (response.status === 200) {
const responseJson = await response.json();
const tokenResponse = new IdentityTokenResponse(responseJson);
await this.tokenService.setTokens(tokenResponse.accessToken, tokenResponse.refreshToken);
return tokenResponse;
} else {
const error = await this.handleError(response, true, true);
return Promise.reject(error);
}
}
private qsStringify(params: any): string {
return Object.keys(params).map(key => {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);