Commit Graph
241 Commits
Author SHA1 Message Date
Claude deacfd5907 Bump version to 0.9.42
https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-02 00:39:49 +00:00
Claude e93e27012e Fix fresh-install pull blocked by saveSettings timestamp
After a browser restart with no extension data, enabling encryption calls
saveSettings() which writes ss_lastModified = Date.now(). All pull paths
then compare that fresh timestamp against the remote's older timestamp,
see local >= remote, and skip the pull with "already on latest version" —
even though local is completely empty.

Fix: add _hasRealLocalData() which returns true only if local storage
contains actual identity profiles or mappings with real values. The
timestamp skip condition now requires BOTH a newer local timestamp AND
real local data. An empty/fresh install always falls through to pull.

Affects pullFromGist, pullFromUrl, pullFromSyncStorage, and importSyncCode.

https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-01 23:45:10 +00:00
Claude dbf178937f Bump version to 0.9.41
https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-01 20:04:51 +00:00
Claude 1b224fb233 Add Ignore button to auto-detect warnings for permanent per-value dismissal
The × close button only hid the warning for the current send — the same
detection reappeared on every subsequent send with no way to silence it.

Added an Ignore button to each item in both the on-send warning
(showAutoDetectWarning) and the pre-send input scanner warning
(showPreSendWarning). Clicking Ignore:
- Adds the specific value to an in-memory Set (ignoredDetections)
- Persists it to ss_ignored_detections in storage
- Removes that item from the current warning; closes the popup if empty

On page load, ss_ignored_detections is read from storage so ignores
survive page reloads. Ignored values are also filtered before
auto-redaction in the fetch interceptor, so they are not redacted either.

https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-01 18:25:13 +00:00
Claude ed8d094320 Bump version to 0.9.40
https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-01 16:08:30 +00:00
Claude ed92b07703 Add grok.com; fix fetch hook on React/Next.js sites (Reddit, Grok, etc.)
Two fixes:

1. grok.com missing from manifest
   Grok moved from grok.x.ai to grok.com. The extension wasn't activating
   on grok.com at all (no content script injected). Added to host_permissions
   and content_scripts in both manifests.

2. Fetch hook bypassed on React/Next.js sites
   content.js was injected async (after awaiting the document-scanner),
   so by the time it replaced window.fetch, React/Next.js had already stored
   a reference to the original. All fetch calls from framework code bypassed
   the hook entirely.

   Fix: load early-hook.js as a "world": "MAIN" content script at
   document_start. This runs synchronously before any page JavaScript,
   captures the real fetch in window.__ssOriginalFetch, and replaces
   window.fetch with a lightweight wrapper. When content.js eventually
   loads, it sets window.__ssInterceptFetch (the real substitution logic)
   and window.__ssReady = true, activating the wrapper. React's stored
   fetch reference now routes through the interceptor.

   Falls back to direct window.fetch replacement if early-hook.js somehow
   didn't run (e.g. older browser without world: MAIN support).

https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-01 16:07:01 +00:00
Claude 9af92a24aa Bump version to 0.9.39
https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-01 14:56:40 +00:00
Claude 1c4b8b0cdd Fix race condition: vault:unlocked message lost when service worker responds before content.js loads
Two related races caused substitution to silently fail with at-rest encryption:

1. vault:request-unlock was sent at the top of init(), but the runtime.onMessage
   listener that handles the vault:unlocked response was registered only after
   await-ing the document-scanner script. A warm service worker (e.g. freshly
   woken by a sync operation) could respond before the listener existed, dropping
   the message permanently.

2. Even if the listener was registered in time, it posted to window immediately,
   but content.js hadn't been injected yet, so its window.addEventListener('message')
   handler wasn't live and the message went nowhere.

Fix: register api.runtime.onMessage before injecting content.js, and move the
vault:request-unlock send into script.onload — by that point content.js has fully
executed and its message listener is live.

