From cd2f174923a763c4dbb73cd36a190bfdd6bc02b0 Mon Sep 17 00:00:00 2001 From: Dmitry Chepurovskiy Date: Fri, 3 Sep 2021 04:54:52 +0300 Subject: [PATCH] Select folder at save bar (#1409) * Markup changes * Render in notification bar folders list that is provided form TS code * Implemented getting of folders list * Refactor addPlatformEventListener and added default selection of "No Folder" * Pass folder id info to saveAddLogin * Modify saveAddLogin to use folder id * Try to fix default folder selection * Fix styling issues found during review * Fix review issues found by kspearrin * Fix default selection and null handling * Fix import order * Applied review suggestions * Implement checking if folderExist during saving * Fix compile issues * Added select folder... option * Add internalization for select folder message * Hide select folder element on narrow screens * Fix lint issues * Review fixes in notification bar * Adjust semi-responsive layout for folder selector * Revert style change Co-authored-by: Thomas Rittson --- src/_locales/en/messages.json | 3 +++ src/background/main.background.ts | 2 +- src/background/runtime.background.ts | 17 ++++++++++++++--- src/notification/bar.html | 5 ++++- src/notification/bar.js | 26 ++++++++++++++++++++++++-- src/notification/bar.scss | 3 ++- 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 3c52e967be..7dfa637610 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1764,5 +1764,8 @@ }, "updateMasterPasswordWarning": { "message": "Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + }, + "selectFolder": { + "message": "Select folder..." } } diff --git a/src/background/main.background.ts b/src/background/main.background.ts index 37a86412ee..f987591ca7 100644 --- a/src/background/main.background.ts +++ b/src/background/main.background.ts @@ -244,7 +244,7 @@ export default class MainBackground { this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService, this.platformUtilsService as BrowserPlatformUtilsService, this.storageService, this.i18nService, this.notificationsService, this.systemService, this.vaultTimeoutService, - this.environmentService, this.policyService, this.userService, this.messagingService); + this.environmentService, this.policyService, this.userService, this.messagingService, this.folderService); this.nativeMessagingBackground = new NativeMessagingBackground(this.storageService, this.cryptoService, this.cryptoFunctionService, this.vaultTimeoutService, this.runtimeBackground, this.i18nService, this.userService, this.messagingService, this.appIdService, this.platformUtilsService); diff --git a/src/background/runtime.background.ts b/src/background/runtime.background.ts index a55026c757..583cc29f77 100644 --- a/src/background/runtime.background.ts +++ b/src/background/runtime.background.ts @@ -6,6 +6,7 @@ import { LoginView } from 'jslib-common/models/view/loginView'; import { CipherService } from 'jslib-common/abstractions/cipher.service'; import { EnvironmentService } from 'jslib-common/abstractions/environment.service'; +import { FolderService } from 'jslib-common/abstractions/folder.service'; import { I18nService } from 'jslib-common/abstractions/i18n.service'; import { MessagingService } from 'jslib-common/abstractions/messaging.service'; import { NotificationsService } from 'jslib-common/abstractions/notifications.service'; @@ -39,7 +40,8 @@ export default class RuntimeBackground { private notificationsService: NotificationsService, private systemService: SystemService, private vaultTimeoutService: VaultTimeoutService, private environmentService: EnvironmentService, private policyService: PolicyService, - private userService: UserService, private messagingService: MessagingService) { + private userService: UserService, private messagingService: MessagingService, + private folderService: FolderService) { // onInstalled listener must be wired up before anything else, so we do it in the ctor chrome.runtime.onInstalled.addListener((details: any) => { @@ -107,7 +109,7 @@ export default class RuntimeBackground { this.removeTabFromNotificationQueue(sender.tab); break; case 'bgAddSave': - await this.saveAddLogin(sender.tab); + await this.saveAddLogin(sender.tab, msg.folder); break; case 'bgChangeSave': await this.saveChangePassword(sender.tab); @@ -218,7 +220,7 @@ export default class RuntimeBackground { this.pageDetailsToAutoFill = []; } - private async saveAddLogin(tab: any) { + private async saveAddLogin(tab: any, folderId: string) { if (await this.vaultTimeoutService.isLocked()) { return; } @@ -249,6 +251,13 @@ export default class RuntimeBackground { model.type = CipherType.Login; model.login = loginModel; + if (!Utils.isNullOrWhitespace(folderId)) { + const folders = await this.folderService.getAllDecrypted(); + if (folders.some(x => x.id === folderId)) { + model.folderId = folderId; + } + } + const cipher = await this.cipherService.encrypt(model); await this.cipherService.saveWithServer(cipher); } @@ -452,6 +461,8 @@ export default class RuntimeBackground { notificationChangeSave: this.i18nService.t('notificationChangeSave'), notificationChangeDesc: this.i18nService.t('notificationChangeDesc'), }; + } else if (responseCommand === 'notificationBarGetFoldersList') { + responseData.folders = await this.folderService.getAllDecrypted(); } await BrowserApi.tabSendMessageData(tab, responseCommand, responseData); diff --git a/src/notification/bar.html b/src/notification/bar.html index 065ca944bb..0403ad1b82 100644 --- a/src/notification/bar.html +++ b/src/notification/bar.html @@ -27,8 +27,11 @@ - + + + + diff --git a/src/notification/bar.js b/src/notification/bar.js index a5e55ca664..7bcd2b2eef 100644 --- a/src/notification/bar.js +++ b/src/notification/bar.js @@ -17,7 +17,6 @@ document.addEventListener('DOMContentLoaded', () => { // delay 50ms so that we get proper body dimensions setTimeout(load, 50); - function load() { var closeButton = document.getElementById('close-button'), @@ -34,10 +33,12 @@ document.addEventListener('DOMContentLoaded', () => { if (bodyRect.width < 768) { document.querySelector('#template-add .add-save').textContent = i18n.yes; document.querySelector('#template-add .never-save').textContent = i18n.never; + document.querySelector('#template-add .select-folder').style.display = 'none'; document.querySelector('#template-change .change-save').textContent = i18n.yes; } else { document.querySelector('#template-add .add-save').textContent = i18n.notificationAddSave; document.querySelector('#template-add .never-save').textContent = i18n.notificationNeverSave; + document.querySelector('#template-add .select-folder').style.display = 'initial'; document.querySelector('#template-change .change-save').textContent = i18n.notificationChangeSave; } @@ -53,7 +54,8 @@ document.addEventListener('DOMContentLoaded', () => { addButton.addEventListener('click', (e) => { e.preventDefault(); sendPlatformMessage({ - command: 'bgAddSave' + command: 'bgAddSave', + folder: document.getElementById("select-folder").value, }); }); @@ -63,6 +65,17 @@ document.addEventListener('DOMContentLoaded', () => { command: 'bgNeverSave' }); }); + + const responseFoldersCommand = 'notificationBarGetFoldersList'; + chrome.runtime.onMessage.addListener((msg) => { + if (msg.command === responseFoldersCommand && msg.data) { + fillSelectorWithFolders(msg.data.folders); + } + }); + sendPlatformMessage({ + command: 'bgGetDataForTab', + responseCommand: responseFoldersCommand + }); } else if (getQueryVariable('change')) { setContent(document.getElementById('template-change')); var changeButton = document.querySelector('#template-change-clone .change-save'); @@ -120,4 +133,13 @@ document.addEventListener('DOMContentLoaded', () => { function sendPlatformMessage(msg) { chrome.runtime.sendMessage(msg); } + + function fillSelectorWithFolders(folders) { + const select = document.querySelector('#template-add-clone .select-folder'); + select.appendChild(new Option(chrome.i18n.getMessage('selectFolder'), null, true)); + folders.forEach((folder) => { + //Select "No Folder" (id=null) folder by default + select.appendChild(new Option(folder.name, folder.id || '', false)); + }); + } }); diff --git a/src/notification/bar.scss b/src/notification/bar.scss index 1f673d5255..2705ed324b 100644 --- a/src/notification/bar.scss +++ b/src/notification/bar.scss @@ -82,7 +82,7 @@ button.link { } body[class*='lang-en'] .add-buttons { - width: 175px; + width: 50px; } @media (min-width: 768px) { @@ -96,3 +96,4 @@ body[class*='lang-en'] .add-buttons { display: none; } } +