Add helper methods to EnvironmentService for retrieving urls (#435)
This commit is contained in:
parent
c77441b353
commit
de288913e4
|
@ -18,10 +18,7 @@ export abstract class CaptchaProtectedComponent {
|
|||
protected platformUtilsService: PlatformUtilsService) { }
|
||||
|
||||
async setupCaptcha() {
|
||||
let webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
if (webVaultUrl == null) {
|
||||
webVaultUrl = 'https://vault.bitwarden.com';
|
||||
}
|
||||
const webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
|
||||
this.captcha = new CaptchaIFrame(window, webVaultUrl,
|
||||
this.i18nService, (token: string) => {
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
|
||||
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
|
||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
import { NotificationsService } from 'jslib-common/abstractions/notifications.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
|
||||
@Directive()
|
||||
|
@ -23,13 +24,16 @@ export class EnvironmentComponent {
|
|||
|
||||
constructor(protected platformUtilsService: PlatformUtilsService, protected environmentService: EnvironmentService,
|
||||
protected i18nService: I18nService) {
|
||||
this.baseUrl = environmentService.baseUrl || '';
|
||||
this.webVaultUrl = environmentService.webVaultUrl || '';
|
||||
this.apiUrl = environmentService.apiUrl || '';
|
||||
this.identityUrl = environmentService.identityUrl || '';
|
||||
this.iconsUrl = environmentService.iconsUrl || '';
|
||||
this.notificationsUrl = environmentService.notificationsUrl || '';
|
||||
this.enterpriseUrl = environmentService.enterpriseUrl || '';
|
||||
|
||||
const urls = this.environmentService.getUrls();
|
||||
|
||||
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.enterpriseUrl = urls.enterprise || '';
|
||||
}
|
||||
|
||||
async submit() {
|
||||
|
|
|
@ -38,14 +38,7 @@ export class IconComponent implements OnChanges {
|
|||
private iconsUrl: string;
|
||||
|
||||
constructor(environmentService: EnvironmentService, protected stateService: StateService) {
|
||||
this.iconsUrl = environmentService.iconsUrl;
|
||||
if (!this.iconsUrl) {
|
||||
if (environmentService.baseUrl) {
|
||||
this.iconsUrl = environmentService.baseUrl + '/icons';
|
||||
} else {
|
||||
this.iconsUrl = 'https://icons.bitwarden.net';
|
||||
}
|
||||
}
|
||||
this.iconsUrl = environmentService.getIconsUrl();
|
||||
}
|
||||
|
||||
async ngOnChanges() {
|
||||
|
|
|
@ -57,10 +57,9 @@ export class LockComponent implements OnInit {
|
|||
(await this.cryptoService.hasKeyStored('biometric') || !this.platformUtilsService.supportsSecureStorage());
|
||||
this.biometricText = await this.storageService.get(ConstantsService.biometricText);
|
||||
this.email = await this.userService.getEmail();
|
||||
let vaultUrl = this.environmentService.getWebVaultUrl();
|
||||
if (vaultUrl == null) {
|
||||
vaultUrl = 'https://bitwarden.com';
|
||||
}
|
||||
|
||||
const webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
const vaultUrl = webVaultUrl === 'https://vault.bitwarden.com' ? 'https://bitwarden.com' : webVaultUrl;
|
||||
this.webVaultHostname = Utils.getHostname(vaultUrl);
|
||||
}
|
||||
|
||||
|
|
|
@ -143,8 +143,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
|
|||
await this.storageService.save(ConstantsService.ssoCodeVerifierKey, ssoCodeVerifier);
|
||||
|
||||
// Build URI
|
||||
const webUrl = this.environmentService.getWebVaultUrl() == null ? 'https://vault.bitwarden.com' :
|
||||
this.environmentService.getWebVaultUrl();
|
||||
const webUrl = this.environmentService.getWebVaultUrl();
|
||||
|
||||
// Launch browser
|
||||
this.platformUtilsService.launchUri(webUrl + '/#/sso?clientId=' + clientId +
|
||||
|
|
|
@ -63,12 +63,7 @@ export class AddEditComponent implements OnInit {
|
|||
{ name: i18nService.t('sendTypeFile'), value: SendType.File },
|
||||
{ name: i18nService.t('sendTypeText'), value: SendType.Text },
|
||||
];
|
||||
const webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
if (webVaultUrl == null) {
|
||||
this.sendLinkBaseUrl = 'https://send.bitwarden.com/#';
|
||||
} else {
|
||||
this.sendLinkBaseUrl = webVaultUrl + '/#/send/';
|
||||
}
|
||||
this.sendLinkBaseUrl = this.environmentService.getSendUrl();
|
||||
}
|
||||
|
||||
get link(): string {
|
||||
|
|
|
@ -170,11 +170,7 @@ export class SendComponent implements OnInit {
|
|||
}
|
||||
|
||||
copy(s: SendView) {
|
||||
let sendLinkBaseUrl = 'https://send.bitwarden.com/#';
|
||||
const webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
if (webVaultUrl != null) {
|
||||
sendLinkBaseUrl = webVaultUrl + '/#/send/';
|
||||
}
|
||||
const sendLinkBaseUrl = this.environmentService.getSendUrl();
|
||||
const link = sendLinkBaseUrl + s.accessId + '/' + s.urlB64Key;
|
||||
this.platformUtilsService.copyToClipboard(link);
|
||||
this.platformUtilsService.showToast('success', null,
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { AuthService } from 'jslib-common/abstractions/auth.service';
|
||||
import { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';
|
||||
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
|
||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
|
@ -43,7 +44,7 @@ export class SsoComponent {
|
|||
protected i18nService: I18nService, protected route: ActivatedRoute,
|
||||
protected storageService: StorageService, protected stateService: StateService,
|
||||
protected platformUtilsService: PlatformUtilsService, protected apiService: ApiService,
|
||||
protected cryptoFunctionService: CryptoFunctionService,
|
||||
protected cryptoFunctionService: CryptoFunctionService, protected environmentService: EnvironmentService,
|
||||
protected passwordGenerationService: PasswordGenerationService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
|
@ -119,7 +120,7 @@ export class SsoComponent {
|
|||
// Save state (regardless of new or existing)
|
||||
await this.storageService.save(ConstantsService.ssoStateKey, state);
|
||||
|
||||
let authorizeUrl = this.apiService.identityBaseUrl + '/connect/authorize?' +
|
||||
let authorizeUrl = this.environmentService.getIdentityUrl() + '/connect/authorize?' +
|
||||
'client_id=' + this.clientId + '&redirect_uri=' + encodeURIComponent(this.redirectUri) + '&' +
|
||||
'response_type=code&scope=api offline_access&' +
|
||||
'state=' + state + '&code_challenge=' + codeChallenge + '&' +
|
||||
|
|
|
@ -76,10 +76,7 @@ export class TwoFactorComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
if (this.win != null && this.webAuthnSupported) {
|
||||
let webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
if (webVaultUrl == null) {
|
||||
webVaultUrl = 'https://vault.bitwarden.com';
|
||||
}
|
||||
const webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
this.webAuthn = new WebAuthnIFrame(this.win, webVaultUrl, this.webAuthnNewTab, this.platformUtilsService,
|
||||
this.i18nService, (token: string) => {
|
||||
this.token = token;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"lunr": "^2.3.9",
|
||||
"node-forge": "^0.10.0",
|
||||
"papaparse": "^5.3.0",
|
||||
"rxjs": "6.6.7",
|
||||
"tldjs": "^2.3.1",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
|
@ -631,6 +632,17 @@
|
|||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "6.6.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
|
||||
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -724,6 +736,11 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
|
@ -1344,6 +1361,14 @@
|
|||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.6.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
|
||||
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -1409,6 +1434,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"lunr": "^2.3.9",
|
||||
"node-forge": "^0.10.0",
|
||||
"papaparse": "^5.3.0",
|
||||
"rxjs": "6.6.7",
|
||||
"tldjs": "^2.3.1",
|
||||
"zxcvbn": "^4.4.2"
|
||||
}
|
||||
|
|
|
@ -153,12 +153,6 @@ import { UserKeyResponse } from '../models/response/userKeyResponse';
|
|||
import { SendAccessView } from '../models/view/sendAccessView';
|
||||
|
||||
export abstract class ApiService {
|
||||
urlsSet: boolean;
|
||||
apiBaseUrl: string;
|
||||
identityBaseUrl: string;
|
||||
eventsBaseUrl: string;
|
||||
|
||||
setUrls: (urls: EnvironmentUrls) => void;
|
||||
postIdentityToken: (request: TokenRequest) => Promise<IdentityTokenResponse | IdentityTwoFactorResponse | IdentityCaptchaResponse>;
|
||||
refreshIdentityToken: () => Promise<any>;
|
||||
|
||||
|
|
|
@ -1,14 +1,29 @@
|
|||
export abstract class EnvironmentService {
|
||||
baseUrl: string;
|
||||
webVaultUrl: string;
|
||||
apiUrl: string;
|
||||
identityUrl: string;
|
||||
iconsUrl: string;
|
||||
notificationsUrl: string;
|
||||
eventsUrl: string;
|
||||
enterpriseUrl: string;
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export type Urls = {
|
||||
base?: string;
|
||||
webVault?: string;
|
||||
api?: string;
|
||||
identity?: string;
|
||||
icons?: string;
|
||||
notifications?: string;
|
||||
events?: string;
|
||||
enterprise?: string;
|
||||
};
|
||||
|
||||
export abstract class EnvironmentService {
|
||||
urls: Observable<Urls>;
|
||||
|
||||
hasBaseUrl: () => boolean;
|
||||
getNotificationsUrl: () => string;
|
||||
getEnterpriseUrl: () => string;
|
||||
getWebVaultUrl: () => string;
|
||||
getSendUrl: () => string;
|
||||
getIconsUrl: () => string;
|
||||
getApiUrl: () => string;
|
||||
getIdentityUrl: () => string;
|
||||
getEventsUrl: () => string;
|
||||
setUrlsFromStorage: () => Promise<void>;
|
||||
setUrls: (urls: any) => Promise<any>;
|
||||
setUrls: (urls: any, saveSettings?: boolean) => Promise<Urls>;
|
||||
getUrls: () => Urls;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { EnvironmentService } from './environment.service';
|
||||
|
||||
export abstract class NotificationsService {
|
||||
init: (environmentService: EnvironmentService) => Promise<void>;
|
||||
init: () => Promise<void>;
|
||||
updateConnection: (sync?: boolean) => Promise<void>;
|
||||
reconnectFromActivity: () => Promise<void>;
|
||||
disconnectFromInactivity: () => Promise<void>;
|
||||
|
|
|
@ -5,8 +5,6 @@ import { ApiService as ApiServiceAbstraction } from '../abstractions/api.service
|
|||
import { PlatformUtilsService } from '../abstractions/platformUtils.service';
|
||||
import { TokenService } from '../abstractions/token.service';
|
||||
|
||||
import { EnvironmentUrls } from '../models/domain/environmentUrls';
|
||||
|
||||
import { AttachmentRequest } from '../models/request/attachmentRequest';
|
||||
import { BitPayInvoiceRequest } from '../models/request/bitPayInvoiceRequest';
|
||||
import { CipherBulkDeleteRequest } from '../models/request/cipherBulkDeleteRequest';
|
||||
|
@ -160,23 +158,19 @@ import { ChallengeResponse } from '../models/response/twoFactorWebAuthnResponse'
|
|||
import { TwoFactorYubiKeyResponse } from '../models/response/twoFactorYubiKeyResponse';
|
||||
import { UserKeyResponse } from '../models/response/userKeyResponse';
|
||||
|
||||
import { EnvironmentService } from '../abstractions';
|
||||
import { IdentityCaptchaResponse } from '../models/response/identityCaptchaResponse';
|
||||
import { SendAccessView } from '../models/view/sendAccessView';
|
||||
|
||||
export class ApiService implements ApiServiceAbstraction {
|
||||
urlsSet: boolean = false;
|
||||
apiBaseUrl: string;
|
||||
identityBaseUrl: string;
|
||||
eventsBaseUrl: string;
|
||||
|
||||
private device: DeviceType;
|
||||
private deviceType: string;
|
||||
private isWebClient = false;
|
||||
private isDesktopClient = false;
|
||||
private usingBaseUrl = false;
|
||||
|
||||
constructor(private tokenService: TokenService, private platformUtilsService: PlatformUtilsService,
|
||||
private logoutCallback: (expired: boolean) => Promise<void>, private customUserAgent: string = null) {
|
||||
private environmentService: EnvironmentService, private logoutCallback: (expired: boolean) => Promise<void>,
|
||||
private customUserAgent: string = null) {
|
||||
this.device = platformUtilsService.getDevice();
|
||||
this.deviceType = this.device.toString();
|
||||
this.isWebClient = this.device === DeviceType.IEBrowser || this.device === DeviceType.ChromeBrowser ||
|
||||
|
@ -187,33 +181,6 @@ export class ApiService implements ApiServiceAbstraction {
|
|||
this.device === DeviceType.LinuxDesktop;
|
||||
}
|
||||
|
||||
setUrls(urls: EnvironmentUrls): void {
|
||||
this.urlsSet = true;
|
||||
|
||||
if (urls.base != null) {
|
||||
this.usingBaseUrl = true;
|
||||
this.apiBaseUrl = urls.base + '/api';
|
||||
this.identityBaseUrl = urls.base + '/identity';
|
||||
this.eventsBaseUrl = urls.base + '/events';
|
||||
return;
|
||||
}
|
||||
|
||||
this.apiBaseUrl = urls.api;
|
||||
this.identityBaseUrl = urls.identity;
|
||||
this.eventsBaseUrl = urls.events;
|
||||
|
||||
// Production
|
||||
if (this.apiBaseUrl == null) {
|
||||
this.apiBaseUrl = 'https://api.bitwarden.com';
|
||||
}
|
||||
if (this.identityBaseUrl == null) {
|
||||
this.identityBaseUrl = 'https://identity.bitwarden.com';
|
||||
}
|
||||
if (this.eventsBaseUrl == null) {
|
||||
this.eventsBaseUrl = 'https://events.bitwarden.com';
|
||||
}
|
||||
}
|
||||
|
||||
// Auth APIs
|
||||
|
||||
async postIdentityToken(request: TokenRequest): Promise<IdentityTokenResponse | IdentityTwoFactorResponse | IdentityCaptchaResponse> {
|
||||
|
@ -226,7 +193,7 @@ export class ApiService implements ApiServiceAbstraction {
|
|||
headers.set('User-Agent', this.customUserAgent);
|
||||
}
|
||||
request.alterIdentityTokenHeaders(headers);
|
||||
const response = await this.fetch(new Request(this.identityBaseUrl + '/connect/token', {
|
||||
const response = await this.fetch(new Request(this.environmentService.getIdentityUrl() + '/connect/token', {
|
||||
body: this.qsStringify(request.toIdentityToken(request.clientId ?? this.platformUtilsService.identityClientId)),
|
||||
credentials: this.getCredentials(),
|
||||
cache: 'no-store',
|
||||
|
@ -1399,7 +1366,7 @@ export class ApiService implements ApiServiceAbstraction {
|
|||
if (this.customUserAgent != null) {
|
||||
headers.set('User-Agent', this.customUserAgent);
|
||||
}
|
||||
const response = await this.fetch(new Request(this.eventsBaseUrl + '/collect', {
|
||||
const response = await this.fetch(new Request(this.environmentService.getEventsUrl() + '/collect', {
|
||||
cache: 'no-store',
|
||||
credentials: this.getCredentials(),
|
||||
method: 'POST',
|
||||
|
@ -1473,7 +1440,7 @@ export class ApiService implements ApiServiceAbstraction {
|
|||
}
|
||||
|
||||
const path = `/account/prevalidate?domainHint=${encodeURIComponent(identifier)}`;
|
||||
const response = await this.fetch(new Request(this.identityBaseUrl + path, {
|
||||
const response = await this.fetch(new Request(this.environmentService.getIdentityUrl() + path, {
|
||||
cache: 'no-store',
|
||||
credentials: this.getCredentials(),
|
||||
headers: headers,
|
||||
|
@ -1503,7 +1470,7 @@ export class ApiService implements ApiServiceAbstraction {
|
|||
}
|
||||
|
||||
const decodedToken = this.tokenService.decodeToken();
|
||||
const response = await this.fetch(new Request(this.identityBaseUrl + '/connect/token', {
|
||||
const response = await this.fetch(new Request(this.environmentService.getIdentityUrl() + '/connect/token', {
|
||||
body: this.qsStringify({
|
||||
grant_type: 'refresh_token',
|
||||
client_id: decodedToken.client_id,
|
||||
|
@ -1528,7 +1495,7 @@ export class ApiService implements ApiServiceAbstraction {
|
|||
private async send(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, body: any,
|
||||
authed: boolean, hasResponse: boolean, apiUrl?: string,
|
||||
alterHeaders?: (headers: Headers) => void): Promise<any> {
|
||||
apiUrl = Utils.isNullOrWhitespace(apiUrl) ? this.apiBaseUrl : apiUrl;
|
||||
apiUrl = Utils.isNullOrWhitespace(apiUrl) ? this.environmentService.getApiUrl() : apiUrl;
|
||||
const headers = new Headers({
|
||||
'Device-Type': this.deviceType,
|
||||
});
|
||||
|
@ -1601,7 +1568,7 @@ export class ApiService implements ApiServiceAbstraction {
|
|||
}
|
||||
|
||||
private getCredentials(): RequestCredentials {
|
||||
if (!this.isWebClient || this.usingBaseUrl) {
|
||||
if (!this.isWebClient || this.environmentService.hasBaseUrl()) {
|
||||
return 'include';
|
||||
}
|
||||
return undefined;
|
||||
|
|
|
@ -1,32 +1,119 @@
|
|||
import { Observable, Subject } from 'rxjs';
|
||||
|
||||
import { EnvironmentUrls } from '../models/domain/environmentUrls';
|
||||
|
||||
import { ConstantsService } from './constants.service';
|
||||
|
||||
import { ApiService } from '../abstractions/api.service';
|
||||
import { EnvironmentService as EnvironmentServiceAbstraction } from '../abstractions/environment.service';
|
||||
import { NotificationsService } from '../abstractions/notifications.service';
|
||||
import { EnvironmentService as EnvironmentServiceAbstraction, Urls } from '../abstractions/environment.service';
|
||||
import { StorageService } from '../abstractions/storage.service';
|
||||
|
||||
export class EnvironmentService implements EnvironmentServiceAbstraction {
|
||||
baseUrl: string;
|
||||
webVaultUrl: string;
|
||||
apiUrl: string;
|
||||
identityUrl: string;
|
||||
iconsUrl: string;
|
||||
notificationsUrl: string;
|
||||
eventsUrl: string;
|
||||
enterpriseUrl: string;
|
||||
|
||||
constructor(private apiService: ApiService, private storageService: StorageService,
|
||||
private notificationsService: NotificationsService) { }
|
||||
private readonly urlsSubject = new Subject<Urls>();
|
||||
urls: Observable<Urls> = this.urlsSubject; // tslint:disable-line
|
||||
|
||||
getWebVaultUrl(): string {
|
||||
private baseUrl: string;
|
||||
private webVaultUrl: string;
|
||||
private apiUrl: string;
|
||||
private identityUrl: string;
|
||||
private iconsUrl: string;
|
||||
private notificationsUrl: string;
|
||||
private eventsUrl: string;
|
||||
private enterpriseUrl: string;
|
||||
|
||||
constructor(private storageService: StorageService) {}
|
||||
|
||||
hasBaseUrl() {
|
||||
return this.baseUrl != null;
|
||||
}
|
||||
|
||||
getNotificationsUrl() {
|
||||
if (this.notificationsUrl != null) {
|
||||
return this.notificationsUrl;
|
||||
}
|
||||
|
||||
if (this.baseUrl != null) {
|
||||
return this.baseUrl + '/notifications';
|
||||
}
|
||||
|
||||
return 'https://notifications.bitwarden.com';
|
||||
}
|
||||
|
||||
getEnterpriseUrl() {
|
||||
if (this.enterpriseUrl != null) {
|
||||
return this.enterpriseUrl;
|
||||
}
|
||||
|
||||
if (this.baseUrl != null) {
|
||||
return this.baseUrl + '/portal';
|
||||
}
|
||||
|
||||
return 'https://portal.bitwarden.com';
|
||||
}
|
||||
|
||||
getWebVaultUrl() {
|
||||
if (this.webVaultUrl != null) {
|
||||
return this.webVaultUrl;
|
||||
} else if (this.baseUrl) {
|
||||
}
|
||||
|
||||
if (this.baseUrl) {
|
||||
return this.baseUrl;
|
||||
}
|
||||
return null;
|
||||
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;
|
||||
}
|
||||
|
||||
if (this.baseUrl) {
|
||||
return this.baseUrl + '/icons';
|
||||
}
|
||||
|
||||
return 'https://icons.bitwarden.net';
|
||||
}
|
||||
|
||||
getApiUrl() {
|
||||
if (this.apiUrl != null) {
|
||||
return this.apiUrl;
|
||||
}
|
||||
|
||||
if (this.baseUrl) {
|
||||
return this.baseUrl + '/api';
|
||||
}
|
||||
|
||||
return 'https://api.bitwarden.com';
|
||||
}
|
||||
|
||||
getIdentityUrl() {
|
||||
if (this.identityUrl != null) {
|
||||
return this.identityUrl;
|
||||
}
|
||||
|
||||
if (this.baseUrl) {
|
||||
return this.baseUrl + '/identity';
|
||||
}
|
||||
|
||||
return 'https://identity.bitwarden.com';
|
||||
}
|
||||
|
||||
getEventsUrl() {
|
||||
if (this.eventsUrl != null) {
|
||||
return this.eventsUrl;
|
||||
}
|
||||
|
||||
if (this.baseUrl) {
|
||||
return this.baseUrl + '/events';
|
||||
}
|
||||
|
||||
return 'https://events.bitwarden.com';
|
||||
}
|
||||
|
||||
async setUrlsFromStorage(): Promise<void> {
|
||||
|
@ -46,7 +133,6 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||
|
||||
if (urls.base) {
|
||||
this.baseUrl = envUrls.base = urls.base;
|
||||
this.apiService.setUrls(envUrls);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -57,10 +143,9 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||
this.notificationsUrl = urls.notifications;
|
||||
this.eventsUrl = envUrls.events = urls.events;
|
||||
this.enterpriseUrl = urls.enterprise;
|
||||
this.apiService.setUrls(envUrls);
|
||||
}
|
||||
|
||||
async setUrls(urls: any): Promise<any> {
|
||||
async setUrls(urls: Urls, saveSettings: boolean = true): Promise<any> {
|
||||
urls.base = this.formatUrl(urls.base);
|
||||
urls.webVault = this.formatUrl(urls.webVault);
|
||||
urls.api = this.formatUrl(urls.api);
|
||||
|
@ -70,16 +155,18 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||
urls.events = this.formatUrl(urls.events);
|
||||
urls.enterprise = this.formatUrl(urls.enterprise);
|
||||
|
||||
await this.storageService.save(ConstantsService.environmentUrlsKey, {
|
||||
base: urls.base,
|
||||
api: urls.api,
|
||||
identity: urls.identity,
|
||||
webVault: urls.webVault,
|
||||
icons: urls.icons,
|
||||
notifications: urls.notifications,
|
||||
events: urls.events,
|
||||
enterprise: urls.enterprise,
|
||||
});
|
||||
if (saveSettings) {
|
||||
await this.storageService.save(ConstantsService.environmentUrlsKey, {
|
||||
base: urls.base,
|
||||
api: urls.api,
|
||||
identity: urls.identity,
|
||||
webVault: urls.webVault,
|
||||
icons: urls.icons,
|
||||
notifications: urls.notifications,
|
||||
events: urls.events,
|
||||
enterprise: urls.enterprise,
|
||||
});
|
||||
}
|
||||
|
||||
this.baseUrl = urls.base;
|
||||
this.webVaultUrl = urls.webVault;
|
||||
|
@ -90,22 +177,24 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||
this.eventsUrl = urls.events;
|
||||
this.enterpriseUrl = urls.enterprise;
|
||||
|
||||
const envUrls = new EnvironmentUrls();
|
||||
if (this.baseUrl) {
|
||||
envUrls.base = this.baseUrl;
|
||||
} else {
|
||||
envUrls.api = this.apiUrl;
|
||||
envUrls.identity = this.identityUrl;
|
||||
envUrls.events = this.eventsUrl;
|
||||
}
|
||||
this.urlsSubject.next(urls);
|
||||
|
||||
this.apiService.setUrls(envUrls);
|
||||
if (this.notificationsService != null) {
|
||||
this.notificationsService.init(this);
|
||||
}
|
||||
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,
|
||||
enterprise: this.enterpriseUrl,
|
||||
};
|
||||
}
|
||||
|
||||
private formatUrl(url: string): string {
|
||||
if (url == null || url === '') {
|
||||
return null;
|
||||
|
|
|
@ -29,18 +29,20 @@ export class NotificationsService implements NotificationsServiceAbstraction {
|
|||
|
||||
constructor(private userService: UserService, private syncService: SyncService,
|
||||
private appIdService: AppIdService, private apiService: ApiService,
|
||||
private vaultTimeoutService: VaultTimeoutService,
|
||||
private vaultTimeoutService: VaultTimeoutService, private environmentService: EnvironmentService,
|
||||
private logoutCallback: () => Promise<void>, private logService: LogService) {
|
||||
this.environmentService.urls.subscribe(() => {
|
||||
if (!this.inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.init();
|
||||
});
|
||||
}
|
||||
|
||||
async init(environmentService: EnvironmentService): Promise<void> {
|
||||
async init(): Promise<void> {
|
||||
this.inited = false;
|
||||
this.url = 'https://notifications.bitwarden.com';
|
||||
if (environmentService.notificationsUrl != null) {
|
||||
this.url = environmentService.notificationsUrl;
|
||||
} else if (environmentService.baseUrl != null) {
|
||||
this.url = environmentService.baseUrl + '/notifications';
|
||||
}
|
||||
this.url = this.environmentService.getNotificationsUrl();
|
||||
|
||||
// Set notifications server URL to `https://-` to effectively disable communication
|
||||
// with the notifications server from the client app
|
||||
|
|
|
@ -279,10 +279,7 @@ export class LoginCommand {
|
|||
}
|
||||
});
|
||||
let foundPort = false;
|
||||
let webUrl = this.environmentService.getWebVaultUrl();
|
||||
if (webUrl == null) {
|
||||
webUrl = 'https://vault.bitwarden.com';
|
||||
}
|
||||
const webUrl = this.environmentService.getWebVaultUrl();
|
||||
for (let port = 8065; port <= 8070; port++) {
|
||||
try {
|
||||
this.ssoRedirectUri = 'http://localhost:' + port;
|
||||
|
|
|
@ -4,6 +4,7 @@ import * as fe from 'node-fetch';
|
|||
|
||||
import { ApiService } from 'jslib-common/services/api.service';
|
||||
|
||||
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
import { TokenService } from 'jslib-common/abstractions/token.service';
|
||||
|
||||
|
@ -15,8 +16,9 @@ import { TokenService } from 'jslib-common/abstractions/token.service';
|
|||
|
||||
export class NodeApiService extends ApiService {
|
||||
constructor(tokenService: TokenService, platformUtilsService: PlatformUtilsService,
|
||||
logoutCallback: (expired: boolean) => Promise<void>, customUserAgent: string = null) {
|
||||
super(tokenService, platformUtilsService, logoutCallback, customUserAgent);
|
||||
environmentService: EnvironmentService, logoutCallback: (expired: boolean) => Promise<void>,
|
||||
customUserAgent: string = null) {
|
||||
super(tokenService, platformUtilsService, environmentService, logoutCallback, customUserAgent);
|
||||
}
|
||||
|
||||
nativeFetch(request: Request): Promise<Response> {
|
||||
|
|
Loading…
Reference in New Issue