1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-30 13:03:53 +01:00

refresh notification token if needed. authed and unlocked required

This commit is contained in:
Kyle Spearrin 2018-08-22 21:46:34 -04:00
parent d37fa836da
commit a360cd8e61
4 changed files with 35 additions and 27 deletions

View File

@ -234,5 +234,6 @@ export abstract class ApiService {
getUserPublicKey: (id: string) => Promise<UserKeyResponse>; getUserPublicKey: (id: string) => Promise<UserKeyResponse>;
getActiveBearerToken: () => Promise<string>;
fetch: (request: Request) => Promise<Response>; fetch: (request: Request) => Promise<Response>;
} }

View File

@ -3,6 +3,6 @@ import { EnvironmentService } from './environment.service';
export abstract class NotificationsService { export abstract class NotificationsService {
init: (environmentService: EnvironmentService) => Promise<void>; init: (environmentService: EnvironmentService) => Promise<void>;
updateConnection: () => Promise<void>; updateConnection: () => Promise<void>;
reconnectFromActivity: () => Promise<any>; reconnectFromActivity: () => Promise<void>;
disconnectFromInactivity: () => Promise<any>; disconnectFromInactivity: () => Promise<void>;
} }

View File

@ -776,6 +776,15 @@ export class ApiService implements ApiServiceAbstraction {
// Helpers // Helpers
async getActiveBearerToken(): Promise<string> {
let accessToken = await this.tokenService.getToken();
if (this.tokenService.tokenNeedsRefresh()) {
const tokenResponse = await this.doRefreshToken();
accessToken = tokenResponse.accessToken;
}
return accessToken;
}
fetch(request: Request): Promise<Response> { fetch(request: Request): Promise<Response> {
if (request.method === 'GET') { if (request.method === 'GET') {
request.headers.set('Cache-Control', 'no-cache'); request.headers.set('Cache-Control', 'no-cache');
@ -797,8 +806,8 @@ export class ApiService implements ApiServiceAbstraction {
}; };
if (authed) { if (authed) {
const authHeader = await this.handleTokenState(); const authHeader = await this.getActiveBearerToken();
headers.set('Authorization', authHeader); headers.set('Authorization', 'Bearer ' + authHeader);
} }
if (body != null) { if (body != null) {
if (typeof body === 'string') { if (typeof body === 'string') {
@ -844,16 +853,6 @@ export class ApiService implements ApiServiceAbstraction {
return new ErrorResponse(responseJson, response.status, tokenError); return new ErrorResponse(responseJson, response.status, tokenError);
} }
private async handleTokenState(): Promise<string> {
let accessToken = await this.tokenService.getToken();
if (this.tokenService.tokenNeedsRefresh()) {
const tokenResponse = await this.doRefreshToken();
accessToken = tokenResponse.accessToken;
}
return 'Bearer ' + accessToken;
}
private async doRefreshToken(): Promise<IdentityTokenResponse> { private async doRefreshToken(): Promise<IdentityTokenResponse> {
const refreshToken = await this.tokenService.getRefreshToken(); const refreshToken = await this.tokenService.getRefreshToken();
if (refreshToken == null || refreshToken === '') { if (refreshToken == null || refreshToken === '') {

View File

@ -4,10 +4,10 @@ import { NotificationType } from '../enums/notificationType';
import { ApiService } from '../abstractions/api.service'; import { ApiService } from '../abstractions/api.service';
import { AppIdService } from '../abstractions/appId.service'; import { AppIdService } from '../abstractions/appId.service';
import { CryptoService } from '../abstractions/crypto.service';
import { EnvironmentService } from '../abstractions/environment.service'; import { EnvironmentService } from '../abstractions/environment.service';
import { NotificationsService as NotificationsServiceAbstraction } from '../abstractions/notifications.service'; import { NotificationsService as NotificationsServiceAbstraction } from '../abstractions/notifications.service';
import { SyncService } from '../abstractions/sync.service'; import { SyncService } from '../abstractions/sync.service';
import { TokenService } from '../abstractions/token.service';
import { UserService } from '../abstractions/user.service'; import { UserService } from '../abstractions/user.service';
import { import {
@ -24,9 +24,9 @@ export class NotificationsService implements NotificationsServiceAbstraction {
private inactive = false; private inactive = false;
private reconnectTimer: any = null; private reconnectTimer: any = null;
constructor(private userService: UserService, private tokenService: TokenService, constructor(private userService: UserService, private syncService: SyncService,
private syncService: SyncService, private appIdService: AppIdService, private appIdService: AppIdService, private apiService: ApiService,
private apiService: ApiService) { } private cryptoService: CryptoService) { }
async init(environmentService: EnvironmentService): Promise<void> { async init(environmentService: EnvironmentService): Promise<void> {
this.inited = false; this.inited = false;
@ -46,7 +46,7 @@ export class NotificationsService implements NotificationsServiceAbstraction {
this.signalrConnection = new signalR.HubConnectionBuilder() this.signalrConnection = new signalR.HubConnectionBuilder()
.withUrl(this.url + '/hub', { .withUrl(this.url + '/hub', {
accessTokenFactory: () => this.tokenService.getToken(), accessTokenFactory: () => this.apiService.getActiveBearerToken(),
}) })
// .configureLogging(signalR.LogLevel.Information) // .configureLogging(signalR.LogLevel.Information)
.build(); .build();
@ -58,14 +58,14 @@ export class NotificationsService implements NotificationsServiceAbstraction {
this.reconnect(); this.reconnect();
}); });
this.inited = true; this.inited = true;
if (await this.userService.isAuthenticated()) { if (await this.isAuthedAndUnlocked()) {
await this.connect(); await this.connect();
} }
} }
async updateConnection(): Promise<void> { async updateConnection(): Promise<void> {
try { try {
if (await this.userService.isAuthenticated()) { if (await this.isAuthedAndUnlocked()) {
await this.connect(); await this.connect();
} else { } else {
await this.signalrConnection.stop(); await this.signalrConnection.stop();
@ -76,16 +76,17 @@ export class NotificationsService implements NotificationsServiceAbstraction {
} }
} }
async reconnectFromActivity(): Promise<any> { async reconnectFromActivity(): Promise<void> {
this.inactive = false; this.inactive = false;
if (!this.connected) { if (!this.connected) {
if (await this.userService.isAuthenticated()) { if (await this.isAuthedAndUnlocked()) {
return this.reconnect().then(() => this.syncService.fullSync(false)); await this.reconnect();
await this.syncService.fullSync(false);
} }
} }
} }
async disconnectFromInactivity(): Promise<any> { async disconnectFromInactivity(): Promise<void> {
this.inactive = true; this.inactive = true;
if (this.connected) { if (this.connected) {
await this.signalrConnection.stop(); await this.signalrConnection.stop();
@ -145,8 +146,8 @@ export class NotificationsService implements NotificationsServiceAbstraction {
if (this.connected || !this.inited || this.inactive) { if (this.connected || !this.inited || this.inactive) {
return; return;
} }
const authed = await this.userService.isAuthenticated(); const authedAndUnlocked = await this.isAuthedAndUnlocked();
if (!authed) { if (!authedAndUnlocked) {
return; return;
} }
@ -158,4 +159,11 @@ export class NotificationsService implements NotificationsServiceAbstraction {
this.reconnectTimer = setTimeout(() => this.reconnect(), 120000); this.reconnectTimer = setTimeout(() => this.reconnect(), 120000);
} }
} }
private async isAuthedAndUnlocked() {
if (await this.userService.isAuthenticated()) {
return this.cryptoService.hasKey();
}
return false;
}
} }