Also stop passing the encrypted settings blob as initial config. When isLocked,
ss_settings is { _ssLocalEncrypted: true, data: '...' }; passing it to content.js
as the initial settings object clutters the settings with encrypted garbage.
Now falls back to { enabled: true } like mappings/identity already did.

https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo
2026-04-01 14:48:19 +00:00
Outis 1f869f2ff0 Merge pull request #66 from outis1one/claude/read-repo-yLNcT
Claude/read repo y l nc t
2026-04-01 00:57:04 -04:00
Claude b3dc4f7abd Bump version to 0.9.34
https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-04-01 04:56:22 +00:00
Claude 7028f60b56 Fix fresh-install pull skipping due to empty-profile timestamp pollution
Root cause: when the popup opens for the first time it calls
addProfile('Personal') + updateProfile(...) to create a default empty
profile. Both call saveProfiles, which was unconditionally setting
ss_lastModified: Date.now(). This made the new browser's local
timestamp look like right now — newer than any Gist data pushed by
the source browser — so every pull returned "Already up to date"
without ever prompting for a password or importing anything.

Fixes:

1. storage.js saveProfiles: only advance ss_lastModified when at
   least one profile contains real PII (non-empty real value in
   names, emails, usernames, phones, or catchAllEmail). Creating the
   default empty profile structure on first install leaves
   ss_lastModified at 0 so pulls correctly see remote data as newer.

2. sync.js pushToGist: persist ss_last_push_time and
   ss_last_push_source alongside ss_gist_id so the source browser
   (which only pushes) can also show its last activity time.

3. options.js: display both "Pushed: <time>" and "Pulled: <time>"
   in the Gist status area on page load, giving both browsers
   meaningful feedback.

4. service-worker.js: after a successful auto-sync pull, broadcast
   vault:unlocked to all open content-script tabs so substitution
   works immediately without a page reload.

https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-04-01 04:53:12 +00:00
Claude 8b6f779a07 Prevent empty-browser auto-sync from clobbering Gist data
On a fresh browser install with auto-sync enabled, performAutoSync
would push because config.lastPush was null (!config.lastPush = true).
With _getAllData now returning lastModified: 0 for browsers with no
saved data, this pushed a payload with lastModified: 0 to the Gist,
overwriting the real data from the source browser. Subsequent pulls
then saw remoteMod (0) <= local (0) and returned "Already up to date"
without ever prompting for a password or importing anything.

Three fixes:

1. performAutoSync: add local.lastModified > 0 guard to the push
   condition so a browser with no saved data never pushes in the
   background (both Gist and URL paths).

2. pushToGist / pushToUrl: return an explicit error if lastModified
   is 0, preventing a manual Push click on a fresh browser from
   clobbering the Gist too.

3. pullFromGist: if the Gist's lastModified is 0 (already clobbered),
   return a clear error message telling the user to push from the
   source browser first, rather than silently returning "up to date".

https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-04-01 04:43:52 +00:00
Outis e46d08428e Merge pull request #65 from outis1one/claude/read-repo-yLNcT
Claude/read repo y l nc t
2026-04-01 00:31:16 -04:00
Claude 64f24f28f1 Bump version to 0.9.33
https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-04-01 04:30:39 +00:00
Claude 9f763ba0ec Fix substitution breaking after sync import with at-rest encryption
When at-rest encryption is enabled, injector.js detects encrypted blobs
in storage, passes empty config to the content script, and waits for a
vault:unlocked broadcast from the background. That broadcast was only
ever triggered when the user explicitly entered their password in the
popup. After a Gist/URL sync import (which writes newly-imported data
in encrypted form), no page ever received the decrypted config, so
substitution silently stopped working.

Two fixes:

1. injector.js: when isLocked is true (encrypted blobs detected), send
   vault:request-unlock to the background. If the key is already cached
   (e.g. the user authenticated during the sync pull), the background
   responds immediately with vault:unlocked containing the decrypted
   data. This fixes every new page load after a sync import.

2. service-worker.js: add vault:request-unlock handler that checks
   Storage.isLocked() and, if the key is available, reads decrypted
   mappings/identity/settings and sends vault:unlocked back to the
   requesting tab.

