From 4d49f6778fd6102ef7369d81202965664540e6d8 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:19:43 -0700 Subject: [PATCH 01/13] Mobile Updates --- manifest.json | 2 +- src/css/options.css | 7 ++++++- src/css/popup.css | 10 +++++++--- src/html/options.html | 14 +++++++------- src/html/popup.html | 20 ++++++++------------ src/js/auth.js | 1 - src/js/options.js | 25 +++++++++++++++++++------ src/js/popup.js | 12 ++++++------ src/js/service-worker.js | 5 ++++- src/js/theme.js | 8 ++++++++ 10 files changed, 66 insertions(+), 38 deletions(-) diff --git a/manifest.json b/manifest.json index 94f8927..60b1bbe 100644 --- a/manifest.json +++ b/manifest.json @@ -29,7 +29,7 @@ "suggested_key": { "default": "Alt+Shift+A" }, - "description": "Show Main Popup Action" + "description": "Show Popup Action" }, "openOptions": { "suggested_key": { diff --git a/src/css/options.css b/src/css/options.css index 11183ca..14f3675 100644 --- a/src/css/options.css +++ b/src/css/options.css @@ -1,6 +1,11 @@ /* CSS for options.html */ +body { + min-width: 340px; + width: 100%; + max-width: 100vw; +} + .card { - min-width: 300px; max-width: 900px; } diff --git a/src/css/popup.css b/src/css/popup.css index 1565ee7..5e45d19 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -1,11 +1,15 @@ /* CSS for popup.html */ body { - min-width: 340px; + min-width: 330px; width: 100%; + max-width: 100vw; overflow-x: hidden; } -input::placeholder { - text-align: center; +#hostname { + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } diff --git a/src/html/options.html b/src/html/options.html index b4fd7d5..3349456 100644 --- a/src/html/options.html +++ b/src/html/options.html @@ -16,14 +16,14 @@
-
- Auto Auth -

Auto Auth

+
+ Cache Cleaner +
+ Cache Cleaner + v +
-
-

v

- +
diff --git a/src/html/popup.html b/src/html/popup.html index 86d57fe..6310a2d 100644 --- a/src/html/popup.html +++ b/src/html/popup.html @@ -14,7 +14,6 @@
-
-
+
- -
+
No Access to the Current Tab.
- Delete Saved Credentials - - - - -
-
+
+
- + + Open Options +
+
Auto Auth (el.textContent = url.host)) document.title = `Login for ${url.host}` document.getElementById('favicon').href = `${url.origin}/favicon.ico` diff --git a/src/js/options.js b/src/js/options.js index 8766065..a429246 100644 --- a/src/js/options.js +++ b/src/js/options.js @@ -96,8 +96,8 @@ async function initOptions() { console.debug('initOptions') updateManifest() - await setShortcuts() - await checkPerms() + setShortcuts('#keyboard-shortcuts', true).then() + checkPerms().then() // const { options, sites } = await chrome.storage.sync.get([ // 'options', @@ -107,6 +107,7 @@ async function initOptions() { const { options } = await chrome.storage.sync.get(['options']) updateOptions(options) backgroundChange(options.radioBackground) + const hosts = await Hosts.all() // console.debug('hosts:', hosts) updateTable(hosts) @@ -430,28 +431,40 @@ async function onChanged(changes, namespace) { /** * Set Keyboard Shortcuts * @function setShortcuts - * @param {String} selector + * @param {String} [selector] + * @param {Boolean} [action] */ -async function setShortcuts(selector = '#keyboard-shortcuts') { +async function setShortcuts(selector = '#keyboard-shortcuts', action = false) { if (!chrome.commands) { return console.debug('Skipping: chrome.commands') } const table = document.querySelector(selector) + table.classList.remove('d-none') const tbody = table.querySelector('tbody') const source = table.querySelector('tfoot > tr').cloneNode(true) const commands = await chrome.commands.getAll() for (const command of commands) { // console.debug('command:', command) const row = source.cloneNode(true) - // TODO: Chrome does not parse the description for _execute_action in manifest.json let description = command.description + // Note: Chrome does not parse the description for _execute_action in manifest.json if (!description && command.name === '_execute_action') { - description = 'Show Popup' + description = 'Show Popup Action' } row.querySelector('.description').textContent = description row.querySelector('kbd').textContent = command.shortcut || 'Not Set' tbody.appendChild(row) } + if (action) { + const userSettings = await chrome.action.getUserSettings() + const row = source.cloneNode(true) + row.querySelector('i').className = 'fa-solid fa-puzzle-piece me-1' + row.querySelector('.description').textContent = 'Toolbar Icon Pinned' + row.querySelector('kbd').textContent = userSettings.isOnToolbar + ? 'Yes' + : 'No' + tbody.appendChild(row) + } } /** diff --git a/src/js/popup.js b/src/js/popup.js index 23bebcd..e7ad849 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -32,7 +32,7 @@ const confirmDeleteHost = document.getElementById('delete-host') const deleteModal = new bootstrap.Modal('#delete-modal') confirmDelete.addEventListener('click', deleteHost) -const hostDiv = document.getElementById('host') +const hostnameEl = document.getElementById('hostname') const deleteSaved = document.getElementById('delete-saved') /** @@ -68,20 +68,20 @@ async function initPopup() { const url = new URL(tab.url) const creds = await Hosts.get(url.host) if (creds) { - hostDiv.classList.add('border-success') - hostDiv.textContent = url.host + hostnameEl.classList.add('border-success') + hostnameEl.textContent = url.host deleteSaved.classList.remove('d-none') deleteSaved.dataset.value = url.host deleteSaved.addEventListener('click', deleteHost) confirmDelete.dataset.value = url.host confirmDeleteHost.textContent = url.host } else { - hostDiv.textContent = 'No Credentials Found for Tab.' - hostDiv.classList.remove('border-success') + hostnameEl.textContent = 'No Credentials Found for Tab.' + hostnameEl.classList.remove('border-success') deleteSaved.classList.add('d-none') } } else { - hostDiv.classList.add('border-danger-subtle') + hostnameEl.classList.add('border-danger-subtle') } } diff --git a/src/js/service-worker.js b/src/js/service-worker.js index 1de9996..efbf95f 100644 --- a/src/js/service-worker.js +++ b/src/js/service-worker.js @@ -285,7 +285,7 @@ async function onChanged(changes, namespace) { createContextMenus() } else { console.info('Disabled contextMenu...') - chrome.contextMenus.removeAll() + chrome.contextMenus?.removeAll() } } if (oldValue.tempDisabled !== newValue.tempDisabled) { @@ -369,6 +369,9 @@ async function updateIcon(options) { * @function createContextMenus */ function createContextMenus() { + if (!chrome.contextMenus) { + return console.debug('Skipping: chrome.contextMenus') + } console.debug('createContextMenus') chrome.contextMenus.removeAll() /** @type {Array[String[], String, String, String]} */ diff --git a/src/js/theme.js b/src/js/theme.js index 8d61db4..ff5976d 100644 --- a/src/js/theme.js +++ b/src/js/theme.js @@ -55,6 +55,14 @@ }) } + window.addEventListener('storage', (event) => { + // console.log('storage:', event) + if (event.key === 'theme') { + setTheme(event.newValue) + showActiveTheme(event.newValue) + } + }) + window .matchMedia('(prefers-color-scheme: dark)') .addEventListener('change', () => { From cbff7581e025fe5936f43d752d3f5fca0a921c52 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 21 Aug 2024 01:40:53 -0700 Subject: [PATCH 02/13] Add Theme Switcher --- README.md | 4 ++-- src/css/auth.css | 7 +++++++ src/html/auth.html | 8 ++++---- src/html/popup.html | 44 ++++++++++++++++++++++++++++++++++++-------- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 2666231..5654906 100644 --- a/README.md +++ b/README.md @@ -126,13 +126,13 @@ If there is enough popularity/requests for these features, there are a couple op ## Support -For help using the web extension, utilize any these resources: +For help using the web extension, see: - Documentation: https://auto-auth.cssnr.com/docs/ - Q&A Discussion: https://github.com/cssnr/auto-auth/discussions/categories/q-a - Request a Feature: https://github.com/cssnr/auto-auth/discussions/categories/feature-requests -If you are experiencing an issue/bug or getting unexpected results, use: +If you are experiencing an issue/bug or getting unexpected results, you can: - Report an Issue: https://github.com/cssnr/auto-auth/issues - Chat with us on Discord: https://discord.gg/wXy6m2X8wY diff --git a/src/css/auth.css b/src/css/auth.css index 47fa3c0..cb5be35 100644 --- a/src/css/auth.css +++ b/src/css/auth.css @@ -15,6 +15,13 @@ video { backdrop-filter: blur(6px); } +kbd.host { + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + [data-bs-theme='dark'] #auth-outer { background-color: rgba(var(--bs-black-rgb), 0.5); border: 1px solid rgba(var(--bs-white-rgb), 0.2); diff --git a/src/html/auth.html b/src/html/auth.html index ee3a821..14a6c3f 100644 --- a/src/html/auth.html +++ b/src/html/auth.html @@ -18,9 +18,9 @@
-

- -

+
+ +

url @@ -97,7 +97,7 @@ Open Options Get Support + href="https://github.com/cssnr/auto-auth?tab=readme-ov-file#support">Get Support

diff --git a/src/html/popup.html b/src/html/popup.html index 6310a2d..5f6d6bb 100644 --- a/src/html/popup.html +++ b/src/html/popup.html @@ -14,6 +14,35 @@
+
+
+ Cache Cleaner +
+ +
+ Auto Auth + + + v + +
+ + +
+ +
+
-
+
@@ -100,13 +129,12 @@ Open Options -
- -
- Auto Auth - Auto Auth v -
+ + + + + +
-
+
-
+
No Access to the Current Tab.
@@ -63,7 +63,7 @@ Delete Saved Credentials
-
+
diff --git a/src/js/export.js b/src/js/export.js index 74dd2f8..33e3463 100644 --- a/src/js/export.js +++ b/src/js/export.js @@ -1,5 +1,7 @@ // JS Exports +export const githubURL = 'https://github.com/cssnr/auto-auth' + export class Hosts { /** @type {[String]} */ static keys = [...'abcdefghijklmnopqrstuvwxyz0123456789'] @@ -324,12 +326,15 @@ export async function activateOrOpen(url, open = true) { */ export function updateManifest() { const manifest = chrome.runtime.getManifest() - document - .querySelectorAll('.version') - .forEach((el) => (el.textContent = manifest.version)) - document - .querySelectorAll('[href="homepage_url"]') - .forEach((el) => (el.href = manifest.homepage_url)) + document.querySelectorAll('.version').forEach((el) => { + el.textContent = manifest.version + }) + document.querySelectorAll('[href="version_url"]').forEach((el) => { + el.href = `${githubURL}/releases/tag/${manifest.version}` + }) + document.querySelectorAll('[href="homepage_url"]').forEach((el) => { + el.href = manifest.homepage_url + }) } /** diff --git a/src/js/service-worker.js b/src/js/service-worker.js index efbf95f..657696a 100644 --- a/src/js/service-worker.js +++ b/src/js/service-worker.js @@ -1,6 +1,6 @@ // JS Background Service Worker -import { Hosts, checkPerms, showPanel } from './export.js' +import { Hosts, checkPerms, showPanel, githubURL } from './export.js' chrome.runtime.onStartup.addListener(onStartup) chrome.runtime.onInstalled.addListener(onInstalled) @@ -162,7 +162,6 @@ async function onStartup() { */ async function onInstalled(details) { console.log('onInstalled:', details) - const githubURL = 'https://github.com/cssnr/auto-auth' // const uninstallURL = new URL('https://link-extractor.cssnr.com/uninstall/') const options = await setDefaultOptions({ tempDisabled: false, From 34dc8109053309b4b0abe686d62aef6e5e09f3b9 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:11:49 -0700 Subject: [PATCH 04/13] Update Test --- src/html/auth.html | 43 ++++++++++++++++++------------------ src/html/permissions.html | 2 +- src/js/export.js | 24 +++++++++++--------- src/js/options.js | 46 ++++++++++++++++++++++++--------------- tests/test.js | 3 +++ 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/src/html/auth.html b/src/html/auth.html index 14a6c3f..5840c5c 100644 --- a/src/html/auth.html +++ b/src/html/auth.html @@ -13,7 +13,7 @@ - +
@@ -21,12 +21,12 @@
-

+

url

- -
+
diff --git a/src/js/export.js b/src/js/export.js index 33e3463..ab7955e 100644 --- a/src/js/export.js +++ b/src/js/export.js @@ -325,16 +325,20 @@ export async function activateOrOpen(url, open = true) { * @function updateManifest */ export function updateManifest() { - const manifest = chrome.runtime.getManifest() - document.querySelectorAll('.version').forEach((el) => { - el.textContent = manifest.version - }) - document.querySelectorAll('[href="version_url"]').forEach((el) => { - el.href = `${githubURL}/releases/tag/${manifest.version}` - }) - document.querySelectorAll('[href="homepage_url"]').forEach((el) => { - el.href = manifest.homepage_url - }) + try { + const manifest = chrome.runtime.getManifest() + document.querySelectorAll('.version').forEach((el) => { + el.textContent = manifest.version + }) + document.querySelectorAll('[href="version_url"]').forEach((el) => { + el.href = `${githubURL}/releases/tag/${manifest.version}` + }) + document.querySelectorAll('[href="homepage_url"]').forEach((el) => { + el.href = manifest.homepage_url + }) + } catch (e) { + console.log('Error updating manifest settings:', e) + } } /** diff --git a/src/js/options.js b/src/js/options.js index a429246..ed264ba 100644 --- a/src/js/options.js +++ b/src/js/options.js @@ -439,31 +439,43 @@ async function setShortcuts(selector = '#keyboard-shortcuts', action = false) { return console.debug('Skipping: chrome.commands') } const table = document.querySelector(selector) + if (!table) { + return console.warn(`${selector} table not found`) + } table.classList.remove('d-none') const tbody = table.querySelector('tbody') const source = table.querySelector('tfoot > tr').cloneNode(true) const commands = await chrome.commands.getAll() for (const command of commands) { - // console.debug('command:', command) - const row = source.cloneNode(true) - let description = command.description - // Note: Chrome does not parse the description for _execute_action in manifest.json - if (!description && command.name === '_execute_action') { - description = 'Show Popup Action' + try { + // console.debug('command:', command) + const row = source.cloneNode(true) + let description = command.description + // Note: Chrome does not parse the description for _execute_action in manifest.json + if (!description && command.name === '_execute_action') { + description = 'Show Popup Action' + } + row.querySelector('.description').textContent = description + row.querySelector('kbd').textContent = command.shortcut || 'Not Set' + tbody.appendChild(row) + } catch (e) { + console.warn('Error adding command:', command, e) } - row.querySelector('.description').textContent = description - row.querySelector('kbd').textContent = command.shortcut || 'Not Set' - tbody.appendChild(row) } if (action) { - const userSettings = await chrome.action.getUserSettings() - const row = source.cloneNode(true) - row.querySelector('i').className = 'fa-solid fa-puzzle-piece me-1' - row.querySelector('.description').textContent = 'Toolbar Icon Pinned' - row.querySelector('kbd').textContent = userSettings.isOnToolbar - ? 'Yes' - : 'No' - tbody.appendChild(row) + try { + const userSettings = await chrome.action.getUserSettings() + const row = source.cloneNode(true) + row.querySelector('i').className = 'fa-solid fa-puzzle-piece me-1' + row.querySelector('.description').textContent = + 'Toolbar Icon Pinned' + row.querySelector('kbd').textContent = userSettings.isOnToolbar + ? 'Yes' + : 'No' + tbody.appendChild(row) + } catch (e) { + console.log('Error adding pinned setting:', e) + } } } diff --git a/tests/test.js b/tests/test.js index 78c7047..7c7d3e2 100644 --- a/tests/test.js +++ b/tests/test.js @@ -91,6 +91,9 @@ async function getPage(browser, name, size) { const popup = await getPage(browser, 'popup.html') console.log('popup:', popup) await popup.waitForNetworkIdle() + console.log('innerWidth:', await popup.evaluate('window.innerWidth')) + console.log('innerHeight:', await popup.evaluate('window.innerHeight')) + console.log('userAgent:', await popup.evaluate('navigator.userAgent')) await popup.screenshot(ssOptions('popup')) await popup.locator('[href="../html/options.html"]').click() From 7b991cea626179404ef3b8b5be01d45e91b7fb04 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:56:53 -0700 Subject: [PATCH 05/13] Add Fix for Firefox Bug --- README.md | 3 ++- src/js/service-worker.js | 7 +++++-- tests/test.js | 8 +++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5654906..1f6fd0d 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,8 @@ Long-term Goals for Improved Security: ### Known Issues * Only allows saving 1 set of credentials per host -* Most browsers will offer to save passwords on login and edit +* Most browsers will offer to save passwords on login and edit +* Firefox: May cache a 401 and not prompt for auth, use `Ctrl+F5` or clear cache > [!TIP] > **Don't see your issue here?** diff --git a/src/js/service-worker.js b/src/js/service-worker.js index 657696a..cede90f 100644 --- a/src/js/service-worker.js +++ b/src/js/service-worker.js @@ -45,10 +45,13 @@ async function onAuthRequired(details, callback) { // console.debug('url.host:', url.host) const hijackRequest = (failed = false) => { - const color = failed ? 'Yellow' : 'Lime' + if (details.tabId === -1) { + console.warn(`Unable to process tab:`, details) + return callback() + } console.log( `Cancel Request and Hijack w/ failed: %c${failed}`, - `color: ${color}` + `color: ${failed ? 'Yellow' : 'Lime'}` ) const auth = new URL(chrome.runtime.getURL('/html/auth.html')) auth.searchParams.append('url', details.url) diff --git a/tests/test.js b/tests/test.js index 7c7d3e2..674df4e 100644 --- a/tests/test.js +++ b/tests/test.js @@ -88,7 +88,7 @@ async function getPage(browser, name, size) { // Popup await worker.evaluate('chrome.action.openPopup();') - const popup = await getPage(browser, 'popup.html') + let popup = await getPage(browser, 'popup.html') console.log('popup:', popup) await popup.waitForNetworkIdle() console.log('innerWidth:', await popup.evaluate('window.innerWidth')) @@ -156,6 +156,12 @@ async function getPage(browser, name, size) { await page.waitForNetworkIdle() await page.screenshot(ssOptions('success')) + await worker.evaluate('chrome.action.openPopup();') + popup = await getPage(browser, 'popup.html') + console.log('popup:', popup) + await popup.waitForNetworkIdle() + await popup.screenshot(ssOptions('popup')) + try { // Intercepting auth throws: Error: net::ERR_ABORTED await page.goto('https://httpbin.org/basic-auth/guest/guest') From 52d02efa919eb8d1aab10b7ececd255823409472 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:58:18 -0700 Subject: [PATCH 06/13] Add Error Handling to Delete/Edit/Import --- src/js/options.js | 148 ++++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 56 deletions(-) diff --git a/src/js/options.js b/src/js/options.js index ed264ba..44920ca 100644 --- a/src/js/options.js +++ b/src/js/options.js @@ -228,20 +228,24 @@ function updateTable(data) { */ async function deleteHost(event) { console.debug('deleteHost:', event) - const host = event.currentTarget?.dataset?.value - console.debug('host:', host) - const confirm = event.currentTarget?.id !== 'confirm-delete' - const { options } = await chrome.storage.sync.get(['options']) - if (options.confirmDelete && !!confirm) { - console.debug('Show Delete Modal') - confirmDelete.dataset.value = host - confirmDeleteHost.textContent = host - deleteModal.show() - return + try { + const host = event.currentTarget?.dataset?.value + console.debug('host:', host) + const confirm = event.currentTarget?.id !== 'confirm-delete' + const { options } = await chrome.storage.sync.get(['options']) + if (options.confirmDelete && !!confirm) { + console.debug('Show Delete Modal') + confirmDelete.dataset.value = host + confirmDeleteHost.textContent = host + deleteModal.show() + return + } + await Hosts.delete(host) + deleteModal.hide() + showToast(`Removed: ${host}`) + } catch (e) { + showToast(`Delete Error: ${e.message}`, 'danger') } - await Hosts.delete(host) - deleteModal.hide() - showToast(`Removed: ${host}`) } /** @@ -276,31 +280,53 @@ async function editSubmit(event) { console.debug('editSubmit:', event) event.preventDefault() event.stopPropagation() - const hostname = editHostname.value.toLowerCase() - const username = editUsername.value - const password = editPassword.value - // console.debug('hostname ,username, password:', hostname, username, password) - if ( - hostname === editHostname.dataset.original && - username === editUsername.dataset.original && - password === editPassword.dataset.original - ) { + try { + const hostname = getHost(editHostname.value) + const username = editUsername.value + const password = editPassword.value + // console.debug('hostname ,username, password:', hostname, username, password) + if ( + hostname === editHostname.dataset.original && + username === editUsername.dataset.original && + password === editPassword.dataset.original + ) { + editModal.hide() + return showToast('No Changes Detected', 'warning') + } + // const { sites } = await chrome.storage.sync.get(['sites']) + // if (hostname !== editHostname.dataset.original) { + // delete sites[editHostname.dataset.original] + // } + // sites[hostname] = `${username}:${password}` + // await chrome.storage.sync.set({ sites }) + await Hosts.edit( + editHostname.dataset.original, + hostname, + `${username}:${password}` + ) editModal.hide() - return showToast('No Changes Detected', 'warning') + showToast(`Updated Host: ${hostname}`, 'success') + } catch (e) { + showToast(`Error saving credentials: ${e.message}`, 'danger') } - // const { sites } = await chrome.storage.sync.get(['sites']) - // if (hostname !== editHostname.dataset.original) { - // delete sites[editHostname.dataset.original] - // } - // sites[hostname] = `${username}:${password}` - // await chrome.storage.sync.set({ sites }) - await Hosts.edit( - editHostname.dataset.original, - hostname, - `${username}:${password}` - ) - editModal.hide() - showToast(`Updated Host: ${hostname}`, 'success') +} + +/** + * @function getHost + * @param host + * @return {String} + */ +function getHost(host) { + host = host.toLowerCase().trim() + try { + const url = new URL(host) + return url.host + } catch (e) {} // eslint-disable-line no-empty + try { + const url = new URL('https://' + host) + return url.host + } catch (e) {} // eslint-disable-line no-empty + throw new Error('Unable to validate hostname') } /** @@ -352,29 +378,39 @@ async function exportHosts(event) { async function hostsInputChange(event) { console.debug('hostsInputChange:', event, hostsInput) event.preventDefault() - const fileReader = new FileReader() - fileReader.onload = async function doBannedImport() { - const results = JSON.parse(fileReader.result.toString()) - // console.debug('results:', results) - // const { sites } = await chrome.storage.sync.get(['sites']) - const hosts = {} - let count = 0 - for (const [key, value] of Object.entries(results)) { - count += 1 - if (typeof value === 'object') { - const { username, password } = value - hosts[key] = `${username}:${password}` - } else if (typeof value === 'string') { - // const [username, password] = value.split(':') - hosts[key] = value + try { + const fileReader = new FileReader() + fileReader.onload = async function doBannedImport() { + const results = JSON.parse(fileReader.result.toString()) + // console.debug('results:', results) + // const { sites } = await chrome.storage.sync.get(['sites']) + const hosts = {} + let count = 0 + for (const [key, value] of Object.entries(results)) { + try { + if (typeof value === 'object') { + const { username, password } = value + hosts[key] = `${username}:${password}` + } else if (typeof value === 'string') { + // const [username, password] = value.split(':') + hosts[key] = value + } + count += 1 + } catch (e) { + console.log(`Error processing: ${key}`, 'color: Red') + } } + // console.debug('hosts:', hosts) + // await chrome.storage.sync.set({ sites }) + await Hosts.update(hosts) + const total = Object.keys(results).length + showToast(`Imported/Updated ${count}/${total} Hosts.`, 'success') } - // console.debug('hosts:', hosts) - // await chrome.storage.sync.set({ sites }) - await Hosts.update(hosts) - showToast(`Imported/Updated ${count} Hosts.`, 'success') + fileReader.readAsText(hostsInput.files[0]) + } catch (e) { + console.log('Import error:', e) + showToast(`Import Error: ${e.message}`, 'warning') } - fileReader.readAsText(hostsInput.files[0]) } /** From acef65c122a7de010ca0a7d9f301a67996b98623 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:07:45 -0700 Subject: [PATCH 07/13] Update Info Span for Mobile --- src/html/options.html | 36 ++++++++++++++++++------------------ src/html/popup.html | 36 ++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/html/options.html b/src/html/options.html index 3349456..1901f02 100644 --- a/src/html/options.html +++ b/src/html/options.html @@ -59,10 +59,10 @@ data-warning="text-danger-emphasis" data-related="disableWarning"> + + +
+ + +
+ + +
+ + +
+ + +
diff --git a/src/html/popup.html b/src/html/popup.html index 53fdfa5..51eeb94 100644 --- a/src/html/popup.html +++ b/src/html/popup.html @@ -71,10 +71,10 @@ data-warning="text-danger-emphasis" data-related="disableWarning"> + + +
+ + +
+ + +
+ + +
+ + +
From 0da0b2f59bed6b9611a31d2b40ab5b67c4832589 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:22:02 -0700 Subject: [PATCH 08/13] Update ClipboardJS --- src/html/auth.html | 12 +++++------- src/js/main.js | 4 +++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/html/auth.html b/src/html/auth.html index 5840c5c..43425ed 100644 --- a/src/html/auth.html +++ b/src/html/auth.html @@ -18,15 +18,13 @@
-
- -
-

- +

+
+ url -

+
-
Keyboard Shortcuts
DescriptionShortcut