From e42360a1b2aa3d25ebc142c2a2ec81efa7683b77 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 7 Dec 2020 13:01:12 -0500 Subject: [PATCH 1/3] add support for encrypted json export (#1483) --- jslib | 2 +- src/_locales/en/messages.json | 3 +++ src/popup/settings/export.component.html | 9 ++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/jslib b/jslib index abb54f0073..dcbd09e736 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit abb54f007305eabd77996623dd20cbe45345e82a +Subproject commit dcbd09e736b516b359369f9d9fe5b0f5a6c2a928 diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 65c3ed7464..bd3b9730f2 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -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." }, diff --git a/src/popup/settings/export.component.html b/src/popup/settings/export.component.html index c04ff10cad..f4a90062c9 100644 --- a/src/popup/settings/export.component.html +++ b/src/popup/settings/export.component.html @@ -21,6 +21,7 @@
@@ -40,7 +41,13 @@
From a1542f050dfbacfcd3a0460faf9dbebc29f5d622 Mon Sep 17 00:00:00 2001 From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Date: Wed, 9 Dec 2020 14:11:25 -0600 Subject: [PATCH 2/3] [Policy] Personal Ownership (#1481) * Initial commit for personal ownership * Removed TODO // Updated allowPersonalOwnership logic to include necessary org/user checks * Fixed import order * Updated jslib (dcbd09e -> 72bf18f) * Fixed casing for error message --- jslib | 2 +- src/_locales/en/messages.json | 3 +++ src/background/main.background.ts | 6 ++--- src/background/runtime.background.ts | 32 +++++++++++++++++++++++-- src/popup/vault/add-edit.component.html | 2 +- src/popup/vault/add-edit.component.ts | 10 ++++++-- 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/jslib b/jslib index dcbd09e736..72bf18f369 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit dcbd09e736b516b359369f9d9fe5b0f5a6c2a928 +Subproject commit 72bf18f369068d36767794bdc0ca377f734cf373 diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index bd3b9730f2..946dba4b98 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1413,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." } } diff --git a/src/background/main.background.ts b/src/background/main.background.ts index 6de29fa43a..c3e235015c 100644 --- a/src/background/main.background.ts +++ b/src/background/main.background.ts @@ -155,9 +155,9 @@ export default class MainBackground { async () => { if (this.nativeMessagingBackground != null) { const promise = this.nativeMessagingBackground.getResponse(); - + try { - await this.nativeMessagingBackground.send({command: 'biometricUnlock'}); + await this.nativeMessagingBackground.send({ command: 'biometricUnlock' }); } catch (e) { return Promise.reject(e); } @@ -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, diff --git a/src/background/runtime.background.ts b/src/background/runtime.background.ts index 685b4a5dff..c7ef83e954 100644 --- a/src/background/runtime.background.ts +++ b/src/background/runtime.background.ts @@ -12,11 +12,13 @@ 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 { PopupUtilsService } from '../popup/services/popup-utils.service'; import { StateService } from 'jslib/abstractions/state.service'; import { StorageService } from 'jslib/abstractions/storage.service'; import { SyncService } from 'jslib/abstractions/sync.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'; @@ -27,6 +29,9 @@ import { NativeMessagingBackground } from './nativeMessaging.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; @@ -39,7 +44,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.isSafari = this.platformUtilsService.isSafari(); this.runtime = this.isSafari ? {} : chrome.runtime; @@ -318,6 +324,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({ @@ -436,8 +447,9 @@ export default class RuntimeBackground { const responseData: any = {}; if (responseCommand === 'notificationBarDataResponse') { responseData.neverDomains = await this.storageService.get(ConstantsService.neverDomainsKey); - responseData.disabledAddLoginNotification = await this.storageService.get( + const disableAddLoginFromOptions = await this.storageService.get( ConstantsService.disableAddLoginNotificationKey); + responseData.disabledAddLoginNotification = disableAddLoginFromOptions || !(await this.allowPersonalOwnership()); responseData.disabledChangedPasswordNotification = await this.storageService.get( ConstantsService.disableChangedPasswordNotificationKey); } else if (responseCommand === 'autofillerAutofillOnPageLoadEnabledResponse') { @@ -459,4 +471,20 @@ export default class RuntimeBackground { await BrowserApi.tabSendMessageData(tab, responseCommand, responseData); } + + private async allowPersonalOwnership(): Promise { + 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; + } } diff --git a/src/popup/vault/add-edit.component.html b/src/popup/vault/add-edit.component.html index 7a4c6c1cd0..65f344e29b 100644 --- a/src/popup/vault/add-edit.component.html +++ b/src/popup/vault/add-edit.component.html @@ -340,7 +340,7 @@ -
+
{{'ownership' | i18n}}
diff --git a/src/popup/vault/add-edit.component.ts b/src/popup/vault/add-edit.component.ts index 5a9872a4fd..fdecd141d8 100644 --- a/src/popup/vault/add-edit.component.ts +++ b/src/popup/vault/add-edit.component.ts @@ -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); + } } From c95230fc48c70dd835b408e45a5739f380435d5d Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Wed, 9 Dec 2020 15:30:03 -0600 Subject: [PATCH 3/3] Close 2fa window if redirected from sso login (#1480) * Close 2fa window if redirected from sso login This is a workaround until we can get browser extension sso to use the toolbar popup. other changes are linter autofixs Co-authored-by: Matt Gibson --- src/content/sso.ts | 2 +- src/popup/accounts/home.component.ts | 2 +- src/popup/accounts/two-factor.component.ts | 17 ++++++++++++++++- src/services/autofill.service.ts | 4 ++-- tslint.json | 6 +++++- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/content/sso.ts b/src/content/sso.ts index 326758b90a..508bc2aea3 100644 --- a/src/content/sso.ts +++ b/src/content/sso.ts @@ -10,4 +10,4 @@ window.addEventListener('message', (event) => { referrer: event.source.location.hostname, }); } -}, false) +}, false); diff --git a/src/popup/accounts/home.component.ts b/src/popup/accounts/home.component.ts index 838f5b6d69..04b4938249 100644 --- a/src/popup/accounts/home.component.ts +++ b/src/popup/accounts/home.component.ts @@ -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'; diff --git a/src/popup/accounts/two-factor.component.ts b/src/popup/accounts/two-factor.component.ts index 194d6c137d..a84ed5070a 100644 --- a/src/popup/accounts/two-factor.component.ts +++ b/src/popup/accounts/two-factor.component.ts @@ -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() { diff --git a/src/services/autofill.service.ts b/src/services/autofill.service.ts index 9a67f33fab..7498248bbe 100644 --- a/src/services/autofill.service.ts +++ b/src/services/autofill.service.ts @@ -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']; diff --git a/tslint.json b/tslint.json index 7e4320f723..cb3f6b016f 100644 --- a/tslint.json +++ b/tslint.json @@ -49,6 +49,10 @@ "check-separator", "check-type" ], - "max-classes-per-file": false + "max-classes-per-file": false, + "semicolon": [ + true, + "always" + ] } }