3. options.js: after a successful Gist or URL pull, send vault:unlocked
   to the background so it broadcasts decrypted data to all currently-
   open tabs immediately, without requiring a page reload.

https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-04-01 04:27:26 +00:00
Claude 0997f7a8e4 Fix pull silently skipping on fresh browser install; show last pull time
Three issues in the Gist pull flow on a browser with no prior data:

1. _getAllData() returned Date.now() as lastModified when ss_lastModified
   was unset (fresh install). The timestamp check in pullFromGist then
   saw the Gist data as older than local, silently returned imported:false
   ("Already up to date") without importing anything or prompting for
   auth. Fixed by using || 0 so a browser with no data always accepts
   remote data as newer.

2. _applyData now persists ss_last_pull_time and ss_last_pull_source so
   the last successful pull survives page reloads.

3. The Gist section on the options page now shows "Last pulled: <time>"
   alongside the Gist ID on load, so both browsers display their sync
   status rather than showing nothing on first open.

https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-04-01 04:11:43 +00:00
Outis 8a066cd357 Merge pull request #64 from outis1one/claude/read-repo-yLNcT
Claude/read repo y l nc t
2026-03-31 17:25:06 -04:00
Claude 6a962e927b Add .version-bump-undo to .gitignore
Local scratch file created by bump-version.sh; no need to track it.

https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-03-31 21:21:16 +00:00
Claude 8539c7ba9b Bump version to 0.9.32
https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-03-31 21:20:46 +00:00
Claude 3420299f51 Fix cross-browser GitHub Gist sync when encryption is enabled
Two bugs prevented sync from working between different browsers
sharing the same GitHub token and encryption password:

1. pullFromGist failed immediately with "No Gist ID stored" on any
   browser that had not previously pushed, because ss_gist_id lives
   in browser.storage.local (isolated per browser). Fix: when no
   local Gist ID is found, search the authenticated user's Gists for
   one containing silent-send-sync.json and cache the result.

2. When the pulled data was encrypted with a different salt (each
   browser generates its own random salt on setup), pullFromGist
   returned needsAuth:true but the UI never set
   window.__ssPendingSyncImport, so the auth prompt fell through to
   reverifyWithPassword instead of authenticateForSync, and the pull
   was never retried after the user entered their password. Fix: set
   window.__ssPendingSyncImport before showing the auth prompt for
   both Gist pull and custom-URL pull, matching how sync-code import
   already handled this flow.

https://claude.ai/code/session_01QJnEnLfbXKR5FSCQ3Qfs53
2026-03-31 20:55:12 +00:00
Outis 7a128b9f10 Merge pull request #63 from outis1one/claude/fix-extension-disable-RJffZ
Claude/fix extension disable r jff z
2026-03-30 18:49:55 -04:00
Claude bb5d9d3837 Bump version to 0.9.31
https://claude.ai/code/session_015TEttQgcq5FALLKLb3uEW8
2026-03-30 22:48:36 +00:00
Claude f021e50c08 Fix extension not fully disabling when toggled off
The fetch/XHR interception correctly checked settings.enabled, but
several other features ignored it — highlights, reveal mode, and
PII auto-detect all continued running after disabling. This adds
settings.enabled checks to the MutationObserver, highlightMatches,
auto-detect input/paste listeners, reveal mode, and cleans up
visual artifacts (highlights, warnings) when the extension is
toggled off.

