mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-27 12:36:14 +01:00
refresh notification token if needed. authed and unlocked required
This commit is contained in:
parent
d37fa836da
commit
a360cd8e61
@ -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>;
|
||||||
}
|
}
|
||||||
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
@ -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 === '') {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user