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": {
"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": {
"message": "Enter your master password to export your vault data."
},
@ -1410,5 +1413,8 @@
},
"nativeMessagingInvalidEncryptionTitle": {
"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

@ -243,7 +243,7 @@ export default class MainBackground {
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService,
this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService,
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.vaultTimeoutService, this.runtimeBackground, this.i18nService, this.userService, this.messagingService);
this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService,
@ -290,7 +290,7 @@ export default class MainBackground {
}
async setIcon() {
if ((!chrome.browserAction && !this.sidebarAction)) {
if (!chrome.browserAction && !this.sidebarAction) {
return;
}

View File

@ -11,8 +11,10 @@ import { ConstantsService } from 'jslib/services/constants.service';
import { EnvironmentService } from 'jslib/abstractions/environment.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { NotificationsService } from 'jslib/abstractions/notifications.service';
import { PolicyService } from 'jslib/abstractions/policy.service';
import { StorageService } from 'jslib/abstractions/storage.service';
import { SystemService } from 'jslib/abstractions/system.service';
import { UserService } from 'jslib/abstractions/user.service';
import { VaultTimeoutService } from 'jslib/abstractions/vaultTimeout.service';
import { BrowserApi } from '../browser/browserApi';
@ -22,6 +24,9 @@ import MainBackground from './main.background';
import { Analytics } from 'jslib/misc';
import { Utils } from 'jslib/misc/utils';
import { OrganizationUserStatusType } from 'jslib/enums/organizationUserStatusType';
import { PolicyType } from 'jslib/enums/policyType';
export default class RuntimeBackground {
private runtime: any;
private autofillTimeout: any;
@ -33,7 +38,8 @@ export default class RuntimeBackground {
private storageService: StorageService, private i18nService: I18nService,
private analytics: Analytics, private notificationsService: NotificationsService,
private systemService: SystemService, private vaultTimeoutService: VaultTimeoutService,
private environmentService: EnvironmentService) {
private environmentService: EnvironmentService, private policyService: PolicyService,
private userService: UserService) {
this.runtime = chrome.runtime;
// 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) {
return;
}
if (!(await this.allowPersonalOwnership())) {
return;
}
// remove any old messages for this tab
this.removeTabFromNotificationQueue(tab);
this.main.notificationQueue.push({
@ -413,8 +424,9 @@ export default class RuntimeBackground {
const responseData: any = {};
if (responseCommand === 'notificationBarDataResponse') {
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);
responseData.disabledAddLoginNotification = disableAddLoginFromOptions || !(await this.allowPersonalOwnership());
responseData.disabledChangedPasswordNotification = await this.storageService.get<boolean>(
ConstantsService.disableChangedPasswordNotificationKey);
} else if (responseCommand === 'autofillerAutofillOnPageLoadEnabledResponse') {
@ -436,4 +448,20 @@ export default class RuntimeBackground {
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,
});
}
}, false)
}, false);

View File

@ -1,6 +1,6 @@
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 { EnvironmentService } from 'jslib/abstractions/environment.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 { PopupUtilsService } from '../services/popup-utils.service';
import { BrowserApi } from '../../browser/browserApi';
const BroadcasterSubscriptionId = 'TwoFactorComponent';
@ -37,7 +38,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
constructor(authService: AuthService, router: Router,
i18nService: I18nService, apiService: ApiService,
platformUtilsService: PlatformUtilsService, syncService: SyncService,
platformUtilsService: PlatformUtilsService, private syncService: SyncService,
environmentService: EnvironmentService, private ngZone: NgZone,
private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef,
private popupUtilsService: PopupUtilsService, stateService: StateService,
@ -80,6 +81,20 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
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() {

View File

@ -21,6 +21,7 @@
<select id="format" name="Format" [(ngModel)]="format">
<option value="json">.json</option>
<option value="csv">.csv</option>
<option value="encrypted_json">.json (Encrypted)</option>
</select>
</div>
<div class="box-content-row box-content-row-flex" appBoxRow>
@ -40,7 +41,13 @@
</div>
<div class="box-footer">
<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>
</content>

View File

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

View File

@ -15,6 +15,7 @@ import { FolderService } from 'jslib/abstractions/folder.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { PolicyService } from 'jslib/abstractions/policy.service';
import { StateService } from 'jslib/abstractions/state.service';
import { UserService } from 'jslib/abstractions/user.service';
@ -36,9 +37,9 @@ export class AddEditComponent extends BaseAddEditComponent {
userService: UserService, collectionService: CollectionService,
messagingService: MessagingService, private route: ActivatedRoute,
private router: Router, private location: Location,
eventService: EventService) {
eventService: EventService, policyService: PolicyService) {
super(cipherService, folderService, i18nService, platformUtilsService, auditService, stateService,
userService, collectionService, messagingService, eventService);
userService, collectionService, messagingService, eventService, policyService);
}
async ngOnInit() {
@ -161,4 +162,9 @@ export class AddEditComponent extends BaseAddEditComponent {
const u = (uri as any);
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',
// German
'vorname'
]
];
const LastnameFieldNames: string[] = [
// English
'l-name', 'last-name', 's-name', 'surname', 'family-name', 'family-n', 'last-n',
// German
'nachname', 'familienname'
]
];
const ExcludedAutofillTypes: string[] = ['radio', 'checkbox', 'hidden', 'file', 'button', 'image', 'reset', 'search'];

View File

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