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; } } +