bitwarden-estensione-browser/libs/common/src/services/environment.service.ts

211 lines
5.1 KiB
TypeScript
Raw Normal View History

import { concatMap, Observable, Subject } from "rxjs";
2021-12-16 13:36:21 +01:00
import {
EnvironmentService as EnvironmentServiceAbstraction,
Urls,
} from "../abstractions/environment.service";
import { StateService } from "../abstractions/state.service";
2022-02-22 15:39:11 +01:00
import { EnvironmentUrls } from "../models/domain/environmentUrls";
2018-01-10 02:20:54 +01:00
2018-01-23 23:29:15 +01:00
export class EnvironmentService implements EnvironmentServiceAbstraction {
2021-12-16 13:36:21 +01:00
private readonly urlsSubject = new Subject<Urls>();
2022-02-22 15:39:11 +01:00
urls: Observable<Urls> = this.urlsSubject;
2021-12-16 13:36:21 +01:00
protected baseUrl: string;
protected webVaultUrl: string;
protected apiUrl: string;
protected identityUrl: string;
protected iconsUrl: string;
protected notificationsUrl: string;
protected eventsUrl: string;
2021-12-16 13:36:21 +01:00
private keyConnectorUrl: string;
private scimUrl: string = null;
2021-12-16 13:36:21 +01:00
Misc Account Switching Fixes & Refactors (#600) * [refactor] Restructure EnvironmentUrls in state * Patch up (add missing fields) and more extensivly use the EnvironmentUrls class instead of passing around an any * Add environmentUrls to the AccountSettings model in addition to GlobalState for use in both scopes * Move EnvironmentUrls initialization to the model level and out of StateSerice * Adjust the StateMigrationService to account for these changes * [refactor] Improve order of operations for LockGuardService We currently jump through a bunch of hoops to verify users can access the Lock page, like checking authentication first. If a user is not authenticated, they are not locked, so we can improve performance for the happy path of this serivice by checking isLocked first and using isAuthenticated to deviate from the normal flow if needed. * [bug] Subscribe to State.accounts in EnvironmentService and set urls accordingly The EnvironmentService has no context for account changes currently and does not update actively used urls based on active account. This commit addresses this issue by subscribing to State.accounts and resetting the service's urls on account change. * [bug] Clear AccessToken from State on clean In order for logout flows to function as expected we need to deauthenticate users when cleaning up state before checking for the next active user Otherwise the service will continue to think the user being logged out is active * [refactor] Stop pushing accounts when modifying disk state There is no reason to push new accounts to subscribers when updating disk state. Subscribers recieve a copy of in memory state, so changes to disk will not be refelected and have to be fetched seperatly from the service. Pushing when saving disk state is just creating an unecassary performance burden. * [refactor] Default to in memory active user if availible, even when accessing disk state Sometimes we need to pull activeUserId from storage to access a bit of data, like on initial boot, but most of the time this isn't necassary. Since we pull this userId a lot, checking disk each time is a performance burden. Defaulting to the in memory user ID if avaible helps alleviate this. * [style] Ran prettier * [style] Change a let to a const
2022-01-07 15:30:54 +01:00
constructor(private stateService: StateService) {
this.stateService.activeAccount$
.pipe(
concatMap(async () => {
await this.setUrlsFromStorage();
})
)
.subscribe();
Misc Account Switching Fixes & Refactors (#600) * [refactor] Restructure EnvironmentUrls in state * Patch up (add missing fields) and more extensivly use the EnvironmentUrls class instead of passing around an any * Add environmentUrls to the AccountSettings model in addition to GlobalState for use in both scopes * Move EnvironmentUrls initialization to the model level and out of StateSerice * Adjust the StateMigrationService to account for these changes * [refactor] Improve order of operations for LockGuardService We currently jump through a bunch of hoops to verify users can access the Lock page, like checking authentication first. If a user is not authenticated, they are not locked, so we can improve performance for the happy path of this serivice by checking isLocked first and using isAuthenticated to deviate from the normal flow if needed. * [bug] Subscribe to State.accounts in EnvironmentService and set urls accordingly The EnvironmentService has no context for account changes currently and does not update actively used urls based on active account. This commit addresses this issue by subscribing to State.accounts and resetting the service's urls on account change. * [bug] Clear AccessToken from State on clean In order for logout flows to function as expected we need to deauthenticate users when cleaning up state before checking for the next active user Otherwise the service will continue to think the user being logged out is active * [refactor] Stop pushing accounts when modifying disk state There is no reason to push new accounts to subscribers when updating disk state. Subscribers recieve a copy of in memory state, so changes to disk will not be refelected and have to be fetched seperatly from the service. Pushing when saving disk state is just creating an unecassary performance burden. * [refactor] Default to in memory active user if availible, even when accessing disk state Sometimes we need to pull activeUserId from storage to access a bit of data, like on initial boot, but most of the time this isn't necassary. Since we pull this userId a lot, checking disk each time is a performance burden. Defaulting to the in memory user ID if avaible helps alleviate this. * [style] Ran prettier * [style] Change a let to a const
2022-01-07 15:30:54 +01:00
}
2021-12-16 13:36:21 +01:00
hasBaseUrl() {
return this.baseUrl != null;
}
getNotificationsUrl() {
if (this.notificationsUrl != null) {
return this.notificationsUrl;
}
2021-12-16 13:36:21 +01:00
if (this.baseUrl != null) {
return this.baseUrl + "/notifications";
}
2021-12-16 13:36:21 +01:00
return "https://notifications.bitwarden.com";
}
2021-12-16 13:36:21 +01:00
getWebVaultUrl() {
if (this.webVaultUrl != null) {
return this.webVaultUrl;
}
2021-12-16 13:36:21 +01:00
if (this.baseUrl) {
return this.baseUrl;
}
2021-12-16 13:36:21 +01:00
return "https://vault.bitwarden.com";
}
getSendUrl() {
return this.getWebVaultUrl() === "https://vault.bitwarden.com"
? "https://send.bitwarden.com/#"
: this.getWebVaultUrl() + "/#/send/";
}
getIconsUrl() {
if (this.iconsUrl != null) {
return this.iconsUrl;
}
2021-12-16 13:36:21 +01:00
if (this.baseUrl) {
return this.baseUrl + "/icons";
}
2021-12-16 13:36:21 +01:00
return "https://icons.bitwarden.net";
}
2021-12-16 13:36:21 +01:00
getApiUrl() {
if (this.apiUrl != null) {
return this.apiUrl;
}
2021-12-16 13:36:21 +01:00
if (this.baseUrl) {
return this.baseUrl + "/api";
}
2021-12-16 13:36:21 +01:00
return "https://api.bitwarden.com";
}
2021-12-16 13:36:21 +01:00
getIdentityUrl() {
if (this.identityUrl != null) {
return this.identityUrl;
}
2021-12-16 13:36:21 +01:00
if (this.baseUrl) {
return this.baseUrl + "/identity";
}
2021-12-16 13:36:21 +01:00
return "https://identity.bitwarden.com";
}
2021-12-16 13:36:21 +01:00
getEventsUrl() {
if (this.eventsUrl != null) {
return this.eventsUrl;
2018-01-10 02:20:54 +01:00
}
2021-12-16 13:36:21 +01:00
if (this.baseUrl) {
return this.baseUrl + "/events";
}
2021-12-16 13:36:21 +01:00
return "https://events.bitwarden.com";
}
getKeyConnectorUrl() {
return this.keyConnectorUrl;
}
getScimUrl() {
if (this.scimUrl != null) {
return this.scimUrl + "/v2";
}
return this.getWebVaultUrl() === "https://vault.bitwarden.com"
? "https://scim.bitwarden.com/v2"
: this.getWebVaultUrl() + "/scim/v2";
}
2021-12-16 13:36:21 +01:00
async setUrlsFromStorage(): Promise<void> {
const urls: any = await this.stateService.getEnvironmentUrls();
2021-12-16 13:36:21 +01:00
const envUrls = new EnvironmentUrls();
this.baseUrl = envUrls.base = urls.base;
2021-12-16 13:36:21 +01:00
this.webVaultUrl = urls.webVault;
this.apiUrl = envUrls.api = urls.api;
this.identityUrl = envUrls.identity = urls.identity;
this.iconsUrl = urls.icons;
this.notificationsUrl = urls.notifications;
this.eventsUrl = envUrls.events = urls.events;
this.keyConnectorUrl = urls.keyConnector;
// scimUrl is not saved to storage
2021-12-16 13:36:21 +01:00
}
async setUrls(urls: Urls): Promise<Urls> {
2021-12-16 13:36:21 +01:00
urls.base = this.formatUrl(urls.base);
urls.webVault = this.formatUrl(urls.webVault);
urls.api = this.formatUrl(urls.api);
urls.identity = this.formatUrl(urls.identity);
urls.icons = this.formatUrl(urls.icons);
urls.notifications = this.formatUrl(urls.notifications);
urls.events = this.formatUrl(urls.events);
urls.keyConnector = this.formatUrl(urls.keyConnector);
// scimUrl cannot be cleared
urls.scim = this.formatUrl(urls.scim) ?? this.scimUrl;
await this.stateService.setEnvironmentUrls({
base: urls.base,
api: urls.api,
identity: urls.identity,
webVault: urls.webVault,
icons: urls.icons,
notifications: urls.notifications,
events: urls.events,
keyConnector: urls.keyConnector,
// scimUrl is not saved to storage
});
2018-01-10 02:20:54 +01:00
2021-12-16 13:36:21 +01:00
this.baseUrl = urls.base;
this.webVaultUrl = urls.webVault;
this.apiUrl = urls.api;
this.identityUrl = urls.identity;
this.iconsUrl = urls.icons;
this.notificationsUrl = urls.notifications;
this.eventsUrl = urls.events;
this.keyConnectorUrl = urls.keyConnector;
this.scimUrl = urls.scim;
2021-12-16 13:36:21 +01:00
this.urlsSubject.next(urls);
return urls;
}
getUrls() {
return {
base: this.baseUrl,
webVault: this.webVaultUrl,
api: this.apiUrl,
identity: this.identityUrl,
icons: this.iconsUrl,
notifications: this.notificationsUrl,
events: this.eventsUrl,
keyConnector: this.keyConnectorUrl,
scim: this.scimUrl,
2021-12-16 13:36:21 +01:00
};
}
private formatUrl(url: string): string {
if (url == null || url === "") {
return null;
}
2018-01-10 02:20:54 +01:00
2021-12-16 13:36:21 +01:00
url = url.replace(/\/+$/g, "");
if (!url.startsWith("http://") && !url.startsWith("https://")) {
url = "https://" + url;
2018-01-10 02:20:54 +01:00
}
2021-12-16 13:36:21 +01:00
return url.trim();
}
2018-01-10 02:20:54 +01:00
}