Merge branch 'master' of https://github.com/bitwarden/browser into feature/safari-webext

# Conflicts:
#	src/background/runtime.background.ts
This commit is contained in:
Hinton 2020-12-11 14:33:46 +01:00
commit 25a2af903a
12 changed files with 82 additions and 16 deletions

2
jslib

@ -1 +1 @@
Subproject commit abb54f007305eabd77996623dd20cbe45345e82a Subproject commit 72bf18f369068d36767794bdc0ca377f734cf373

View File

@ -609,6 +609,9 @@
"exportWarningDesc": { "exportWarningDesc": {
"message": "This export contains your vault data in an unencrypted format. You should not store or send the exported file over unsecure channels (such as email). Delete it immediately after you are done using it." "message": "This export contains your vault data in an unencrypted format. You should not store or send the exported file over unsecure channels (such as email). Delete it immediately after you are done using it."
}, },
"encExportWarningDesc": {
"message": "This export encrypts your data using your account's encryption key. If you ever rotate your account's encryption key you should export again since you will not be able to decrypt this export file."
},
"exportMasterPassword": { "exportMasterPassword": {
"message": "Enter your master password to export your vault data." "message": "Enter your master password to export your vault data."
}, },
@ -1410,5 +1413,8 @@
}, },
"nativeMessagingInvalidEncryptionTitle": { "nativeMessagingInvalidEncryptionTitle": {
"message": "Desktop communication interupted" "message": "Desktop communication interupted"
},
"personalOwnershipSubmitError": {
"message": "Due to an Enterprise Policy, you are restricted from saving items to your personal vault. Change the Ownership option to an organization and choose from available Collections."
} }
} }

View File

