From 7a0ab602af4b5d0b04b06d11844dd0c6c99d7df3 Mon Sep 17 00:00:00 2001 From: Cabia Rangris Date: Thu, 8 May 2025 12:36:20 +0400 Subject: [PATCH] password name templates --- src/background.js | 1 + src/manifest-firefox.json | 1 + src/options/interface.js | 8 ++++++++ src/popup/addEditInterface.js | 27 +++++++++++++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/src/background.js b/src/background.js index 53b285c8..2cb76eee 100644 --- a/src/background.js +++ b/src/background.js @@ -20,6 +20,7 @@ var defaultSettings = { theme: "auto", enableOTP: false, hideBadge: false, + nameTemplate: "%host%", caps: { save: false, delete: false, diff --git a/src/manifest-firefox.json b/src/manifest-firefox.json index 0336d74f..67965588 100644 --- a/src/manifest-firefox.json +++ b/src/manifest-firefox.json @@ -29,6 +29,7 @@ "tabs", "clipboardRead", "clipboardWrite", + "contextualIdentities", "nativeMessaging", "notifications", "scripting", diff --git a/src/options/interface.js b/src/options/interface.js index 41c696f8..f5417a9c 100644 --- a/src/options/interface.js +++ b/src/options/interface.js @@ -59,9 +59,17 @@ function view(ctl, params) { createCheckbox.call(this, "enableOTP", "Enable support for OTP tokens (not recommended)") ); nodes.push(createCheckbox.call(this, "hideBadge", "Hide badge counter on the toolbar icon")); + nodes.push(createInput.call(this, "username", "Default username", "john.smith")); nodes.push(createInput.call(this, "gpgPath", "Custom gpg binary", "/path/to/gpg")); + nodes.push( + createInput.call(this, "nameTemplate", "Template for new credentials", "%container%/%host%") + ); + nodes.push( + m("p", "%host%: tab's hostname; %container%: container name (for Firefox, username otherwise)") + ); + nodes.push(m("h3", "Theme")); nodes.push( createDropdown.call(this, "theme", [ diff --git a/src/popup/addEditInterface.js b/src/popup/addEditInterface.js index dca5d188..e52ad685 100644 --- a/src/popup/addEditInterface.js +++ b/src/popup/addEditInterface.js @@ -284,6 +284,33 @@ function AddEditInterface(settingsModel) { } else { // view instance should be a Login loginObj = new Login(settings); + const template = + helpers.getSetting("nameTemplate", loginObj, settings) || "%host%"; + const tab = await chrome.tabs + .query({ + lastFocusedWindow: true, + active: true, + }) + .then((it) => it[0]); + + const host = new URL(tab.url).host; + const defaultUser = helpers.getSetting("username", loginObj, settings); + + const containerName = + (await browser?.contextualIdentities + ?.query({}) + ?.then( + (a) => + a.find((a) => a.cookieStoreId === tab.cookieStoreId)?.name || + defaultUser + )) || defaultUser; + + // Apply to a template + rendered = template + .replaceAll("%container%", containerName) + .replaceAll("%host%", host); + + loginObj.login = rendered; } // set the storePath and get tree dirs