https://claude.ai/code/session_015TEttQgcq5FALLKLb3uEW8
2026-03-30 22:26:58 +00:00
Outis d6707d9cf6 Bump version to 0.9.30 2026-03-30 11:55:20 -04:00
Claude 4968b4cde2 Bump version to 0.9.30 2026-03-30 15:54:48 +00:00
Outis bd9d28cd50 Bump version to 0.9.29 2026-03-30 10:25:08 -04:00
Claude 90b0a04a9c Bump version to 0.9.29 2026-03-30 14:24:33 +00:00
Outis 4021a496db Bump version to 0.9.28 2026-03-30 09:58:31 -04:00
Claude d35926083f Bump version to 0.9.28 2026-03-30 13:57:56 +00:00
Claude 74df048cef Bump version to 0.9.28 2026-03-30 13:56:49 +00:00
Outis cc5d3bf4fd Bump version to 0.9.27 2026-03-29 18:10:12 -04:00
Outis adabfdff57 Push storage.js and document-scanner.js fixes to main 2026-03-29 17:55:15 -04:00
Outis 8151056456 Fix PDF scanner, add proper noun toggle, fix footer version, bump to 0.9.26
- document-scanner.js: Add missing await on _inflateSync(), widen FlateDecode
  lookback to 500 bytes, support array form /Filter [/FlateDecode]
- content.js, storage.js: Gate proper noun detection behind detectProperNouns
  setting (default false) — was always-on causing noisy false positives
- options.html, options.js: Add toggle for proper noun detection, fix footer
  version to read dynamically from manifest (was hardcoded v0.3.0)
- Bump version 0.9.23 → 0.9.26
2026-03-29 17:48:48 -04:00
Outis 8c455bcc3b Merge pull request #62 from outis1one/claude/explore-silent-send-oth4L
Claude/explore silent send oth4 l
2026-03-29 17:38:40 -04:00
Claude 1390e3d245 Bump version to 0.9.26
https://claude.ai/code/session_01ReZUeR1nrYzJeX7fTqwXMw
2026-03-29 21:36:51 +00:00
Claude bcce37483e Fix footer version, improve PDF filter detection
- options.html/js: Footer version now reads dynamically from manifest via
  api.runtime.getManifest().version instead of hardcoded v0.3.0
- document-scanner.js: Increase FlateDecode lookback from 200 to 500 bytes
  (real PDF stream dictionaries are often larger than 200 bytes), and support
  array form /Filter [/FlateDecode] alongside the scalar form

https://claude.ai/code/session_01ReZUeR1nrYzJeX7fTqwXMw
2026-03-29 21:32:49 +00:00
Outis 486e1ff27d Merge pull request #61 from outis1one/claude/explore-silent-send-oth4L
Fix PDF decompression, add proper noun detection toggle, bump to 0.9.25
2026-03-29 17:10:50 -04:00
Claude 4b494b5eab Fix PDF decompression, add proper noun detection toggle, bump to 0.9.25
- document-scanner.js: Add missing await on _inflateSync() call — FlateDecode
  streams were not being decompressed because the async function was called
  without await, causing decompressed to hold a Promise instead of data
- content.js, storage.js, options.html, options.js: Gate proper noun / capital
  letter detection behind a new detectProperNouns setting (default off); was
  previously always-on causing noisy false-positive warnings on AI thinking
  output and common capitalized words
- Bump version 0.9.23 → 0.9.25

https://claude.ai/code/session_01ReZUeR1nrYzJeX7fTqwXMw
2026-03-29 21:09:49 +00:00
Outis 8a9736d6a3 Merge pull request #60 from outis1one/claude/audit-silent-send-5thF8
Claude/audit silent send 5th f8
2026-03-29 16:01:47 -04:00
Claude 490b2ebf33 Fix reveal mode not restoring substitute values on toggle off
The old unrevealInElement relied on a WeakMap (originalTexts) to restore
text nodes to their pre-reveal state. This broke when SPA frameworks
(React) re-rendered the DOM while reveal was active — new text nodes
containing real values had no WeakMap entry to restore from, so real
data stayed visible after turning reveal off.

Fix: unrevealInElement now actively reverse-replaces real values back
to their substitute counterparts using the reveal pairs, matching the
same approach revealText uses in the forward direction. This works
regardless of DOM re-renders or streaming content changes.

https://claude.ai/code/session_01NNBEPuXMFGWezJb1f958nL
2026-03-29 19:56:57 +00:00
Claude 4fa607d53f Wire up document scanner for file upload interception, bump to 0.9.23
- Inject document-scanner.js into page world via injector.js (as module,
  sets globalThis.DocumentScanner)