@ -157,7 +157,7 @@ export default class MainBackground {
const promise = this.nativeMessagingBackground.getResponse(); const promise = this.nativeMessagingBackground.getResponse();
try { try {
await this.nativeMessagingBackground.send({command: 'biometricUnlock'}); await this.nativeMessagingBackground.send({ command: 'biometricUnlock' });
} catch (e) { } catch (e) {
return Promise.reject(e); return Promise.reject(e);
} }
@ -243,7 +243,7 @@ export default class MainBackground {
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService, this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService,
this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService, this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService,
this.analytics, this.notificationsService, this.systemService, this.vaultTimeoutService, this.analytics, this.notificationsService, this.systemService, this.vaultTimeoutService,
this.environmentService); this.environmentService, this.policyService, this.userService);
this.nativeMessagingBackground = new NativeMessagingBackground(this.storageService, this.cryptoService, this.cryptoFunctionService, this.nativeMessagingBackground = new NativeMessagingBackground(this.storageService, this.cryptoService, this.cryptoFunctionService,
this.vaultTimeoutService, this.runtimeBackground, this.i18nService, this.userService, this.messagingService); this.vaultTimeoutService, this.runtimeBackground, this.i18nService, this.userService, this.messagingService);
this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService, this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService,
@ -290,7 +290,7 @@ export default class MainBackground {
} }
async setIcon() { async setIcon() {
if ((!chrome.browserAction && !this.sidebarAction)) { if (!chrome.browserAction && !this.sidebarAction) {
return; return;
} }

View File

@ -11,8 +11,10 @@ import { ConstantsService } from 'jslib/services/constants.service';
import { EnvironmentService } from 'jslib/abstractions/environment.service'; import { EnvironmentService } from 'jslib/abstractions/environment.service';
import { I18nService } from 'jslib/abstractions/i18n.service'; import { I18nService } from 'jslib/abstractions/i18n.service';
import { NotificationsService } from 'jslib/abstractions/notifications.service'; import { NotificationsService } from 'jslib/abstractions/notifications.service';
import { PolicyService } from 'jslib/abstractions/policy.service';
import { StorageService } from 'jslib/abstractions/storage.service'; import { StorageService } from 'jslib/abstractions/storage.service';
import { SystemService } from 'jslib/abstractions/system.service'; import { SystemService } from 'jslib/abstractions/system.service';
import { UserService } from 'jslib/abstractions/user.service';
import { VaultTimeoutService } from 'jslib/abstractions/vaultTimeout.service'; import { VaultTimeoutService } from 'jslib/abstractions/vaultTimeout.service';
import { BrowserApi } from '../browser/browserApi'; import { BrowserApi } from '../browser/browserApi';
@ -22,6 +24,9 @@ import MainBackground from './main.background';
import { Analytics } from 'jslib/misc'; import { Analytics } from 'jslib/misc';
import { Utils } from 'jslib/misc/utils'; import { Utils } from 'jslib/misc/utils';
import { OrganizationUserStatusType } from 'jslib/enums/organizationUserStatusType';
import { PolicyType } from 'jslib/enums/policyType';
export default class RuntimeBackground { export default class RuntimeBackground {
private runtime: any; private runtime: any;
private autofillTimeout: any; private autofillTimeout: any;
@ -33,7 +38,8 @@ export default class RuntimeBackground {
private storageService: StorageService, private i18nService: I18nService, private storageService: StorageService, private i18nService: I18nService,
private analytics: Analytics, private notificationsService: NotificationsService, private analytics: Analytics, private notificationsService: NotificationsService,
private systemService: SystemService, private vaultTimeoutService: VaultTimeoutService, private systemService: SystemService, private vaultTimeoutService: VaultTimeoutService,
private environmentService: EnvironmentService) { private environmentService: EnvironmentService, private policyService: PolicyService,
private userService: UserService) {
this.runtime = chrome.runtime; this.runtime = chrome.runtime;
// onInstalled listener must be wired up before anything else, so we do it in the ctor // onInstalled listener must be wired up before anything else, so we do it in the ctor
@ -309,6 +315,11 @@ export default class RuntimeBackground {
if (disabledAddLogin) { if (disabledAddLogin) {
return; return;
} }
if (!(await this.allowPersonalOwnership())) {
return;
}
// remove any old messages for this tab // remove any old messages for this tab
this.removeTabFromNotificationQueue(tab); this.removeTabFromNotificationQueue(tab);
this.main.notificationQueue.push({ this.main.notificationQueue.push({
@ -413,8 +424,9 @@ export default class RuntimeBackground {
const responseData: any = {}; const responseData: any = {};
if (responseCommand === 'notificationBarDataResponse') { if (responseCommand === 'notificationBarDataResponse') {
responseData.neverDomains = await this.storageService.get<any>(ConstantsService.neverDomainsKey); responseData.neverDomains = await this.storageService.get<any>(ConstantsService.neverDomainsKey);
responseData.disabledAddLoginNotification = await this.storageService.get<boolean>( const disableAddLoginFromOptions = await this.storageService.get<boolean>(
ConstantsService.disableAddLoginNotificationKey); ConstantsService.disableAddLoginNotificationKey);
responseData.disabledAddLoginNotification = disableAddLoginFromOptions || !(await this.allowPersonalOwnership());
responseData.disabledChangedPasswordNotification = await this.storageService.get<boolean>( responseData.disabledChangedPasswordNotification = await this.storageService.get<boolean>(
ConstantsService.disableChangedPasswordNotificationKey); ConstantsService.disableChangedPasswordNotificationKey);
} else if (responseCommand === 'autofillerAutofillOnPageLoadEnabledResponse') { } else if (responseCommand === 'autofillerAutofillOnPageLoadEnabledResponse') {
@ -436,4 +448,20 @@ export default class RuntimeBackground {
await BrowserApi.tabSendMessageData(tab, responseCommand, responseData); await BrowserApi.tabSendMessageData(tab, responseCommand, responseData);
} }
private async allowPersonalOwnership(): Promise<boolean> {
const personalOwnershipPolicies = await this.policyService.getAll(PolicyType.PersonalOwnership);
if (personalOwnershipPolicies != null) {
for (const policy of personalOwnershipPolicies) {
if (policy.enabled) {
const org = await this.userService.getOrganization(policy.organizationId);
if (org != null && org.enabled && org.usePolicies && !org.isAdmin
&& org.status == OrganizationUserStatusType.Confirmed) {
return false;
}
}
}
}
return true;
}
} }

View File

@ -10,4 +10,4 @@ window.addEventListener('message', (event) => {
referrer: event.source.location.hostname, referrer: event.source.location.hostname,
}); });
} }
}, false) }, false);

View File

@ -1,6 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ConstantsService } from 'jslib/services/constants.service' import { ConstantsService } from 'jslib/services/constants.service';
import { CryptoFunctionService } from 'jslib/abstractions/cryptoFunction.service'; import { CryptoFunctionService } from 'jslib/abstractions/cryptoFunction.service';
import { EnvironmentService } from 'jslib/abstractions/environment.service'; import { EnvironmentService } from 'jslib/abstractions/environment.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service'; import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';

View File

@ -25,6 +25,7 @@ import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { TwoFactorComponent as BaseTwoFactorComponent } from 'jslib/angular/components/two-factor.component'; import { TwoFactorComponent as BaseTwoFactorComponent } from 'jslib/angular/components/two-factor.component';
import { PopupUtilsService } from '../services/popup-utils.service'; import { PopupUtilsService } from '../services/popup-utils.service';
import { BrowserApi } from '../../browser/browserApi';
const BroadcasterSubscriptionId = 'TwoFactorComponent'; const BroadcasterSubscriptionId = 'TwoFactorComponent';
@ -37,7 +38,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
constructor(authService: AuthService, router: Router, constructor(authService: AuthService, router: Router,
i18nService: I18nService, apiService: ApiService, i18nService: I18nService, apiService: ApiService,
platformUtilsService: PlatformUtilsService, syncService: SyncService, platformUtilsService: PlatformUtilsService, private syncService: SyncService,
environmentService: EnvironmentService, private ngZone: NgZone, environmentService: EnvironmentService, private ngZone: NgZone,
private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef, private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef,
private popupUtilsService: PopupUtilsService, stateService: StateService, private popupUtilsService: PopupUtilsService, stateService: StateService,
@ -80,6 +81,20 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
this.popupUtilsService.popOut(window); this.popupUtilsService.popOut(window);
} }
} }
const queryParamsSub = this.route.queryParams.subscribe(async (qParams) => {
if (qParams.sso === 'true') {
super.onSuccessfulLogin = () => {
BrowserApi.reloadOpenWindows();
const thisWindow = window.open('', '_self');
thisWindow.close();
return this.syncService.fullSync(true);
};
if (queryParamsSub != null) {
queryParamsSub.unsubscribe();
}
}
});
} }
ngOnDestroy() { ngOnDestroy() {

View File

@ -21,6 +21,7 @@
<select id="format" name="Format" [(ngModel)]="format"> <select id="format" name="Format" [(ngModel)]="format">
<option value="json">.json</option> <option value="json">.json</option>
<option value="csv">.csv</option> <option value="csv">.csv</option>
<option value="encrypted_json">.json (Encrypted)</option>
</select> </select>
</div> </div>
<div class="box-content-row box-content-row-flex" appBoxRow> <div class="box-content-row box-content-row-flex" appBoxRow>
@ -40,7 +41,13 @@
</div> </div>
<div class="box-footer"> <div class="box-footer">
<p>{{'exportMasterPassword' | i18n}}</p> <p>{{'exportMasterPassword' | i18n}}</p>
<strong>{{'warning' | i18n}}</strong>: {{'exportWarningDesc' | i18n}} <strong>{{'warning' | i18n}}</strong>:
<span *ngIf="!encryptedFormat">
{{'exportWarningDesc' | i18n}}
</span>
<span *ngIf="encryptedFormat">
{{'encExportWarningDesc' | i18n}}
</span>
</div> </div>
</div> </div>
</content> </content>

View File

@ -340,7 +340,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="box" *ngIf="(!editMode || cloneMode) && ownershipOptions && ownershipOptions.length > 1"> <div class="box" *ngIf="allowOwnershipOptions()">
<div class="box-header"> <div class="box-header">
{{'ownership' | i18n}} {{'ownership' | i18n}}
</div> </div>

View File

@ -15,6 +15,7 @@ import { FolderService } from 'jslib/abstractions/folder.service';
import { I18nService } from 'jslib/abstractions/i18n.service'; import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service'; import { MessagingService } from 'jslib/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service'; import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { PolicyService } from 'jslib/abstractions/policy.service';
import { StateService } from 'jslib/abstractions/state.service'; import { StateService } from 'jslib/abstractions/state.service';
import { UserService } from 'jslib/abstractions/user.service'; import { UserService } from 'jslib/abstractions/user.service';
@ -36,9 +37,9 @@ export class AddEditComponent extends BaseAddEditComponent {
userService: UserService, collectionService: CollectionService, userService: UserService, collectionService: CollectionService,
messagingService: MessagingService, private route: ActivatedRoute, messagingService: MessagingService, private route: ActivatedRoute,
private router: Router, private location: Location, private router: Router, private location: Location,
eventService: EventService) { eventService: EventService, policyService: PolicyService) {
super(cipherService, folderService, i18nService, platformUtilsService, auditService, stateService, super(cipherService, folderService, i18nService, platformUtilsService, auditService, stateService,
userService, collectionService, messagingService, eventService); userService, collectionService, messagingService, eventService, policyService);
} }
async ngOnInit() { async ngOnInit() {
@ -161,4 +162,9 @@ export class AddEditComponent extends BaseAddEditComponent {
const u = (uri as any); const u = (uri as any);
u.showCurrentUris = !u.showCurrentUris; u.showCurrentUris = !u.showCurrentUris;
} }
allowOwnershipOptions(): boolean {
return (!this.editMode || this.cloneMode) && this.ownershipOptions
&& (this.ownershipOptions.length > 1 || !this.allowPersonal);
}
} }

View File

@ -42,14 +42,14 @@ const FirstnameFieldNames: string[] = [
'f-name', 'first-name', 'given-name', 'first-n', 'f-name', 'first-name', 'given-name', 'first-n',
// German // German
'vorname' 'vorname'
] ];
const LastnameFieldNames: string[] = [ const LastnameFieldNames: string[] = [
// English // English
'l-name', 'last-name', 's-name', 'surname', 'family-name', 'family-n', 'last-n', 'l-name', 'last-name', 's-name', 'surname', 'family-name', 'family-n', 'last-n',
// German // German
'nachname', 'familienname' 'nachname', 'familienname'
] ];
const ExcludedAutofillTypes: string[] = ['radio', 'checkbox', 'hidden', 'file', 'button', 'image', 'reset', 'search']; const ExcludedAutofillTypes: string[] = ['radio', 'checkbox', 'hidden', 'file', 'button', 'image', 'reset', 'search'];

View File

@ -49,6 +49,10 @@
"check-separator", "check-separator",
"check-type" "check-type"
], ],
"max-classes-per-file": false "max-classes-per-file": false,
"semicolon": [
true,
"always"
]
} }
} }