mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-24 16:49:26 +01:00
separated BrowserUtils from generic Utils
This commit is contained in:
parent
ac0126b210
commit
0dd711471b
@ -14,6 +14,7 @@ import WindowsBackground from './windows.background';
|
|||||||
import ApiService from '../services/api.service';
|
import ApiService from '../services/api.service';
|
||||||
import AppIdService from '../services/appId.service';
|
import AppIdService from '../services/appId.service';
|
||||||
import AutofillService from '../services/autofill.service';
|
import AutofillService from '../services/autofill.service';
|
||||||
|
import BrowserUtilsService from '../services/browserUtils.service';
|
||||||
import ChromeStorageService from '../services/chromeStorage.service';
|
import ChromeStorageService from '../services/chromeStorage.service';
|
||||||
import CipherService from '../services/cipher.service';
|
import CipherService from '../services/cipher.service';
|
||||||
import CollectionService from '../services/collection.service';
|
import CollectionService from '../services/collection.service';
|
||||||
@ -36,6 +37,7 @@ import { StorageService } from '../services/abstractions/storage.service';
|
|||||||
export default class MainBackground {
|
export default class MainBackground {
|
||||||
storageService: StorageService;
|
storageService: StorageService;
|
||||||
i18nService: any;
|
i18nService: any;
|
||||||
|
browserUtilsService: BrowserUtilsService;
|
||||||
utilsService: UtilsService;
|
utilsService: UtilsService;
|
||||||
constantsService: ConstantsService;
|
constantsService: ConstantsService;
|
||||||
cryptoService: CryptoService;
|
cryptoService: CryptoService;
|
||||||
@ -75,12 +77,13 @@ export default class MainBackground {
|
|||||||
// Services
|
// Services
|
||||||
this.storageService = new ChromeStorageService();
|
this.storageService = new ChromeStorageService();
|
||||||
this.utilsService = new UtilsService();
|
this.utilsService = new UtilsService();
|
||||||
this.i18nService = i18nService(this.utilsService);
|
this.browserUtilsService = new BrowserUtilsService();
|
||||||
this.constantsService = new ConstantsService(this.i18nService, this.utilsService);
|
this.i18nService = i18nService(this.browserUtilsService);
|
||||||
|
this.constantsService = new ConstantsService(this.i18nService, this.browserUtilsService);
|
||||||
this.cryptoService = new CryptoService(this.storageService, this.storageService);
|
this.cryptoService = new CryptoService(this.storageService, this.storageService);
|
||||||
this.tokenService = new TokenService(this.storageService);
|
this.tokenService = new TokenService(this.storageService);
|
||||||
this.appIdService = new AppIdService(this.storageService);
|
this.appIdService = new AppIdService(this.storageService);
|
||||||
this.apiService = new ApiService(this.tokenService, this.utilsService,
|
this.apiService = new ApiService(this.tokenService, this.browserUtilsService,
|
||||||
(expired: boolean) => this.logout(expired));
|
(expired: boolean) => this.logout(expired));
|
||||||
this.environmentService = new EnvironmentService(this.apiService, this.storageService);
|
this.environmentService = new EnvironmentService(this.apiService, this.storageService);
|
||||||
this.userService = new UserService(this.tokenService, this.storageService);
|
this.userService = new UserService(this.tokenService, this.storageService);
|
||||||
@ -91,7 +94,7 @@ export default class MainBackground {
|
|||||||
this.apiService, this.storageService);
|
this.apiService, this.storageService);
|
||||||
this.collectionService = new CollectionService(this.cryptoService, this.userService, this.storageService);
|
this.collectionService = new CollectionService(this.cryptoService, this.userService, this.storageService);
|
||||||
this.lockService = new LockService(this.cipherService, this.folderService, this.collectionService,
|
this.lockService = new LockService(this.cipherService, this.folderService, this.collectionService,
|
||||||
this.cryptoService, this.utilsService, this.storageService,
|
this.cryptoService, this.browserUtilsService, this.storageService,
|
||||||
() => this.setIcon(), () => this.refreshBadgeAndMenu());
|
() => this.setIcon(), () => this.refreshBadgeAndMenu());
|
||||||
this.syncService = new SyncService(this.userService, this.apiService, this.settingsService,
|
this.syncService = new SyncService(this.userService, this.apiService, this.settingsService,
|
||||||
this.folderService, this.cipherService, this.cryptoService, this.collectionService,
|
this.folderService, this.cipherService, this.cryptoService, this.collectionService,
|
||||||
@ -99,7 +102,7 @@ export default class MainBackground {
|
|||||||
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService);
|
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService);
|
||||||
this.totpService = new TotpService(this.storageService);
|
this.totpService = new TotpService(this.storageService);
|
||||||
this.autofillService = new AutofillService(this.cipherService, this.tokenService,
|
this.autofillService = new AutofillService(this.cipherService, this.tokenService,
|
||||||
this.totpService, this.utilsService);
|
this.totpService, this.utilsService, this.browserUtilsService);
|
||||||
|
|
||||||
// Other fields
|
// Other fields
|
||||||
this.sidebarAction = (typeof opr !== 'undefined') && opr.sidebarAction ?
|
this.sidebarAction = (typeof opr !== 'undefined') && opr.sidebarAction ?
|
||||||
@ -111,7 +114,7 @@ export default class MainBackground {
|
|||||||
this.passwordGenerationService);
|
this.passwordGenerationService);
|
||||||
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService);
|
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService);
|
||||||
this.tabsBackground = new TabsBackground(this);
|
this.tabsBackground = new TabsBackground(this);
|
||||||
this.webRequestBackground = new WebRequestBackground(this.utilsService, this.cipherService);
|
this.webRequestBackground = new WebRequestBackground(this.browserUtilsService, this.cipherService);
|
||||||
this.windowsBackground = new WindowsBackground(this);
|
this.windowsBackground = new WindowsBackground(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +254,7 @@ export default class MainBackground {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Firefox & Edge do not support writing to the clipboard from background
|
// Firefox & Edge do not support writing to the clipboard from background
|
||||||
if (!this.utilsService.isFirefox() && !this.utilsService.isEdge()) {
|
if (!this.browserUtilsService.isFirefox() && !this.browserUtilsService.isEdge()) {
|
||||||
await this.contextMenusCreate({
|
await this.contextMenusCreate({
|
||||||
type: 'normal',
|
type: 'normal',
|
||||||
id: 'copy-username',
|
id: 'copy-username',
|
||||||
@ -295,7 +298,7 @@ export default class MainBackground {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabDomain = UtilsService.getDomain(url);
|
const tabDomain = BrowserUtilsService.getDomain(url);
|
||||||
if (tabDomain == null) {
|
if (tabDomain == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -370,7 +373,7 @@ export default class MainBackground {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.utilsService.isFirefox()) {
|
if (this.browserUtilsService.isFirefox()) {
|
||||||
// Firefox does not support writing to the clipboard from background
|
// Firefox does not support writing to the clipboard from background
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -411,7 +414,7 @@ export default class MainBackground {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabDomain = UtilsService.getDomain(tab.url);
|
const tabDomain = BrowserUtilsService.getDomain(tab.url);
|
||||||
if (tabDomain == null) {
|
if (tabDomain == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -489,7 +492,7 @@ export default class MainBackground {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.utilsService.isFirefox()) {
|
if (this.browserUtilsService.isFirefox()) {
|
||||||
await theAction.setIcon(options);
|
await theAction.setIcon(options);
|
||||||
} else {
|
} else {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
@ -5,6 +5,7 @@ import BrowserApi from '../browser/browserApi';
|
|||||||
import MainBackground from './main.background';
|
import MainBackground from './main.background';
|
||||||
|
|
||||||
import AutofillService from '../services/autofill.service';
|
import AutofillService from '../services/autofill.service';
|
||||||
|
import BrowserUtilsService from '../services/browserUtils.service';
|
||||||
import CipherService from '../services/cipher.service';
|
import CipherService from '../services/cipher.service';
|
||||||
import UtilsService from '../services/utils.service';
|
import UtilsService from '../services/utils.service';
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ export default class RuntimeBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loginInfo = this.main.loginsToAdd[i];
|
const loginInfo = this.main.loginsToAdd[i];
|
||||||
const tabDomain = UtilsService.getDomain(tab.url);
|
const tabDomain = BrowserUtilsService.getDomain(tab.url);
|
||||||
if (tabDomain != null && tabDomain !== loginInfo.domain) {
|
if (tabDomain != null && tabDomain !== loginInfo.domain) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -172,7 +173,7 @@ export default class RuntimeBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loginInfo = this.main.loginsToAdd[i];
|
const loginInfo = this.main.loginsToAdd[i];
|
||||||
const tabDomain = UtilsService.getDomain(tab.url);
|
const tabDomain = BrowserUtilsService.getDomain(tab.url);
|
||||||
if (tabDomain != null && tabDomain !== loginInfo.domain) {
|
if (tabDomain != null && tabDomain !== loginInfo.domain) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -185,7 +186,7 @@ export default class RuntimeBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async addLogin(loginInfo: any, tab: any) {
|
private async addLogin(loginInfo: any, tab: any) {
|
||||||
const loginDomain = UtilsService.getDomain(loginInfo.url);
|
const loginDomain = BrowserUtilsService.getDomain(loginInfo.url);
|
||||||
if (loginDomain == null) {
|
if (loginDomain == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
|
import BrowserUtilsService from '../services/browserUtils.service';
|
||||||
import CipherService from '../services/cipher.service';
|
import CipherService from '../services/cipher.service';
|
||||||
import UtilsService from '../services/utils.service';
|
|
||||||
|
|
||||||
export default class WebRequestBackground {
|
export default class WebRequestBackground {
|
||||||
private pendingAuthRequests: any[] = [];
|
private pendingAuthRequests: any[] = [];
|
||||||
private webRequest: any;
|
private webRequest: any;
|
||||||
private isFirefox: boolean;
|
private isFirefox: boolean;
|
||||||
|
|
||||||
constructor(utilsService: UtilsService, private cipherService: CipherService) {
|
constructor(browserUtilsService: BrowserUtilsService, private cipherService: CipherService) {
|
||||||
this.webRequest = (window as any).chrome.webRequest;
|
this.webRequest = (window as any).chrome.webRequest;
|
||||||
this.isFirefox = utilsService.isFirefox();
|
this.isFirefox = browserUtilsService.isFirefox();
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
@ -24,7 +24,7 @@ export default class WebRequestBackground {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const domain = UtilsService.getDomain(details.url);
|
const domain = BrowserUtilsService.getDomain(details.url);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
|
@ -11,7 +11,7 @@ import { Identity } from './identity';
|
|||||||
import { Login } from './login';
|
import { Login } from './login';
|
||||||
import { SecureNote } from './secureNote';
|
import { SecureNote } from './secureNote';
|
||||||
|
|
||||||
import { UtilsService } from '../../services/abstractions/utils.service';
|
import { BrowserUtilsService } from '../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
class Cipher extends Domain {
|
class Cipher extends Domain {
|
||||||
id: string;
|
id: string;
|
||||||
@ -32,7 +32,7 @@ class Cipher extends Domain {
|
|||||||
fields: Field[];
|
fields: Field[];
|
||||||
collectionIds: string[];
|
collectionIds: string[];
|
||||||
|
|
||||||
private utilsService: UtilsService;
|
private browserUtilsService: BrowserUtilsService;
|
||||||
|
|
||||||
constructor(obj?: CipherData, alreadyEncrypted: boolean = false, localData: any = null) {
|
constructor(obj?: CipherData, alreadyEncrypted: boolean = false, localData: any = null) {
|
||||||
super();
|
super();
|
||||||
@ -119,12 +119,12 @@ class Cipher extends Domain {
|
|||||||
model.login = await this.login.decrypt(this.organizationId);
|
model.login = await this.login.decrypt(this.organizationId);
|
||||||
model.subTitle = model.login.username;
|
model.subTitle = model.login.username;
|
||||||
if (model.login.uri) {
|
if (model.login.uri) {
|
||||||
if (this.utilsService == null) {
|
if (this.browserUtilsService == null) {
|
||||||
this.utilsService = chrome.extension.getBackgroundPage()
|
this.browserUtilsService = chrome.extension.getBackgroundPage()
|
||||||
.bitwardenMain.utilsService as UtilsService;
|
.bitwardenMain.browserUtilsService as BrowserUtilsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
model.login.domain = this.utilsService.getDomain(model.login.uri);
|
model.login.domain = this.browserUtilsService.getDomain(model.login.uri);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CipherType.SecureNote:
|
case CipherType.SecureNote:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { BrowserType } from '../../enums/browserType.enum';
|
import { BrowserType } from '../../enums/browserType.enum';
|
||||||
import { UtilsService } from '../../services/abstractions/utils.service';
|
import { BrowserUtilsService } from '../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
class DeviceRequest {
|
class DeviceRequest {
|
||||||
type: BrowserType;
|
type: BrowserType;
|
||||||
@ -7,9 +7,9 @@ class DeviceRequest {
|
|||||||
identifier: string;
|
identifier: string;
|
||||||
pushToken?: string;
|
pushToken?: string;
|
||||||
|
|
||||||
constructor(appId: string, utilsService: UtilsService) {
|
constructor(appId: string, browserUtilsService: BrowserUtilsService) {
|
||||||
this.type = utilsService.getBrowser();
|
this.type = browserUtilsService.getBrowser();
|
||||||
this.name = utilsService.getBrowserString();
|
this.name = browserUtilsService.getBrowserString();
|
||||||
this.identifier = appId;
|
this.identifier = appId;
|
||||||
this.pushToken = null;
|
this.pushToken = null;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
angular
|
angular
|
||||||
.module('bit.accounts')
|
.module('bit.accounts')
|
||||||
|
|
||||||
.controller('accountsHintController', function ($scope, $state, apiService, toastr, $q, utilsService,
|
.controller('accountsHintController', function ($scope, $state, apiService, toastr, $q, browserUtilsService,
|
||||||
$analytics, i18nService, $timeout) {
|
$analytics, i18nService, $timeout) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
document.getElementById('email').focus();
|
document.getElementById('email').focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ angular
|
|||||||
.module('bit.accounts')
|
.module('bit.accounts')
|
||||||
|
|
||||||
.controller('accountsLoginController', function ($scope, $state, $stateParams, authService, userService, toastr,
|
.controller('accountsLoginController', function ($scope, $state, $stateParams, authService, userService, toastr,
|
||||||
utilsService, $analytics, i18nService, $timeout) {
|
browserUtilsService, $analytics, i18nService, $timeout) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
if ($stateParams.email) {
|
if ($stateParams.email) {
|
||||||
document.getElementById('master-password').focus();
|
document.getElementById('master-password').focus();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
angular
|
angular
|
||||||
.module('bit.accounts')
|
.module('bit.accounts')
|
||||||
|
|
||||||
.controller('accountsLoginTwoFactorController', function ($scope, $state, authService, toastr, utilsService, SweetAlert,
|
.controller('accountsLoginTwoFactorController', function ($scope, $state, authService, toastr, browserUtilsService, SweetAlert,
|
||||||
$analytics, i18nService, $stateParams, $filter, constantsService, $timeout, $window, cryptoService, apiService,
|
$analytics, i18nService, $stateParams, $filter, constantsService, $timeout, $window, cryptoService, apiService,
|
||||||
environmentService) {
|
environmentService) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
@ -130,7 +130,7 @@ angular
|
|||||||
var provider = $filter('filter')(constants.twoFactorProviderInfo, { type: keys[i], active: true });
|
var provider = $filter('filter')(constants.twoFactorProviderInfo, { type: keys[i], active: true });
|
||||||
if (provider.length && provider[0].priority > providerPriority) {
|
if (provider.length && provider[0].priority > providerPriority) {
|
||||||
if (provider[0].type == constants.twoFactorProvider.u2f && (typeof $window.u2f === 'undefined') &&
|
if (provider[0].type == constants.twoFactorProvider.u2f && (typeof $window.u2f === 'undefined') &&
|
||||||
!utilsService.isChrome() && !utilsService.isOpera()) {
|
!browserUtilsService.isChrome() && !browserUtilsService.isOpera()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,8 +183,8 @@ angular
|
|||||||
params = providers[constants.twoFactorProvider.email];
|
params = providers[constants.twoFactorProvider.email];
|
||||||
$scope.twoFactorEmail = params.Email;
|
$scope.twoFactorEmail = params.Email;
|
||||||
|
|
||||||
if (chrome.extension.getViews({ type: 'popup' }).length > 0 && !utilsService.inSidebar($window) &&
|
if (chrome.extension.getViews({ type: 'popup' }).length > 0 && !browserUtilsService.inSidebar($window) &&
|
||||||
!utilsService.inTab($window) && !utilsService.inPopout($window)) {
|
!browserUtilsService.inTab($window) && !browserUtilsService.inPopout($window)) {
|
||||||
SweetAlert.swal({
|
SweetAlert.swal({
|
||||||
title: i18nService.twoStepLogin,
|
title: i18nService.twoStepLogin,
|
||||||
text: i18nService.popup2faCloseMessage,
|
text: i18nService.popup2faCloseMessage,
|
||||||
|
@ -3,9 +3,9 @@ angular
|
|||||||
|
|
||||||
.controller(
|
.controller(
|
||||||
'accountsRegisterController',
|
'accountsRegisterController',
|
||||||
function ($scope, $state, cryptoService, toastr, $q, apiService, utilsService, $analytics, i18nService, $timeout) {
|
function ($scope, $state, cryptoService, toastr, $q, apiService, browserUtilsService, $analytics, i18nService, $timeout) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
document.getElementById('email').focus();
|
document.getElementById('email').focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
angular
|
angular
|
||||||
.module('bit.accounts')
|
.module('bit.accounts')
|
||||||
|
|
||||||
.controller('accountsTwoFactorMethodsController', function ($scope, $state, $stateParams, constantsService,
|
.controller('accountsTwoFactorMethodsController', function ($scope, $state, $stateParams, constantsService,
|
||||||
@ -25,7 +25,8 @@
|
|||||||
if (providers.hasOwnProperty(constants.twoFactorProvider.duo)) {
|
if (providers.hasOwnProperty(constants.twoFactorProvider.duo)) {
|
||||||
add(constants.twoFactorProvider.duo);
|
add(constants.twoFactorProvider.duo);
|
||||||
}
|
}
|
||||||
if (providers.hasOwnProperty(constants.twoFactorProvider.u2f) && (utilsService.isChrome() || utilsService.isOpera())) {
|
if (providers.hasOwnProperty(constants.twoFactorProvider.u2f) &&
|
||||||
|
(browserUtilsService.isChrome() || browserUtilsService.isOpera())) {
|
||||||
add(constants.twoFactorProvider.u2f);
|
add(constants.twoFactorProvider.u2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as template from './action-buttons.component.html';
|
import * as template from './action-buttons.component.html';
|
||||||
|
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
export class ActionButtonsController implements ng.IController {
|
export class ActionButtonsController implements ng.IController {
|
||||||
onView: Function;
|
onView: Function;
|
||||||
@ -11,7 +11,7 @@ export class ActionButtonsController implements ng.IController {
|
|||||||
constants: any;
|
constants: any;
|
||||||
|
|
||||||
constructor(private i18nService: any, private $analytics: any, private constantsService: any, private toastr: any,
|
constructor(private i18nService: any, private $analytics: any, private constantsService: any, private toastr: any,
|
||||||
private $timeout: any, private $window: any, private utilsService: UtilsService) {
|
private $timeout: any, private $window: any, private browserUtilsService: BrowserUtilsService) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
this.constants = constantsService;
|
this.constants = constantsService;
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ export class ActionButtonsController implements ng.IController {
|
|||||||
if (self.cipher.login.uri.startsWith('http://') || self.cipher.login.uri.startsWith('https://')) {
|
if (self.cipher.login.uri.startsWith('http://') || self.cipher.login.uri.startsWith('https://')) {
|
||||||
self.$analytics.eventTrack('Launched Website From Listing');
|
self.$analytics.eventTrack('Launched Website From Listing');
|
||||||
chrome.tabs.create({ url: self.cipher.login.uri });
|
chrome.tabs.create({ url: self.cipher.login.uri });
|
||||||
if (self.utilsService.inPopup(self.$window)) {
|
if (self.browserUtilsService.inPopup(self.$window)) {
|
||||||
self.$window.close();
|
self.$window.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import * as template from './pop-out.component.html';
|
import * as template from './pop-out.component.html';
|
||||||
|
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
export class PopOutController implements ng.IController {
|
export class PopOutController implements ng.IController {
|
||||||
i18n: any;
|
i18n: any;
|
||||||
|
|
||||||
constructor(private $analytics: any, private $window: any, private utilsService: UtilsService,
|
constructor(private $analytics: any, private $window: any, private browserUtilsService: BrowserUtilsService,
|
||||||
private i18nService: any) {
|
private i18nService: any) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
}
|
}
|
||||||
@ -14,7 +14,7 @@ export class PopOutController implements ng.IController {
|
|||||||
this.$analytics.eventTrack('Expand Vault');
|
this.$analytics.eventTrack('Expand Vault');
|
||||||
|
|
||||||
let href = this.$window.location.href;
|
let href = this.$window.location.href;
|
||||||
if (this.utilsService.isEdge()) {
|
if (this.browserUtilsService.isEdge()) {
|
||||||
const popupIndex = href.indexOf('/popup/');
|
const popupIndex = href.indexOf('/popup/');
|
||||||
if (popupIndex > -1) {
|
if (popupIndex > -1) {
|
||||||
href = href.substring(popupIndex);
|
href = href.substring(popupIndex);
|
||||||
@ -39,7 +39,7 @@ export class PopOutController implements ng.IController {
|
|||||||
height: bodyRect.height,
|
height: bodyRect.height,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.utilsService.inPopup(this.$window)) {
|
if (this.browserUtilsService.inPopup(this.$window)) {
|
||||||
this.$window.close();
|
this.$window.close();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { CipherType } from '../../../enums/cipherType.enum';
|
import { CipherType } from '../../../enums/cipherType.enum';
|
||||||
|
|
||||||
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
import { UtilsService } from '../../../services/abstractions/utils.service';
|
||||||
import * as template from './current.component.html';
|
import * as template from './current.component.html';
|
||||||
|
|
||||||
@ -17,12 +18,13 @@ export class CurrentController {
|
|||||||
inSidebar: boolean = false;
|
inSidebar: boolean = false;
|
||||||
disableSearch: boolean = false;
|
disableSearch: boolean = false;
|
||||||
|
|
||||||
constructor($scope: any, private cipherService: any, private utilsService: UtilsService, private toastr: any,
|
constructor($scope: any, private cipherService: any, private browserUtilsService: BrowserUtilsService,
|
||||||
private $window: any, private $state: any, private $timeout: any, private autofillService: any,
|
private utilsService: UtilsService, private toastr: any, private $window: any, private $state: any,
|
||||||
private $analytics: any, private i18nService: any, private $filter: any) {
|
private $timeout: any, private autofillService: any, private $analytics: any, private i18nService: any,
|
||||||
|
private $filter: any) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
this.inSidebar = utilsService.inSidebar($window);
|
this.inSidebar = browserUtilsService.inSidebar($window);
|
||||||
this.disableSearch = utilsService.isEdge();
|
this.disableSearch = browserUtilsService.isEdge();
|
||||||
|
|
||||||
$scope.$on('syncCompleted', (event: any, successfully: boolean) => {
|
$scope.$on('syncCompleted', (event: any, successfully: boolean) => {
|
||||||
if (this.loaded) {
|
if (this.loaded) {
|
||||||
@ -76,10 +78,10 @@ export class CurrentController {
|
|||||||
fromBackground: false,
|
fromBackground: false,
|
||||||
}).then((totpCode: string) => {
|
}).then((totpCode: string) => {
|
||||||
this.$analytics.eventTrack('Autofilled');
|
this.$analytics.eventTrack('Autofilled');
|
||||||
if (totpCode && this.utilsService.isFirefox()) {
|
if (totpCode && this.browserUtilsService.isFirefox()) {
|
||||||
this.utilsService.copyToClipboard(totpCode, document);
|
this.utilsService.copyToClipboard(totpCode, document);
|
||||||
}
|
}
|
||||||
if (this.utilsService.inPopup(this.$window)) {
|
if (this.browserUtilsService.inPopup(this.$window)) {
|
||||||
this.$window.close();
|
this.$window.close();
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@ -105,7 +107,7 @@ export class CurrentController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.domain = this.utilsService.getDomain(this.url);
|
this.domain = this.browserUtilsService.getDomain(this.url);
|
||||||
|
|
||||||
chrome.tabs.sendMessage(tabs[0].id, {
|
chrome.tabs.sendMessage(tabs[0].id, {
|
||||||
command: 'collectPageDetails',
|
command: 'collectPageDetails',
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
import * as template from './lock.component.html';
|
import * as template from './lock.component.html';
|
||||||
|
|
||||||
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
|
||||||
|
|
||||||
export class LockController {
|
export class LockController {
|
||||||
i18n: any;
|
i18n: any;
|
||||||
masterPassword: string;
|
masterPassword: string;
|
||||||
|
|
||||||
constructor(public $state: any, public i18nService: any, private $timeout: any, private utilsService: UtilsService,
|
constructor(public $state: any, public i18nService: any, private $timeout: any,
|
||||||
public cryptoService: CryptoService, public toastr: any, public userService: any,
|
private browserUtilsService: BrowserUtilsService, public cryptoService: CryptoService, public toastr: any,
|
||||||
public SweetAlert: any) {
|
public userService: any, public SweetAlert: any) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
}
|
}
|
||||||
|
|
||||||
$onInit() {
|
$onInit() {
|
||||||
this.$timeout(() => {
|
this.$timeout(() => {
|
||||||
this.utilsService.initListSectionItemListeners(document, angular);
|
this.browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
document.getElementById('master-password').focus();
|
document.getElementById('master-password').focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { DeviceRequest } from '../../../models/request/deviceRequest';
|
import { DeviceRequest } from '../../../models/request/deviceRequest';
|
||||||
import { TokenRequest } from '../../../models/request/tokenRequest';
|
import { TokenRequest } from '../../../models/request/tokenRequest';
|
||||||
|
|
||||||
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
|
||||||
|
|
||||||
class AuthService {
|
class AuthService {
|
||||||
constructor(public cryptoService: CryptoService, public apiService: any, public userService: any,
|
constructor(public cryptoService: CryptoService, public apiService: any, public userService: any,
|
||||||
public tokenService: any, public $rootScope: any, public appIdService: any, public utilsService: UtilsService,
|
public tokenService: any, public $rootScope: any, public appIdService: any,
|
||||||
public constantsService: any) {
|
public browserUtilsService: BrowserUtilsService, public constantsService: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async logIn(email: string, masterPassword: string, twoFactorProvider?: number,
|
async logIn(email: string, masterPassword: string, twoFactorProvider?: number,
|
||||||
@ -19,7 +19,7 @@ class AuthService {
|
|||||||
const storedTwoFactorToken = await this.tokenService.getTwoFactorToken(email);
|
const storedTwoFactorToken = await this.tokenService.getTwoFactorToken(email);
|
||||||
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
|
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
|
||||||
|
|
||||||
const deviceRequest = new DeviceRequest(appId, this.utilsService);
|
const deviceRequest = new DeviceRequest(appId, this.browserUtilsService);
|
||||||
|
|
||||||
let request: TokenRequest;
|
let request: TokenRequest;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
||||||
import { StorageService } from '../../../services/abstractions/storage.service';
|
import { StorageService } from '../../../services/abstractions/storage.service';
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
import { UtilsService } from '../../../services/abstractions/utils.service';
|
||||||
@ -19,6 +20,7 @@ export const cipherService = getBackgroundService<CryptoService>('cipherService'
|
|||||||
export const syncService = getBackgroundService<any>('syncService');
|
export const syncService = getBackgroundService<any>('syncService');
|
||||||
export const autofillService = getBackgroundService<any>('autofillService');
|
export const autofillService = getBackgroundService<any>('autofillService');
|
||||||
export const passwordGenerationService = getBackgroundService<any>('passwordGenerationService');
|
export const passwordGenerationService = getBackgroundService<any>('passwordGenerationService');
|
||||||
|
export const browserUtilsService = getBackgroundService<BrowserUtilsService>('browserUtilsService');
|
||||||
export const utilsService = getBackgroundService<UtilsService>('utilsService');
|
export const utilsService = getBackgroundService<UtilsService>('utilsService');
|
||||||
export const appIdService = getBackgroundService<any>('appIdService');
|
export const appIdService = getBackgroundService<any>('appIdService');
|
||||||
export const i18nService = getBackgroundService<any>('i18nService');
|
export const i18nService = getBackgroundService<any>('i18nService');
|
||||||
|
@ -20,6 +20,7 @@ export default angular
|
|||||||
.factory('syncService', backgroundServices.syncService)
|
.factory('syncService', backgroundServices.syncService)
|
||||||
.factory('autofillService', backgroundServices.autofillService)
|
.factory('autofillService', backgroundServices.autofillService)
|
||||||
.factory('passwordGenerationService', backgroundServices.passwordGenerationService)
|
.factory('passwordGenerationService', backgroundServices.passwordGenerationService)
|
||||||
|
.factory('browserUtilsService', backgroundServices.browserUtilsService)
|
||||||
.factory('utilsService', backgroundServices.utilsService)
|
.factory('utilsService', backgroundServices.utilsService)
|
||||||
.factory('appIdService', backgroundServices.appIdService)
|
.factory('appIdService', backgroundServices.appIdService)
|
||||||
.factory('i18nService', backgroundServices.i18nService)
|
.factory('i18nService', backgroundServices.i18nService)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
import UtilsService from '../../../services/utils.service';
|
import BrowserUtilsService from '../../../services/browserUtils.service';
|
||||||
import * as template from './environment.component.html';
|
import * as template from './environment.component.html';
|
||||||
|
|
||||||
export class EnvironmentController {
|
export class EnvironmentController {
|
||||||
@ -10,12 +10,12 @@ export class EnvironmentController {
|
|||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
i18n: any;
|
i18n: any;
|
||||||
|
|
||||||
constructor(private i18nService: any, private $analytics: any, utilsService: UtilsService,
|
constructor(private i18nService: any, private $analytics: any, browserUtilsService: BrowserUtilsService,
|
||||||
private environmentService: any, private toastr: any, private $timeout: ng.ITimeoutService) {
|
private environmentService: any, private toastr: any, private $timeout: ng.ITimeoutService) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
|
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
this.baseUrl = environmentService.baseUrl || '';
|
this.baseUrl = environmentService.baseUrl || '';
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
import { Folder } from '../../../../models/domain/folder';
|
import { Folder } from '../../../../models/domain/folder';
|
||||||
import { UtilsService } from '../../../../services/abstractions/utils.service';
|
|
||||||
import * as template from './add-folder.component.html';
|
import * as template from './add-folder.component.html';
|
||||||
|
|
||||||
|
import { BrowserUtilsService } from '../../../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
export class AddFolderController {
|
export class AddFolderController {
|
||||||
savePromise: any;
|
savePromise: any;
|
||||||
folder: {};
|
folder: {};
|
||||||
i18n: any;
|
i18n: any;
|
||||||
|
|
||||||
constructor(private folderService: any, private $state: any, private toastr: any, utilsService: UtilsService,
|
constructor(private folderService: any, private $state: any, private toastr: any,
|
||||||
private $analytics: any, private i18nService: any, $timeout: any) {
|
browserUtilsService: BrowserUtilsService, private $analytics: any, private i18nService: any, $timeout: any) {
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
document.getElementById('name').focus();
|
document.getElementById('name').focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
import { Folder } from '../../../../models/domain/folder';
|
import { Folder } from '../../../../models/domain/folder';
|
||||||
import UtilsService from '../../../../services/utils.service';
|
|
||||||
import * as template from './edit-folder.component.html';
|
import * as template from './edit-folder.component.html';
|
||||||
|
|
||||||
|
import { BrowserUtilsService } from '../../../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
export class EditFolderController {
|
export class EditFolderController {
|
||||||
$transition$: any;
|
$transition$: any;
|
||||||
folderId: any;
|
folderId: any;
|
||||||
@ -11,12 +12,12 @@ export class EditFolderController {
|
|||||||
folder: Folder;
|
folder: Folder;
|
||||||
|
|
||||||
constructor($scope: any, $stateParams: any, private folderService: any, private toastr: any, private $state: any,
|
constructor($scope: any, $stateParams: any, private folderService: any, private toastr: any, private $state: any,
|
||||||
private SweetAlert: any, utilsService: UtilsService, private $analytics: any, private i18nService: any,
|
private SweetAlert: any, browserUtilsService: BrowserUtilsService, private $analytics: any,
|
||||||
$timeout: any) {
|
private i18nService: any, $timeout: any) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
|
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
document.getElementById('name').focus();
|
document.getElementById('name').focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
import { StorageService } from '../../../services/abstractions/storage.service';
|
import { StorageService } from '../../../services/abstractions/storage.service';
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
|
||||||
import StateService from '../services/state.service';
|
import StateService from '../services/state.service';
|
||||||
import * as template from './options.component.html';
|
import * as template from './options.component.html';
|
||||||
|
|
||||||
@ -14,12 +14,12 @@ export class OptionsController {
|
|||||||
i18n: any;
|
i18n: any;
|
||||||
|
|
||||||
constructor(private i18nService: any, private $analytics: any, private constantsService: any,
|
constructor(private i18nService: any, private $analytics: any, private constantsService: any,
|
||||||
private utilsService: UtilsService, private totpService: any, private stateService: StateService,
|
private browserUtilsService: BrowserUtilsService, private totpService: any, private stateService: StateService,
|
||||||
private storageService: StorageService, private $timeout: ng.ITimeoutService) {
|
private storageService: StorageService, private $timeout: ng.ITimeoutService) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
|
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
this.loadSettings();
|
this.loadSettings();
|
||||||
@ -31,7 +31,7 @@ export class OptionsController {
|
|||||||
|
|
||||||
const disableGa = await this.storageService.get<boolean>(
|
const disableGa = await this.storageService.get<boolean>(
|
||||||
this.constantsService.disableGaKey);
|
this.constantsService.disableGaKey);
|
||||||
this.disableGa = disableGa || (this.utilsService.isFirefox() && disableGa === undefined);
|
this.disableGa = disableGa || (this.browserUtilsService.isFirefox() && disableGa === undefined);
|
||||||
|
|
||||||
this.disableAddLoginNotification = await this.storageService.get<boolean>(
|
this.disableAddLoginNotification = await this.storageService.get<boolean>(
|
||||||
this.constantsService.disableAddLoginNotificationKey);
|
this.constantsService.disableAddLoginNotificationKey);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
import { BrowserType } from '../../../enums/browserType.enum';
|
import { BrowserType } from '../../../enums/browserType.enum';
|
||||||
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
import { CryptoService } from '../../../services/abstractions/crypto.service';
|
||||||
import { StorageService } from '../../../services/abstractions/storage.service';
|
import { StorageService } from '../../../services/abstractions/storage.service';
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
|
||||||
import ConstantsService from '../../../services/constants.service';
|
import ConstantsService from '../../../services/constants.service';
|
||||||
|
|
||||||
import * as template from './settings.component.html';
|
import * as template from './settings.component.html';
|
||||||
@ -27,17 +27,17 @@ export class SettingsController {
|
|||||||
i18n: any;
|
i18n: any;
|
||||||
showOnLocked: boolean;
|
showOnLocked: boolean;
|
||||||
|
|
||||||
constructor(private $state: any, private SweetAlert: any, private utilsService: UtilsService,
|
constructor(private $state: any, private SweetAlert: any, private browserUtilsService: BrowserUtilsService,
|
||||||
private $analytics: any, private i18nService: any, private constantsService: ConstantsService,
|
private $analytics: any, private i18nService: any, private constantsService: ConstantsService,
|
||||||
private cryptoService: CryptoService, private lockService: any, private storageService: StorageService,
|
private cryptoService: CryptoService, private lockService: any, private storageService: StorageService,
|
||||||
private $timeout: ng.ITimeoutService) {
|
private $timeout: ng.ITimeoutService) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
|
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
this.showOnLocked = !utilsService.isFirefox() && !utilsService.isEdge();
|
this.showOnLocked = !browserUtilsService.isFirefox() && !browserUtilsService.isEdge();
|
||||||
this.storageService.get(constantsService.lockOptionKey).then((lockOption: number) => {
|
this.storageService.get(constantsService.lockOptionKey).then((lockOption: number) => {
|
||||||
if (lockOption != null) {
|
if (lockOption != null) {
|
||||||
let option = lockOption.toString();
|
let option = lockOption.toString();
|
||||||
@ -146,7 +146,7 @@ export class SettingsController {
|
|||||||
rate() {
|
rate() {
|
||||||
this.$analytics.eventTrack('Rate Extension');
|
this.$analytics.eventTrack('Rate Extension');
|
||||||
chrome.tabs.create({
|
chrome.tabs.create({
|
||||||
url: RateUrls[this.utilsService.getBrowser()],
|
url: RateUrls[this.browserUtilsService.getBrowser()],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
import * as template from './password-generator.component.html';
|
import * as template from './password-generator.component.html';
|
||||||
|
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
export class PasswordGeneratorController {
|
export class PasswordGeneratorController {
|
||||||
$transition$: any;
|
$transition$: any;
|
||||||
@ -13,7 +13,7 @@ export class PasswordGeneratorController {
|
|||||||
i18n: any;
|
i18n: any;
|
||||||
|
|
||||||
constructor(private $state: any, private passwordGenerationService: any,
|
constructor(private $state: any, private passwordGenerationService: any,
|
||||||
private toastr: any, private utilsService: UtilsService, private $analytics: any,
|
private toastr: any, private browserUtilsService: BrowserUtilsService, private $analytics: any,
|
||||||
private i18nService: any, private $timeout: any) {
|
private i18nService: any, private $timeout: any) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
|
|
||||||
@ -41,9 +41,8 @@ export class PasswordGeneratorController {
|
|||||||
|
|
||||||
this.showSelect = this.addState || this.editState;
|
this.showSelect = this.addState || this.editState;
|
||||||
|
|
||||||
const self = this;
|
|
||||||
this.$timeout(() => {
|
this.$timeout(() => {
|
||||||
self.utilsService.initListSectionItemListeners(document, angular);
|
this.browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as template from './tools.component.html';
|
import * as template from './tools.component.html';
|
||||||
|
|
||||||
import { UtilsService } from '../../../services/abstractions/utils.service';
|
import { BrowserUtilsService } from '../../../services/abstractions/browserUtils.service';
|
||||||
|
|
||||||
export class ToolsController {
|
export class ToolsController {
|
||||||
showExport: boolean;
|
showExport: boolean;
|
||||||
@ -8,10 +8,10 @@ export class ToolsController {
|
|||||||
private webVaultBaseUrl: string = 'https://vault.bitwarden.com';
|
private webVaultBaseUrl: string = 'https://vault.bitwarden.com';
|
||||||
|
|
||||||
constructor(private SweetAlert: any, private i18nService: any,
|
constructor(private SweetAlert: any, private i18nService: any,
|
||||||
private $analytics: any, private utilsService: UtilsService,
|
private $analytics: any, private browserUtilsService: BrowserUtilsService,
|
||||||
private environmentService: any) {
|
private environmentService: any) {
|
||||||
this.i18n = i18nService;
|
this.i18n = i18nService;
|
||||||
this.showExport = !utilsService.isEdge();
|
this.showExport = !browserUtilsService.isEdge();
|
||||||
if (environmentService.baseUrl) {
|
if (environmentService.baseUrl) {
|
||||||
this.webVaultBaseUrl = environmentService.baseUrl;
|
this.webVaultBaseUrl = environmentService.baseUrl;
|
||||||
} else if (environmentService.webVaultUrl) {
|
} else if (environmentService.webVaultUrl) {
|
||||||
|
@ -2,7 +2,7 @@ angular
|
|||||||
.module('bit.vault')
|
.module('bit.vault')
|
||||||
|
|
||||||
.controller('vaultAddCipherController', function ($scope, $state, $stateParams, cipherService, folderService,
|
.controller('vaultAddCipherController', function ($scope, $state, $stateParams, cipherService, folderService,
|
||||||
cryptoService, toastr, utilsService, $analytics, i18nService, constantsService, $timeout) {
|
cryptoService, toastr, browserUtilsService, $analytics, i18nService, constantsService, $timeout) {
|
||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
$scope.constants = constantsService;
|
$scope.constants = constantsService;
|
||||||
$scope.addFieldType = constantsService.fieldType.text.toString();
|
$scope.addFieldType = constantsService.fieldType.text.toString();
|
||||||
@ -31,7 +31,7 @@ angular
|
|||||||
}
|
}
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
|
|
||||||
if (!$stateParams.cipher && $scope.cipher.name && $scope.cipher.login && $scope.cipher.login.uri) {
|
if (!$stateParams.cipher && $scope.cipher.name && $scope.cipher.login && $scope.cipher.login.uri) {
|
||||||
document.getElementById('loginUsername').focus();
|
document.getElementById('loginUsername').focus();
|
||||||
@ -49,7 +49,7 @@ angular
|
|||||||
$scope.cipher.type = parseInt($scope.selectedType);
|
$scope.cipher.type = parseInt($scope.selectedType);
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ angular
|
|||||||
});
|
});
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ angular
|
|||||||
.module('bit.vault')
|
.module('bit.vault')
|
||||||
|
|
||||||
.controller('vaultAttachmentsController', function ($scope, $state, $stateParams, cipherService, toastr,
|
.controller('vaultAttachmentsController', function ($scope, $state, $stateParams, cipherService, toastr,
|
||||||
SweetAlert, utilsService, $analytics, i18nService, cryptoService, tokenService, $timeout) {
|
SweetAlert, browserUtilsService, $analytics, i18nService, cryptoService, tokenService, $timeout) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
|
@ -2,14 +2,14 @@ angular
|
|||||||
.module('bit.vault')
|
.module('bit.vault')
|
||||||
|
|
||||||
.controller('vaultController', function ($scope, $rootScope, cipherService, folderService, $q, $state, $stateParams, toastr,
|
.controller('vaultController', function ($scope, $rootScope, cipherService, folderService, $q, $state, $stateParams, toastr,
|
||||||
syncService, utilsService, $analytics, i18nService, stateService, $timeout, $window, collectionService, $filter) {
|
syncService, browserUtilsService, $analytics, i18nService, stateService, $timeout, $window, collectionService, $filter) {
|
||||||
var stateKey = 'vault',
|
var stateKey = 'vault',
|
||||||
state = stateService.getState(stateKey) || {};
|
state = stateService.getState(stateKey) || {};
|
||||||
stateService.removeState('viewGrouping');
|
stateService.removeState('viewGrouping');
|
||||||
|
|
||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
$scope.showGroupingCounts = !utilsService.isEdge();
|
$scope.showGroupingCounts = !browserUtilsService.isEdge();
|
||||||
$scope.disableSearch = utilsService.isEdge();
|
$scope.disableSearch = browserUtilsService.isEdge();
|
||||||
document.getElementById('search').focus();
|
document.getElementById('search').focus();
|
||||||
|
|
||||||
var syncOnLoad = $stateParams.syncOnLoad;
|
var syncOnLoad = $stateParams.syncOnLoad;
|
||||||
|
@ -2,15 +2,15 @@ angular
|
|||||||
.module('bit.vault')
|
.module('bit.vault')
|
||||||
|
|
||||||
.controller('vaultEditCipherController', function ($scope, $state, $stateParams, cipherService, folderService,
|
.controller('vaultEditCipherController', function ($scope, $state, $stateParams, cipherService, folderService,
|
||||||
cryptoService, toastr, SweetAlert, utilsService, $analytics, i18nService, constantsService, $timeout) {
|
cryptoService, toastr, SweetAlert, browserUtilsService, $analytics, i18nService, constantsService, $timeout) {
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
document.getElementById('name').focus();
|
document.getElementById('name').focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
$scope.constants = constantsService;
|
$scope.constants = constantsService;
|
||||||
$scope.showAttachments = !utilsService.isEdge();
|
$scope.showAttachments = !browserUtilsService.isEdge();
|
||||||
$scope.addFieldType = constantsService.fieldType.text.toString();
|
$scope.addFieldType = constantsService.fieldType.text.toString();
|
||||||
$scope.selectedType = constantsService.cipherType.login.toString();
|
$scope.selectedType = constantsService.cipherType.login.toString();
|
||||||
var cipherId = $stateParams.cipherId;
|
var cipherId = $stateParams.cipherId;
|
||||||
@ -40,7 +40,7 @@ angular
|
|||||||
$scope.cipher.type = parseInt($scope.selectedType);
|
$scope.cipher.type = parseInt($scope.selectedType);
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ angular
|
|||||||
});
|
});
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
utilsService.initListSectionItemListeners(document, angular);
|
browserUtilsService.initListSectionItemListeners(document, angular);
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@ angular
|
|||||||
.module('bit.vault')
|
.module('bit.vault')
|
||||||
|
|
||||||
.controller('vaultViewCipherController', function ($scope, $state, $stateParams, cipherService, toastr,
|
.controller('vaultViewCipherController', function ($scope, $state, $stateParams, cipherService, toastr,
|
||||||
$analytics, i18nService, utilsService, totpService, $timeout, tokenService, $window, cryptoService, SweetAlert,
|
$analytics, i18nService, browserUtilsService, totpService, $timeout, tokenService, $window, cryptoService, SweetAlert,
|
||||||
constantsService) {
|
constantsService) {
|
||||||
$scope.constants = constantsService;
|
$scope.constants = constantsService;
|
||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
$scope.showAttachments = !utilsService.isEdge();
|
$scope.showAttachments = !browserUtilsService.isEdge();
|
||||||
var from = $stateParams.from,
|
var from = $stateParams.from,
|
||||||
totpInterval = null;
|
totpInterval = null;
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ angular
|
|||||||
|
|
||||||
if (model.login.uri) {
|
if (model.login.uri) {
|
||||||
$scope.cipher.showLaunch = model.login.uri.startsWith('http://') || model.login.uri.startsWith('https://');
|
$scope.cipher.showLaunch = model.login.uri.startsWith('http://') || model.login.uri.startsWith('https://');
|
||||||
var domain = utilsService.getDomain(model.login.uri);
|
var domain = browserUtilsService.getDomain(model.login.uri);
|
||||||
if (domain) {
|
if (domain) {
|
||||||
$scope.cipher.login.website = domain;
|
$scope.cipher.login.website = domain;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ angular
|
|||||||
.module('bit.vault')
|
.module('bit.vault')
|
||||||
|
|
||||||
.controller('vaultViewGroupingController', function ($scope, cipherService, folderService, $q, $state, $stateParams, toastr,
|
.controller('vaultViewGroupingController', function ($scope, cipherService, folderService, $q, $state, $stateParams, toastr,
|
||||||
syncService, $analytics, i18nService, stateService, utilsService, $timeout, $window, collectionService) {
|
syncService, $analytics, i18nService, stateService, browserUtilsService, $timeout, $window, collectionService) {
|
||||||
var stateKey = 'viewGrouping',
|
var stateKey = 'viewGrouping',
|
||||||
state = stateService.getState(stateKey) || {};
|
state = stateService.getState(stateKey) || {};
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ angular
|
|||||||
|
|
||||||
var cipherPromise = cipherService.getAllDecryptedForGrouping($scope.grouping.id, $scope.folderGrouping)
|
var cipherPromise = cipherService.getAllDecryptedForGrouping($scope.grouping.id, $scope.folderGrouping)
|
||||||
.then(function (ciphers) {
|
.then(function (ciphers) {
|
||||||
if (utilsService.isEdge()) {
|
if (browserUtilsService.isEdge()) {
|
||||||
// Edge is super slow at sorting
|
// Edge is super slow at sorting
|
||||||
decCiphers = ciphers;
|
decCiphers = ciphers;
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var gaTrackingId = bgMain.utilsService.analyticsId();
|
var gaTrackingId = bgMain.browserUtilsService.analyticsId();
|
||||||
var gaFunc = null;
|
var gaFunc = null;
|
||||||
var isFirefox = bgMain.utilsService.isFirefox();
|
var isFirefox = bgMain.browserUtilsService.isFirefox();
|
||||||
|
|
||||||
window.GoogleAnalyticsObject = 'ga';
|
window.GoogleAnalyticsObject = 'ga';
|
||||||
window[window.GoogleAnalyticsObject] = function (action, param1, param2, param3, param4) {
|
window[window.GoogleAnalyticsObject] = function (action, param1, param2, param3, param4) {
|
||||||
|
17
src/services/abstractions/browserUtils.service.ts
Normal file
17
src/services/abstractions/browserUtils.service.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { BrowserType } from '../../enums/browserType.enum';
|
||||||
|
|
||||||
|
export interface BrowserUtilsService {
|
||||||
|
getBrowser(): BrowserType;
|
||||||
|
getBrowserString(): string;
|
||||||
|
isFirefox(): boolean;
|
||||||
|
isChrome(): boolean;
|
||||||
|
isEdge(): boolean;
|
||||||
|
isOpera(): boolean;
|
||||||
|
analyticsId(): string;
|
||||||
|
initListSectionItemListeners(doc: Document, angular: any): void;
|
||||||
|
getDomain(uriString: string): string;
|
||||||
|
inSidebar(theWindow: Window): boolean;
|
||||||
|
inTab(theWindow: Window): boolean;
|
||||||
|
inPopout(theWindow: Window): boolean;
|
||||||
|
inPopup(theWindow: Window): boolean;
|
||||||
|
}
|
@ -1,19 +1,4 @@
|
|||||||
import { BrowserType } from '../../enums/browserType.enum';
|
|
||||||
|
|
||||||
export interface UtilsService {
|
export interface UtilsService {
|
||||||
getBrowser(): BrowserType;
|
|
||||||
getBrowserString(): string;
|
|
||||||
isFirefox(): boolean;
|
|
||||||
isChrome(): boolean;
|
|
||||||
isEdge(): boolean;
|
|
||||||
isOpera(): boolean;
|
|
||||||
analyticsId(): string;
|
|
||||||
initListSectionItemListeners(doc: Document, angular: any): void;
|
|
||||||
copyToClipboard(text: string, doc?: Document): void;
|
copyToClipboard(text: string, doc?: Document): void;
|
||||||
getDomain(uriString: string): string;
|
|
||||||
getHostname(uriString: string): string;
|
getHostname(uriString: string): string;
|
||||||
inSidebar(theWindow: Window): boolean;
|
|
||||||
inTab(theWindow: Window): boolean;
|
|
||||||
inPopout(theWindow: Window): boolean;
|
|
||||||
inPopup(theWindow: Window): boolean;
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import AppIdService from './appId.service';
|
import AppIdService from './appId.service';
|
||||||
|
import BrowserUtilsService from './browserUtils.service';
|
||||||
import ConstantsService from './constants.service';
|
import ConstantsService from './constants.service';
|
||||||
import TokenService from './token.service';
|
import TokenService from './token.service';
|
||||||
import UtilsService from './utils.service';
|
|
||||||
|
|
||||||
import EnvironmentUrls from '../models/domain/environmentUrls';
|
import EnvironmentUrls from '../models/domain/environmentUrls';
|
||||||
|
|
||||||
@ -32,11 +32,13 @@ export default class ApiService {
|
|||||||
urlsSet: boolean = false;
|
urlsSet: boolean = false;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
identityBaseUrl: string;
|
identityBaseUrl: string;
|
||||||
|
deviceType: string;
|
||||||
logoutCallback: Function;
|
logoutCallback: Function;
|
||||||
|
|
||||||
constructor(private tokenService: TokenService, private utilsService: UtilsService,
|
constructor(private tokenService: TokenService, browserUtilsService: BrowserUtilsService,
|
||||||
logoutCallback: Function) {
|
logoutCallback: Function) {
|
||||||
this.logoutCallback = logoutCallback;
|
this.logoutCallback = logoutCallback;
|
||||||
|
this.deviceType = browserUtilsService.getBrowser().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
setUrls(urls: EnvironmentUrls) {
|
setUrls(urls: EnvironmentUrls) {
|
||||||
@ -86,7 +88,7 @@ export default class ApiService {
|
|||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
|
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
@ -126,7 +128,7 @@ export default class ApiService {
|
|||||||
cache: 'no-cache',
|
cache: 'no-cache',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
@ -146,7 +148,7 @@ export default class ApiService {
|
|||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -164,7 +166,7 @@ export default class ApiService {
|
|||||||
cache: 'no-cache',
|
cache: 'no-cache',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
@ -181,7 +183,7 @@ export default class ApiService {
|
|||||||
cache: 'no-cache',
|
cache: 'no-cache',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
@ -203,7 +205,7 @@ export default class ApiService {
|
|||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
@ -226,7 +228,7 @@ export default class ApiService {
|
|||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
}));
|
}));
|
||||||
@ -246,7 +248,7 @@ export default class ApiService {
|
|||||||
cache: 'no-cache',
|
cache: 'no-cache',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
}));
|
}));
|
||||||
@ -268,7 +270,7 @@ export default class ApiService {
|
|||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
@ -291,7 +293,7 @@ export default class ApiService {
|
|||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
}));
|
}));
|
||||||
@ -311,7 +313,7 @@ export default class ApiService {
|
|||||||
cache: 'no-cache',
|
cache: 'no-cache',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
}));
|
}));
|
||||||
@ -332,7 +334,7 @@ export default class ApiService {
|
|||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
@ -352,7 +354,7 @@ export default class ApiService {
|
|||||||
cache: 'no-cache',
|
cache: 'no-cache',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
}));
|
}));
|
||||||
@ -372,7 +374,7 @@ export default class ApiService {
|
|||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': authHeader,
|
'Authorization': authHeader,
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -430,7 +432,7 @@ export default class ApiService {
|
|||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
|
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Device-Type': this.utilsService.getBrowser().toString(),
|
'Device-Type': this.deviceType,
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
}));
|
}));
|
||||||
|
@ -5,6 +5,7 @@ import AutofillField from '../models/domain/autofillField';
|
|||||||
import AutofillPageDetails from '../models/domain/autofillPageDetails';
|
import AutofillPageDetails from '../models/domain/autofillPageDetails';
|
||||||
import AutofillScript from '../models/domain/autofillScript';
|
import AutofillScript from '../models/domain/autofillScript';
|
||||||
|
|
||||||
|
import BrowserUtilsService from './browserUtils.service';
|
||||||
import CipherService from './cipher.service';
|
import CipherService from './cipher.service';
|
||||||
import TokenService from './token.service';
|
import TokenService from './token.service';
|
||||||
import TotpService from './totp.service';
|
import TotpService from './totp.service';
|
||||||
@ -92,7 +93,8 @@ var IsoProvinces: { [id: string]: string; } = {
|
|||||||
|
|
||||||
export default class AutofillService {
|
export default class AutofillService {
|
||||||
constructor(public cipherService: CipherService, public tokenService: TokenService,
|
constructor(public cipherService: CipherService, public tokenService: TokenService,
|
||||||
public totpService: TotpService, public utilsService: UtilsService) {
|
public totpService: TotpService, public utilsService: UtilsService,
|
||||||
|
public browserUtilsService: BrowserUtilsService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormsWithPasswordFields(pageDetails: AutofillPageDetails): any[] {
|
getFormsWithPasswordFields(pageDetails: AutofillPageDetails): any[] {
|
||||||
@ -167,7 +169,7 @@ export default class AutofillService {
|
|||||||
}, { frameId: pd.frameId });
|
}, { frameId: pd.frameId });
|
||||||
|
|
||||||
if (options.cipher.type !== CipherType.Login || totpPromise ||
|
if (options.cipher.type !== CipherType.Login || totpPromise ||
|
||||||
(options.fromBackground && this.utilsService.isFirefox()) || options.skipTotp ||
|
(options.fromBackground && this.browserUtilsService.isFirefox()) || options.skipTotp ||
|
||||||
!options.cipher.login.totp || !this.tokenService.getPremium()) {
|
!options.cipher.login.totp || !this.tokenService.getPremium()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -205,7 +207,7 @@ export default class AutofillService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabDomain = UtilsService.getDomain(tab.url);
|
const tabDomain = BrowserUtilsService.getDomain(tab.url);
|
||||||
if (tabDomain == null) {
|
if (tabDomain == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
84
src/services/browserUtils.service.spec.ts
Normal file
84
src/services/browserUtils.service.spec.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import BrowserUtilsService from './browserUtils.service';
|
||||||
|
import { BrowserType } from '../enums/browserType.enum';
|
||||||
|
|
||||||
|
describe('Browser Utils Service', () => {
|
||||||
|
describe('getDomain', () => {
|
||||||
|
it('should fail for invalid urls', () => {
|
||||||
|
expect(BrowserUtilsService.getDomain(null)).toBeNull();
|
||||||
|
expect(BrowserUtilsService.getDomain(undefined)).toBeNull();
|
||||||
|
expect(BrowserUtilsService.getDomain(' ')).toBeNull();
|
||||||
|
expect(BrowserUtilsService.getDomain('https://bit!:"_&ward.com')).toBeNull();
|
||||||
|
expect(BrowserUtilsService.getDomain('bitwarden')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle urls without protocol', () => {
|
||||||
|
expect(BrowserUtilsService.getDomain('bitwarden.com')).toBe('bitwarden.com');
|
||||||
|
expect(BrowserUtilsService.getDomain('wrong://bitwarden.com')).toBe('bitwarden.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle valid urls', () => {
|
||||||
|
expect(BrowserUtilsService.getDomain('https://bitwarden')).toBe('bitwarden');
|
||||||
|
expect(BrowserUtilsService.getDomain('https://bitwarden.com')).toBe('bitwarden.com');
|
||||||
|
expect(BrowserUtilsService.getDomain('http://bitwarden.com')).toBe('bitwarden.com');
|
||||||
|
expect(BrowserUtilsService.getDomain('http://vault.bitwarden.com')).toBe('bitwarden.com');
|
||||||
|
expect(BrowserUtilsService.getDomain('https://user:password@bitwarden.com:8080/password/sites?and&query#hash')).toBe('bitwarden.com');
|
||||||
|
expect(BrowserUtilsService.getDomain('https://bitwarden.unknown')).toBe('bitwarden.unknown');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support localhost and IP', () => {
|
||||||
|
expect(BrowserUtilsService.getDomain('https://localhost')).toBe('localhost');
|
||||||
|
expect(BrowserUtilsService.getDomain('https://192.168.1.1')).toBe('192.168.1.1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getBrowser', () => {
|
||||||
|
const original = navigator.userAgent;
|
||||||
|
|
||||||
|
// Reset the userAgent.
|
||||||
|
afterAll(() => {
|
||||||
|
Object.defineProperty(navigator, 'userAgent', {
|
||||||
|
value: original
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect chrome', () => {
|
||||||
|
Object.defineProperty(navigator, 'userAgent', {
|
||||||
|
configurable: true,
|
||||||
|
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
|
||||||
|
});
|
||||||
|
|
||||||
|
const browserUtilsService = new BrowserUtilsService();
|
||||||
|
expect(browserUtilsService.getBrowser()).toBe(BrowserType.Chrome);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect firefox', () => {
|
||||||
|
Object.defineProperty(navigator, 'userAgent', {
|
||||||
|
configurable: true,
|
||||||
|
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0'
|
||||||
|
});
|
||||||
|
|
||||||
|
const browserUtilsService = new BrowserUtilsService();
|
||||||
|
expect(browserUtilsService.getBrowser()).toBe(BrowserType.Firefox);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect opera', () => {
|
||||||
|
Object.defineProperty(navigator, 'userAgent', {
|
||||||
|
configurable: true,
|
||||||
|
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3175.3 Safari/537.36 OPR/49.0.2695.0 (Edition developer)'
|
||||||
|
});
|
||||||
|
|
||||||
|
const browserUtilsService = new BrowserUtilsService();
|
||||||
|
expect(browserUtilsService.getBrowser()).toBe(BrowserType.Opera);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect edge', () => {
|
||||||
|
Object.defineProperty(navigator, 'userAgent', {
|
||||||
|
configurable: true,
|
||||||
|
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ServiceUI 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063'
|
||||||
|
});
|
||||||
|
|
||||||
|
const browserUtilsService = new BrowserUtilsService();
|
||||||
|
expect(browserUtilsService.getBrowser()).toBe(BrowserType.Edge);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
215
src/services/browserUtils.service.ts
Normal file
215
src/services/browserUtils.service.ts
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
import * as tldjs from 'tldjs';
|
||||||
|
import { BrowserType } from '../enums/browserType.enum';
|
||||||
|
import { BrowserUtilsService as BrowserUtilsServiceInterface } from './abstractions/browserUtils.service';
|
||||||
|
|
||||||
|
const AnalyticsIds = {
|
||||||
|
[BrowserType.Chrome]: 'UA-81915606-6',
|
||||||
|
[BrowserType.Firefox]: 'UA-81915606-7',
|
||||||
|
[BrowserType.Opera]: 'UA-81915606-8',
|
||||||
|
[BrowserType.Edge]: 'UA-81915606-9',
|
||||||
|
[BrowserType.Vivaldi]: 'UA-81915606-15',
|
||||||
|
[BrowserType.Safari]: 'UA-81915606-16',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class BrowserUtilsService implements BrowserUtilsServiceInterface {
|
||||||
|
static getDomain(uriString: string): string {
|
||||||
|
if (uriString == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
uriString = uriString.trim();
|
||||||
|
if (uriString === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uriString.startsWith('http://') || uriString.startsWith('https://')) {
|
||||||
|
try {
|
||||||
|
const url = new URL(uriString);
|
||||||
|
|
||||||
|
if (url.hostname === 'localhost' || BrowserUtilsService.validIpAddress(url.hostname)) {
|
||||||
|
return url.hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlDomain = tldjs.getDomain(url.hostname);
|
||||||
|
return urlDomain != null ? urlDomain : url.hostname;
|
||||||
|
} catch (e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
const domain = tldjs.getDomain(uriString);
|
||||||
|
if (domain != null) {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static validIpAddress(ipString: string): boolean {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
const ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
||||||
|
return ipRegex.test(ipString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private browserCache: BrowserType = null;
|
||||||
|
private analyticsIdCache: string = null;
|
||||||
|
|
||||||
|
getBrowser(): BrowserType {
|
||||||
|
if (this.browserCache) {
|
||||||
|
return this.browserCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigator.userAgent.indexOf('Firefox') !== -1 || navigator.userAgent.indexOf('Gecko/') !== -1) {
|
||||||
|
this.browserCache = BrowserType.Firefox;
|
||||||
|
} else if ((!!(window as any).opr && !!opr.addons) || !!(window as any).opera ||
|
||||||
|
navigator.userAgent.indexOf(' OPR/') >= 0) {
|
||||||
|
this.browserCache = BrowserType.Opera;
|
||||||
|
} else if (navigator.userAgent.indexOf(' Edge/') !== -1) {
|
||||||
|
this.browserCache = BrowserType.Edge;
|
||||||
|
} else if (navigator.userAgent.indexOf(' Vivaldi/') !== -1) {
|
||||||
|
this.browserCache = BrowserType.Vivaldi;
|
||||||
|
} else if ((window as any).chrome) {
|
||||||
|
this.browserCache = BrowserType.Chrome;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.browserCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBrowserString(): string {
|
||||||
|
return BrowserType[this.getBrowser()].toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
isFirefox(): boolean {
|
||||||
|
return this.getBrowser() === BrowserType.Firefox;
|
||||||
|
}
|
||||||
|
|
||||||
|
isChrome(): boolean {
|
||||||
|
return this.getBrowser() === BrowserType.Chrome;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEdge(): boolean {
|
||||||
|
return this.getBrowser() === BrowserType.Edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOpera(): boolean {
|
||||||
|
return this.getBrowser() === BrowserType.Opera;
|
||||||
|
}
|
||||||
|
|
||||||
|
isVivaldi(): boolean {
|
||||||
|
return this.getBrowser() === BrowserType.Vivaldi;
|
||||||
|
}
|
||||||
|
|
||||||
|
isSafari(): boolean {
|
||||||
|
return this.getBrowser() === BrowserType.Safari;
|
||||||
|
}
|
||||||
|
|
||||||
|
analyticsId(): string {
|
||||||
|
if (this.analyticsIdCache) {
|
||||||
|
return this.analyticsIdCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.analyticsIdCache = AnalyticsIds[this.getBrowser()];
|
||||||
|
return this.analyticsIdCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
initListSectionItemListeners(doc: Document, angular: any): void {
|
||||||
|
if (!doc) {
|
||||||
|
throw new Error('doc parameter required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const sectionItems = doc.querySelectorAll(
|
||||||
|
'.list-section-item:not([data-bw-events="1"])');
|
||||||
|
const sectionFormItems = doc.querySelectorAll(
|
||||||
|
'.list-section-item:not([data-bw-events="1"]) input, ' +
|
||||||
|
'.list-section-item:not([data-bw-events="1"]) select, ' +
|
||||||
|
'.list-section-item:not([data-bw-events="1"]) textarea');
|
||||||
|
|
||||||
|
sectionItems.forEach((item) => {
|
||||||
|
(item as HTMLElement).dataset.bwEvents = '1';
|
||||||
|
|
||||||
|
item.addEventListener('click', (e) => {
|
||||||
|
if (e.defaultPrevented) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const el = e.target as HTMLElement;
|
||||||
|
|
||||||
|
// Some elements will already focus properly
|
||||||
|
if (el.tagName != null) {
|
||||||
|
switch (el.tagName.toLowerCase()) {
|
||||||
|
case 'label': case 'input': case 'textarea': case 'select':
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cell = el.closest('.list-section-item');
|
||||||
|
if (!cell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const textFilter = 'input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"])';
|
||||||
|
const text = cell.querySelectorAll(textFilter + ', textarea');
|
||||||
|
const checkbox = cell.querySelectorAll('input[type="checkbox"]');
|
||||||
|
const select = cell.querySelectorAll('select');
|
||||||
|
|
||||||
|
if (text.length > 0) {
|
||||||
|
(text[0] as HTMLElement).focus();
|
||||||
|
} else if (select.length > 0) {
|
||||||
|
(select[0] as HTMLElement).focus();
|
||||||
|
} else if (checkbox.length > 0) {
|
||||||
|
const cb = checkbox[0] as HTMLInputElement;
|
||||||
|
cb.checked = !cb.checked;
|
||||||
|
if (angular) {
|
||||||
|
angular.element(checkbox[0]).triggerHandler('click');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
sectionFormItems.forEach((item) => {
|
||||||
|
const itemCell = item.closest('.list-section-item');
|
||||||
|
(itemCell as HTMLElement).dataset.bwEvents = '1';
|
||||||
|
|
||||||
|
item.addEventListener('focus', (e: Event) => {
|
||||||
|
const el = e.target as HTMLElement;
|
||||||
|
const cell = el.closest('.list-section-item');
|
||||||
|
if (!cell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.classList.add('active');
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
item.addEventListener('blur', (e: Event) => {
|
||||||
|
const el = e.target as HTMLElement;
|
||||||
|
const cell = el.closest('.list-section-item');
|
||||||
|
if (!cell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.classList.remove('active');
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getDomain(uriString: string): string {
|
||||||
|
return BrowserUtilsService.getDomain(uriString);
|
||||||
|
}
|
||||||
|
|
||||||
|
inSidebar(theWindow: Window): boolean {
|
||||||
|
return theWindow.location.search !== '' && theWindow.location.search.indexOf('uilocation=sidebar') > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inTab(theWindow: Window): boolean {
|
||||||
|
return theWindow.location.search !== '' && theWindow.location.search.indexOf('uilocation=tab') > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inPopout(theWindow: Window): boolean {
|
||||||
|
return theWindow.location.search !== '' && theWindow.location.search.indexOf('uilocation=popout') > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inPopup(theWindow: Window): boolean {
|
||||||
|
return theWindow.location.search === '' || theWindow.location.search.indexOf('uilocation=') === -1 ||
|
||||||
|
theWindow.location.search.indexOf('uilocation=popup') > -1;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import UtilsService from './utils.service';
|
import BrowserUtilsService from './browserUtils.service';
|
||||||
|
|
||||||
export default class ConstantsService {
|
export default class ConstantsService {
|
||||||
static readonly environmentUrlsKey: string = 'environmentUrls';
|
static readonly environmentUrlsKey: string = 'environmentUrls';
|
||||||
@ -57,8 +57,8 @@ export default class ConstantsService {
|
|||||||
|
|
||||||
twoFactorProviderInfo: any[];
|
twoFactorProviderInfo: any[];
|
||||||
|
|
||||||
constructor(i18nService: any, utilsService: UtilsService) {
|
constructor(i18nService: any, browserUtilsService: BrowserUtilsService) {
|
||||||
if (utilsService.isEdge()) {
|
if (browserUtilsService.isEdge()) {
|
||||||
// delay for i18n fetch
|
// delay for i18n fetch
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.bootstrap(i18nService);
|
this.bootstrap(i18nService);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import UtilsService from '../services/utils.service';
|
import BrowserUtilsService from '../services/browserUtils.service';
|
||||||
|
|
||||||
export default function i18nService(utilsService: UtilsService) {
|
export default function i18nService(browserUtilsService: BrowserUtilsService) {
|
||||||
const edgeMessages: any = {};
|
const edgeMessages: any = {};
|
||||||
|
|
||||||
if (utilsService.isEdge()) {
|
if (browserUtilsService.isEdge()) {
|
||||||
fetch('../_locales/en/messages.json').then((file) => {
|
fetch('../_locales/en/messages.json').then((file) => {
|
||||||
return file.json();
|
return file.json();
|
||||||
}).then((locales) => {
|
}).then((locales) => {
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
|
import BrowserUtilsService from './browserUtils.service';
|
||||||
import CipherService from './cipher.service';
|
import CipherService from './cipher.service';
|
||||||
import CollectionService from './collection.service';
|
import CollectionService from './collection.service';
|
||||||
import ConstantsService from './constants.service';
|
import ConstantsService from './constants.service';
|
||||||
import CryptoService from './crypto.service';
|
import CryptoService from './crypto.service';
|
||||||
import FolderService from './folder.service';
|
import FolderService from './folder.service';
|
||||||
import UtilsService from './utils.service';
|
|
||||||
|
|
||||||
import { StorageService } from './abstractions/storage.service';
|
import { StorageService } from './abstractions/storage.service';
|
||||||
|
|
||||||
export default class LockService {
|
export default class LockService {
|
||||||
constructor(private cipherService: CipherService, private folderService: FolderService,
|
constructor(private cipherService: CipherService, private folderService: FolderService,
|
||||||
private collectionService: CollectionService, private cryptoService: CryptoService,
|
private collectionService: CollectionService, private cryptoService: CryptoService,
|
||||||
private utilsService: UtilsService, private storageService: StorageService,
|
private browserUtilsService: BrowserUtilsService, private storageService: StorageService,
|
||||||
private setIcon: Function, private refreshBadgeAndMenu: Function) {
|
private setIcon: Function, private refreshBadgeAndMenu: Function) {
|
||||||
this.checkLock();
|
this.checkLock();
|
||||||
setInterval(() => this.checkLock(), 10 * 1000); // check every 10 seconds
|
setInterval(() => this.checkLock(), 10 * 1000); // check every 10 seconds
|
||||||
@ -81,9 +81,9 @@ export default class LockService {
|
|||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
private sidebarViewName(): string {
|
private sidebarViewName(): string {
|
||||||
if ((window as any).chrome.sidebarAction && this.utilsService.isFirefox()) {
|
if ((window as any).chrome.sidebarAction && this.browserUtilsService.isFirefox()) {
|
||||||
return 'sidebar';
|
return 'sidebar';
|
||||||
} else if (this.utilsService.isOpera() && (typeof opr !== 'undefined') && opr.sidebarAction) {
|
} else if (this.browserUtilsService.isOpera() && (typeof opr !== 'undefined') && opr.sidebarAction) {
|
||||||
return 'sidebar_panel';
|
return 'sidebar_panel';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,36 +1,6 @@
|
|||||||
import UtilsService from './utils.service';
|
import UtilsService from './utils.service';
|
||||||
import { BrowserType } from '../enums/browserType.enum';
|
|
||||||
|
|
||||||
describe('Utils Service', () => {
|
describe('Utils Service', () => {
|
||||||
describe('getDomain', () => {
|
|
||||||
it('should fail for invalid urls', () => {
|
|
||||||
expect(UtilsService.getDomain(null)).toBeNull();
|
|
||||||
expect(UtilsService.getDomain(undefined)).toBeNull();
|
|
||||||
expect(UtilsService.getDomain(' ')).toBeNull();
|
|
||||||
expect(UtilsService.getDomain('https://bit!:"_&ward.com')).toBeNull();
|
|
||||||
expect(UtilsService.getDomain('bitwarden')).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle urls without protocol', () => {
|
|
||||||
expect(UtilsService.getDomain('bitwarden.com')).toBe('bitwarden.com');
|
|
||||||
expect(UtilsService.getDomain('wrong://bitwarden.com')).toBe('bitwarden.com');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle valid urls', () => {
|
|
||||||
expect(UtilsService.getDomain('https://bitwarden')).toBe('bitwarden');
|
|
||||||
expect(UtilsService.getDomain('https://bitwarden.com')).toBe('bitwarden.com');
|
|
||||||
expect(UtilsService.getDomain('http://bitwarden.com')).toBe('bitwarden.com');
|
|
||||||
expect(UtilsService.getDomain('http://vault.bitwarden.com')).toBe('bitwarden.com');
|
|
||||||
expect(UtilsService.getDomain('https://user:password@bitwarden.com:8080/password/sites?and&query#hash')).toBe('bitwarden.com');
|
|
||||||
expect(UtilsService.getDomain('https://bitwarden.unknown')).toBe('bitwarden.unknown');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support localhost and IP', () => {
|
|
||||||
expect(UtilsService.getDomain('https://localhost')).toBe('localhost');
|
|
||||||
expect(UtilsService.getDomain('https://192.168.1.1')).toBe('192.168.1.1');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getHostname', () => {
|
describe('getHostname', () => {
|
||||||
it('should fail for invalid urls', () => {
|
it('should fail for invalid urls', () => {
|
||||||
expect(UtilsService.getHostname(null)).toBeNull();
|
expect(UtilsService.getHostname(null)).toBeNull();
|
||||||
@ -59,55 +29,4 @@ describe('Utils Service', () => {
|
|||||||
expect(UtilsService.newGuid()).toMatch(validGuid);
|
expect(UtilsService.newGuid()).toMatch(validGuid);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getBrowser', () => {
|
|
||||||
const original = navigator.userAgent;
|
|
||||||
|
|
||||||
// Reset the userAgent.
|
|
||||||
afterAll(() => {
|
|
||||||
Object.defineProperty(navigator, 'userAgent', {
|
|
||||||
value: original
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should detect chrome', () => {
|
|
||||||
Object.defineProperty(navigator, 'userAgent', {
|
|
||||||
configurable: true,
|
|
||||||
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
|
|
||||||
});
|
|
||||||
|
|
||||||
const utilsService = new UtilsService();
|
|
||||||
expect(utilsService.getBrowser()).toBe(BrowserType.Chrome);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should detect firefox', () => {
|
|
||||||
Object.defineProperty(navigator, 'userAgent', {
|
|
||||||
configurable: true,
|
|
||||||
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0'
|
|
||||||
});
|
|
||||||
|
|
||||||
const utilsService = new UtilsService();
|
|
||||||
expect(utilsService.getBrowser()).toBe(BrowserType.Firefox);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should detect opera', () => {
|
|
||||||
Object.defineProperty(navigator, 'userAgent', {
|
|
||||||
configurable: true,
|
|
||||||
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3175.3 Safari/537.36 OPR/49.0.2695.0 (Edition developer)'
|
|
||||||
});
|
|
||||||
|
|
||||||
const utilsService = new UtilsService();
|
|
||||||
expect(utilsService.getBrowser()).toBe(BrowserType.Opera);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should detect edge', () => {
|
|
||||||
Object.defineProperty(navigator, 'userAgent', {
|
|
||||||
configurable: true,
|
|
||||||
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ServiceUI 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063'
|
|
||||||
});
|
|
||||||
|
|
||||||
const utilsService = new UtilsService();
|
|
||||||
expect(utilsService.getBrowser()).toBe(BrowserType.Edge);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,16 +1,5 @@
|
|||||||
import * as tldjs from 'tldjs';
|
|
||||||
import { BrowserType } from '../enums/browserType.enum';
|
|
||||||
import { UtilsService as UtilsServiceInterface } from './abstractions/utils.service';
|
import { UtilsService as UtilsServiceInterface } from './abstractions/utils.service';
|
||||||
|
|
||||||
const AnalyticsIds = {
|
|
||||||
[BrowserType.Chrome]: 'UA-81915606-6',
|
|
||||||
[BrowserType.Firefox]: 'UA-81915606-7',
|
|
||||||
[BrowserType.Opera]: 'UA-81915606-8',
|
|
||||||
[BrowserType.Edge]: 'UA-81915606-9',
|
|
||||||
[BrowserType.Vivaldi]: 'UA-81915606-15',
|
|
||||||
[BrowserType.Safari]: 'UA-81915606-16',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class UtilsService implements UtilsServiceInterface {
|
export default class UtilsService implements UtilsServiceInterface {
|
||||||
static copyToClipboard(text: string, doc?: Document): void {
|
static copyToClipboard(text: string, doc?: Document): void {
|
||||||
doc = doc || document;
|
doc = doc || document;
|
||||||
@ -136,37 +125,6 @@ export default class UtilsService implements UtilsServiceInterface {
|
|||||||
return decodeURIComponent(escape(encodedString));
|
return decodeURIComponent(escape(encodedString));
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDomain(uriString: string): string {
|
|
||||||
if (uriString == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
uriString = uriString.trim();
|
|
||||||
if (uriString === '') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uriString.startsWith('http://') || uriString.startsWith('https://')) {
|
|
||||||
try {
|
|
||||||
const url = new URL(uriString);
|
|
||||||
|
|
||||||
if (url.hostname === 'localhost' || UtilsService.validIpAddress(url.hostname)) {
|
|
||||||
return url.hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
const urlDomain = tldjs.getDomain(url.hostname);
|
|
||||||
return urlDomain != null ? urlDomain : url.hostname;
|
|
||||||
} catch (e) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
const domain = tldjs.getDomain(uriString);
|
|
||||||
if (domain != null) {
|
|
||||||
return domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static getHostname(uriString: string): string {
|
static getHostname(uriString: string): string {
|
||||||
if (uriString == null) {
|
if (uriString == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -187,159 +145,6 @@ export default class UtilsService implements UtilsServiceInterface {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static validIpAddress(ipString: string): boolean {
|
|
||||||
// tslint:disable-next-line
|
|
||||||
const ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
||||||
return ipRegex.test(ipString);
|
|
||||||
}
|
|
||||||
|
|
||||||
private browserCache: BrowserType = null;
|
|
||||||
private analyticsIdCache: string = null;
|
|
||||||
|
|
||||||
getBrowser(): BrowserType {
|
|
||||||
if (this.browserCache) {
|
|
||||||
return this.browserCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (navigator.userAgent.indexOf('Firefox') !== -1 || navigator.userAgent.indexOf('Gecko/') !== -1) {
|
|
||||||
this.browserCache = BrowserType.Firefox;
|
|
||||||
} else if ((!!(window as any).opr && !!opr.addons) || !!(window as any).opera ||
|
|
||||||
navigator.userAgent.indexOf(' OPR/') >= 0) {
|
|
||||||
this.browserCache = BrowserType.Opera;
|
|
||||||
} else if (navigator.userAgent.indexOf(' Edge/') !== -1) {
|
|
||||||
this.browserCache = BrowserType.Edge;
|
|
||||||
} else if (navigator.userAgent.indexOf(' Vivaldi/') !== -1) {
|
|
||||||
this.browserCache = BrowserType.Vivaldi;
|
|
||||||
} else if ((window as any).chrome) {
|
|
||||||
this.browserCache = BrowserType.Chrome;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.browserCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
getBrowserString(): string {
|
|
||||||
return BrowserType[this.getBrowser()].toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
isFirefox(): boolean {
|
|
||||||
return this.getBrowser() === BrowserType.Firefox;
|
|
||||||
}
|
|
||||||
|
|
||||||
isChrome(): boolean {
|
|
||||||
return this.getBrowser() === BrowserType.Chrome;
|
|
||||||
}
|
|
||||||
|
|
||||||
isEdge(): boolean {
|
|
||||||
return this.getBrowser() === BrowserType.Edge;
|
|
||||||
}
|
|
||||||
|
|
||||||
isOpera(): boolean {
|
|
||||||
return this.getBrowser() === BrowserType.Opera;
|
|
||||||
}
|
|
||||||
|
|
||||||
isVivaldi(): boolean {
|
|
||||||
return this.getBrowser() === BrowserType.Vivaldi;
|
|
||||||
}
|
|
||||||
|
|
||||||
isSafari(): boolean {
|
|
||||||
return this.getBrowser() === BrowserType.Safari;
|
|
||||||
}
|
|
||||||
|
|
||||||
analyticsId(): string {
|
|
||||||
if (this.analyticsIdCache) {
|
|
||||||
return this.analyticsIdCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.analyticsIdCache = AnalyticsIds[this.getBrowser()];
|
|
||||||
return this.analyticsIdCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
initListSectionItemListeners(doc: Document, angular: any): void {
|
|
||||||
if (!doc) {
|
|
||||||
throw new Error('doc parameter required');
|
|
||||||
}
|
|
||||||
|
|
||||||
const sectionItems = doc.querySelectorAll(
|
|
||||||
'.list-section-item:not([data-bw-events="1"])');
|
|
||||||
const sectionFormItems = doc.querySelectorAll(
|
|
||||||
'.list-section-item:not([data-bw-events="1"]) input, ' +
|
|
||||||
'.list-section-item:not([data-bw-events="1"]) select, ' +
|
|
||||||
'.list-section-item:not([data-bw-events="1"]) textarea');
|
|
||||||
|
|
||||||
sectionItems.forEach((item) => {
|
|
||||||
(item as HTMLElement).dataset.bwEvents = '1';
|
|
||||||
|
|
||||||
item.addEventListener('click', (e) => {
|
|
||||||
if (e.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const el = e.target as HTMLElement;
|
|
||||||
|
|
||||||
// Some elements will already focus properly
|
|
||||||
if (el.tagName != null) {
|
|
||||||
switch (el.tagName.toLowerCase()) {
|
|
||||||
case 'label': case 'input': case 'textarea': case 'select':
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cell = el.closest('.list-section-item');
|
|
||||||
if (!cell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const textFilter = 'input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"])';
|
|
||||||
const text = cell.querySelectorAll(textFilter + ', textarea');
|
|
||||||
const checkbox = cell.querySelectorAll('input[type="checkbox"]');
|
|
||||||
const select = cell.querySelectorAll('select');
|
|
||||||
|
|
||||||
if (text.length > 0) {
|
|
||||||
(text[0] as HTMLElement).focus();
|
|
||||||
} else if (select.length > 0) {
|
|
||||||
(select[0] as HTMLElement).focus();
|
|
||||||
} else if (checkbox.length > 0) {
|
|
||||||
const cb = checkbox[0] as HTMLInputElement;
|
|
||||||
cb.checked = !cb.checked;
|
|
||||||
if (angular) {
|
|
||||||
angular.element(checkbox[0]).triggerHandler('click');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
sectionFormItems.forEach((item) => {
|
|
||||||
const itemCell = item.closest('.list-section-item');
|
|
||||||
(itemCell as HTMLElement).dataset.bwEvents = '1';
|
|
||||||
|
|
||||||
item.addEventListener('focus', (e: Event) => {
|
|
||||||
const el = e.target as HTMLElement;
|
|
||||||
const cell = el.closest('.list-section-item');
|
|
||||||
if (!cell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell.classList.add('active');
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
item.addEventListener('blur', (e: Event) => {
|
|
||||||
const el = e.target as HTMLElement;
|
|
||||||
const cell = el.closest('.list-section-item');
|
|
||||||
if (!cell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell.classList.remove('active');
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getDomain(uriString: string): string {
|
|
||||||
return UtilsService.getDomain(uriString);
|
|
||||||
}
|
|
||||||
|
|
||||||
getHostname(uriString: string): string {
|
getHostname(uriString: string): string {
|
||||||
return UtilsService.getHostname(uriString);
|
return UtilsService.getHostname(uriString);
|
||||||
}
|
}
|
||||||
@ -347,21 +152,4 @@ export default class UtilsService implements UtilsServiceInterface {
|
|||||||
copyToClipboard(text: string, doc?: Document) {
|
copyToClipboard(text: string, doc?: Document) {
|
||||||
UtilsService.copyToClipboard(text, doc);
|
UtilsService.copyToClipboard(text, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
inSidebar(theWindow: Window): boolean {
|
|
||||||
return theWindow.location.search !== '' && theWindow.location.search.indexOf('uilocation=sidebar') > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inTab(theWindow: Window): boolean {
|
|
||||||
return theWindow.location.search !== '' && theWindow.location.search.indexOf('uilocation=tab') > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inPopout(theWindow: Window): boolean {
|
|
||||||
return theWindow.location.search !== '' && theWindow.location.search.indexOf('uilocation=popout') > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inPopup(theWindow: Window): boolean {
|
|
||||||
return theWindow.location.search === '' || theWindow.location.search.indexOf('uilocation=') === -1 ||
|
|
||||||
theWindow.location.search.indexOf('uilocation=popup') > -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user