- Add FormData interception to fetch hook: scans File/Blob entries through
  DocumentScanner.processUpload(), also substitutes string fields
- Add document-scanner.js to web_accessible_resources in both manifests
- Bump version to 0.9.23 in package.json, manifest.json, manifest.firefox.json

https://claude.ai/code/session_01NNBEPuXMFGWezJb1f958nL
2026-03-29 19:49:04 +00:00
Outis a52693c586 Merge pull request #59 from outis1one/claude/audit-silent-send-5thF8
Fix PPI → PII terminology across entire codebase
2026-03-29 15:33:55 -04:00
Claude bc1492032d Fix PPI → PII terminology across entire codebase
All references to "PPI" (Personal Private Information) have been
corrected to the industry-standard "PII" (Personally Identifiable
Information). This includes UI labels, comments, CSS class comments,
and variable/function names (PPI_PATTERNS → PII_PATTERNS,
autoDetectPPI → autoDetectPII, scanInputForPPI → scanInputForPII,
ppiWarnings → piiWarnings).

Files changed: README.md, content.css, content.js, auto-detect.js,
org-policy.js, storage.js, options.html, popup.html, popup.js

https://claude.ai/code/session_01NNBEPuXMFGWezJb1f958nL
2026-03-29 19:32:02 +00:00
Outis a0202625ac Merge pull request #58 from outis1one/claude/read-repo-YMu21
revert: restore src/ from pre-doc-scanner baseline, bump 0.9.21
2026-03-29 14:45:33 -04:00
Claude 2719e1be44 revert: restore entire src/ from pre-doc-scanner commit (e4b44a7)
Going back to a known-good baseline. This version had:
- Working reveal mode with CSS Highlight API
- Working substitution (fetch + XHR hooks)
- Smart patterns (names, emails, phones, usernames)
- Encryption/sync (password, TOTP, WebAuthn)
- Multiple identity profiles
- Activity log
- Secret scanner
- Auto-detect PII warnings
- Pre-send PII detection

Kept current manifests (UUID, data_collection_permissions, version).
No renames applied — uses original naming (secretScanning, PPI, etc).
Will re-apply renames and new features from this working base.

https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
2026-03-29 18:45:10 +00:00
Outis 73bc08dad2 Merge pull request #57 from outis1one/claude/read-repo-YMu21
fix: config race condition — use persistent JSON element, bump 0.9.20
2026-03-29 14:25:47 -04:00
Claude 740f692ff1 fix: config not reaching content.js — race condition with script removal
The data-ss-config attribute on the script tag was being removed
(via script.onload) before content.js could read it. Changed approach:
inject config as a separate <script type="application/json" id="ss-config-data">
element that persists in the DOM until content.js reads and removes it.

This eliminates the race condition between script execution and onload
removal. Bump 0.9.20.

https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
2026-03-29 18:25:28 +00:00
Outis 274bb89b48 Merge pull request #56 from outis1one/claude/read-repo-YMu21
fix: restore working injector + add get:decrypted-config handler, bump 0.9.19
2026-03-29 14:07:38 -04:00
Claude b622d5abd4 fix: restore working injector.js + add missing get:decrypted-config handler
Restored injector.js from v2.0.14 (commit 9a11896) which:
- Requests decrypted config from background via get:decrypted-config
  message instead of passing empty arrays when data is encrypted
- Handles the identity.profiles merge correctly for background responses
- Passes ss_settings directly (not checking _ssLocalEncrypted which
  caused settings loss)

Added missing get:decrypted-config message handler to service-worker.js
which returns decrypted mappings, identity, and settings via Storage
module.

https://claude.ai/code/session_01KF4i7Ra7zCEDskxDBaNtcT
2026-03-29 18:06:51 +00:00
Outis 685917f695 Merge pull request #55 from outis1one/claude/read-repo-YMu21
fix: restore working content.js from v2.0.14, bump 0.9.18
2026-03-29 13:56:13 -04:00