Skip to content

chore: sync upstream changes (2026-10-27) - #228

Merged
pando85 merged 41 commits into
mainfrom
sync/upstream-2026-10-27
Oct 27, 2026
Merged

pando85 merged 41 commits into
mainfrom
sync/upstream-2026-10-27

Conversation

@pando85

@pando85 pando85 commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Summary

Selectively reconcile non-passkey changes from agrahn/Android-Password-Store:develop, upstream range 48ce3af5..5f320126 (107 commits, ~55 non-dependency). As before, upstream develop is not merged: the fork's passkey implementation stays authoritative and every upstream commit gets an explicit disposition.

Also adds the opencode skill .opencode/skills/upstream-sync so future syncs can follow the same process (audit → per-area subagent ports in worktrees → integrate → record → dated PR).

Highlights

Full disposition table: docs/upstream-reconciliation.md → Current reconciliation (2026-10-27). Baseline moved to 5f320126e14b9324db7a84f33e48fa9fdbdc30ca.

Passkey boundary — please review

No upstream passkey provider/UI code was imported (35a4294, 2022222, agrahn#1088, agrahn#1089 skipped). Fork passkey-owned paths touched on purpose:

Skipped

Renovate-owned dependency/action bumps, upstream changelog/release/snapshot commits, upstream README/verification text (agrahn#1055), lint baseline for absent bcpkix (agrahn#1086), string tweaks to strings the fork has changed (324757e). Lagging versions vs upstream (left to Renovate): bouncycastle 1.86→1.86.2, serialization 1.11.0→1.12.0, test-parameter-injector 1.24→1.25. The fork keeps jgit 7.8.0 (upstream reverted to 6.2.0).

Validation

  • CI=true ./gradlew lint spotlessCheck test -PslimTests assembleDebug passes locally: 633 unit tests, 0 failures, including the new AutofillPasskeyExclusionTest.
  • Not tested on a device: password creation form, combinations of mapped directories and Autofill save, shared-repo storage (no storage permission, so it relies on scoped storage, as upstream does), and the Android 17 local-network flow. Manual QA is recommended before release.

agrahn and others added 30 commits October 27, 2026 20:53
Cherry-picked from upstream fe3a199 (agrahn#1076).

Fork adaptation: kept GitOperationCoordinator serialization. The lock is taken
after the local-network permission flow so an interactive permission request
never blocks background passkey sync. Upstream CHANGELOG/README hunks omitted.

(cherry picked from commit fe3a199)
Cherry-picked from upstream ce90e84 (agrahn#1112).

The fork already uses sshj 0.41.2, so the fix applies: the Conscrypt EdDSA
normalizeForSshj workaround (agrahn#868) is dropped because sshj >= 0.41.1 handles
those keys natively. The fork's existing provider-ordering comment in
SshKey.kt is kept.

(cherry picked from commit ce90e84)
infer missing runtime permission from timeout exception thrown

(cherry picked from commit 35f993e)
Adapted from upstream 2b4a5e2 (agrahn#1063) and a7adcd4 (agrahn#1115). The fork has no
bcpkix dependency, so only bcprov/bcutil/bcpg are aligned; the BOM is applied
in every module that consumes the versionless aliases (app, crypto:pgpainless,
passkeys:core, passkeys:provider). The separate bcprov version is no longer
needed. kotlinx-coroutines-android is now resolved through the coroutines BOM.

(cherry picked from commit 2b4a5e2)
(cherry picked from commit a7adcd4)
Cherry-picked from upstream 1f70ce6 (agrahn#1119).

Fork adaptation: kept the GitOperationCoordinator lock (taken after the
permission flow). Upstream CHANGELOG hunk omitted.

(cherry picked from commit 1f70ce6)
Cherry-picked from upstream f33c65f (agrahn#1129).

Fork adaptation: German translation conflict resolved keeping the fork's
"Abbruch" label for git_server_hostkey_dialog_abort while adding the new
banner dialog strings. Upstream CHANGELOG hunk omitted.

(cherry picked from commit f33c65f)
(cherry picked from commit 1c048ab)
Fixed "entrada de búsqueda" with "búsqueda de entrada", as the former means "entry of search" and doesn't make sense, while the latter does mean that you want to search for an entry.

Signed-off-by: Pablo Alonso Rodriguez <palonsoro@users.noreply.github.com>
(cherry picked from commit e2de1b1)
also, _default_ email for commit messages and generated ssh keys
adjusted to aps@ + device model (android.os.Build.MODEL)

(cherry picked from commit c3ce2ca)
Cherry-picked from upstream 8ce4a3d (agrahn#1162).

Security-relevant: sshj 0.41.1+ resets BouncyCastle registration when the
provider is cleared, which broke host key verification after a keystore-backed
key had disabled BC. setUpBouncyCastleForSshj() now re-enables BC and the
provider on every connection (also used by the headless passkey sync SSH
session); the redundant per-key re-registration is removed. Also treats an
empty author e-mail as unset for the public key comment.

Fork adaptation: conflict resolved by taking upstream's userId handling
(replaces the fork's "nn@aps" fallback) and block comment; CHANGELOG omitted.

(cherry picked from commit 8ce4a3d)
…ream/develop

Single snapshot replacing upstream's generated update commits agrahn#1068, agrahn#1092,
agrahn#1106, agrahn#1122, agrahn#1131, agrahn#1154, agrahn#1167 (upstream develop 069f892).
Forward the autofill client state to AutofillSaveActivity so that the
newly created credentials can be filled in after creation, and use
distinct PendingIntent request codes for the autofill activities.

Ported from upstream 4769224.
The PasswordCreationActivity/layout/string hunks are ported together
with the rest of the upstream password-creation series in a later
commit; the CredmanUtils hunk does not apply (upstream passkey code).

(cherry picked from commit 4769224)
list of matched items: file path with the matched search string as
bold text shown on the first line and the password file with two parent
directory levels (at most two) on the second line of each list item

(cherry picked from commit 1307f4b)
Cherry-picked from upstream 30cfa16 (agrahn#1168).

Reintroduces the optional shared-folder repository (Documents/PasswordStore)
selectable during onboarding and shown in repository settings.

Fork adaptation: CHANGELOG omitted; Application.kt conflict resolved by
dropping the now-unused @FilesDirPath injection; strings conflicts resolved
keeping the fork's dialog_cancel wording while adding dialog_continue and the
new onboarding/visibility strings. Passkey storage roots are adapted in a
follow-up commit.

(cherry picked from commit 30cfa16)
for entries without encrypted username (file-based, dir-based), lookup
username now based on form origin; lookup based on current directory
structure setting (aka password file organisation) only used as fallback

Fork adaptation: instead of storing the origin in a static companion
field when the PendingIntent is created, AutofillDecryptActivity derives
the form origin from the autofill client state it already receives. This
also covers the fork's external OpenPGP provider decrypt path. Upstream
CHANGELOG hunk skipped.

(cherry picked from commit 2b3312e)
automatically switches to popup view with scrollable list

Fork adaptation:
- matches stored by older versions as an unordered Set<String> are
  migrated to the new ordered representation instead of being dropped;
- the suggestion-order update in AutofillDecryptActivity uses the form
  origin from the client state (no static state) and also runs for the
  fork's external OpenPGP provider decrypt path;
- fixed operator precedence in the inline suggestion content
  description;
- upstream CHANGELOG hunk skipped; PasswordStore.moveFile hunk not
  applicable (fork moved the code, call sites unchanged).

(cherry picked from commit 13e7961)
…adapts upstream agrahn#1168)

Upstream agrahn#1168 reintroduces an optional shared-folder repository, so the
repository root is no longer always filesDir/store. Passkey storage, recipient
resolver and generation provider now use PasswordRepository.getRepositoryDirectory()
so passkeys stay in the same working tree that Git sync operates on.
Follow-up hardening for upstream agrahn#1119 (close the local-network probe socket
instead of leaking it) and agrahn#1168 (RepoVisibilityFragment.createRepository
pushed KeySelectionFragment twice).
…rahn#1079)

Upstream agrahn#1079 ("no autofill with passkey data") decrypts the selected
entry and refuses to fill it when it contains passkey data. The same
invariant applies to this fork, but the detection is reimplemented for
the fork's passkey storage format: passkey credentials are encrypted
CBOR files below the repository's passkey directory
(PasskeyStorageConfig.passkeyDirectory, "fido2/<rp>/<id>.gpg").

- AutofillPasskeyExclusion identifies files in the passkey directory
  (path-based, optionally resolving symbolic links);
- AutofillDecryptActivity refuses such files before anything is
  decrypted, drops stale matches and shows the upstream message;
- the Autofill search pane and the stored quick-select matches never
  include passkey credential files;
- as upstream: the quick-select match is now recorded by
  AutofillDecryptActivity after a successful fill, only if the
  "add quick select button" switch is enabled.

The unrelated dialog_delete_msg wording change bundled in the upstream
commit and the upstream CHANGELOG hunk are not taken; fixed a typo in
the German translation.

Upstream: ada5dd5
Fork adaptation: upstream temporarily overwrites the global "show
hidden contents" setting while the Autofill search pane is open and
restores it in onStop(), which loses the user's setting if the process
dies in between. Instead, the search pane now filters its result list
itself: only non-hidden *.gpg files are offered (this also keeps
hidden metadata such as Pass-Secrets' .secrets.gpg out of the list),
combined with the passkey exclusion. The search filter mode now honours
the app's search setting (exact/fuzzy) unless phishing-resistant search
is enabled, as upstream. Message wording updates taken from upstream.

(cherry picked from commit abd234e)
Fork adaptation: AutofillDecryptActivity keeps deriving the form origin
from the autofill client state, so makeDecryptFileIntent() does not
take (and statically store) a FormOrigin; the "remove quick select
button when disabled" behaviour is applied in the shared
updateAutofillMatches() helper, which also covers the external OpenPGP
provider path.

(cherry picked from commit 7d62402)
pando85 and others added 11 commits October 27, 2026 21:06
* suppress autofill save-password UI after manually entering username
  and password into a web form and submittng it, if an entry for
  origin+username already exists in the password repo

* autofill setting "Ask to save password" added

Fork adaptation:
- PasswordRepository.findByName()/findByParentName() are added here
  (the fork had removed upstream's passkey-only predecessors); they do
  not descend into hidden directories such as .git, which keeps the
  per-fill-request lookup cheap;
- known usernames ignore passkey credential files and non-.gpg/hidden
  files, and are looked up with the plain (unquoted) app label so that
  app origins can match as well;
- PasskeyCreationActivity/CredmanUtils hunks (upstream passkey code),
  the AutofillSaveActivity hunk (ported with the password-creation
  series) and the CHANGELOG hunk are not taken.

(cherry picked from commit c329e9e)
Upstream CHANGELOG hunk skipped.

(cherry picked from commit 0ea4370)
use fuzzy matcher to determine the type of directory structure (file
or directory-based)

(cherry picked from commit 5ba944c)
Upstream CHANGELOG and fastlane changelog hunks skipped.

(cherry picked from commit 60e8593)
exact matching between origin identifier and folder name is also tried

Fork adaptation: fuzzy matching is skipped for an empty parent or
grandparent name (entries at the repository root or one level below),
which would otherwise trivially match any origin.

(cherry picked from commit 48978fd)
…am series)

Ports the upstream password-creation / autofill-save series as one
change, because the six upstream commits repeatedly rewrite the same
PasswordCreationActivity code paths and the intermediate states do not
map onto the fork's Pass-Secrets aware save flow:

- 6f66681 manual password creation: honour directory structure setting
- 4769224 autofill-save fix: fill in credentials after creation
           (PasswordCreationActivity/layout/string parts; the rest was
           ported earlier)
- 0c2ab3c autofill-save: preserve subfolder structure of new entry
- 0676a7b autofill-save: fix username pre-fill after credential
           creation (agrahn#1056)
- bbedde0 fixing password entry creation and editing (agrahn#1101)
- e224dac refactorings of password creation UI (agrahn#1109)

Behaviour (as upstream e224dac): the "New password" form shows
name/username/file name fields and an "Insert username" switch
depending on the password file organisation setting and on whether the
entry is edited, created in the app, or created via Autofill. Entries
created via Autofill are stored as .../<origin>.gpg,
.../<origin>/<username>.gpg or .../<origin>/<username>/<file>.gpg, and
the suggested parent folder is the one already holding entries for the
same origin. Generated credentials are filled into the form afterwards.
The folder picker lists entries as well as folders.

Fork adaptations:
- writes still go through PassSecretsMutationService; inside a
  Pass-Secrets mapped directory no plaintext origin/username
  sub-directories are created, the structure becomes part of the
  (encrypted) logical name instead; metadata unlock is requested for
  the final destination directory;
- AutofillSaveActivity keeps sanitizing the origin (directory
  traversal), looks up existing origin folders only when the user
  actually saves (not on every fill request), ignores passkey
  credential folders, and falls back to the fork's configurable
  Autofill save directory;
- "." and ".." are rejected as name/username/file name;
- generated credentials are returned as copies so the originals can be
  wiped;
- intent extra names (EXTRA_FILE_NAME) and DecryptActivity are kept;
  PasskeyCreationActivity hunks (upstream passkey UI), README, CHANGELOG
  and unrelated git commit message wording changes are not taken.
# Conflicts:
#	app/src/main/java/app/passwordstore/util/git/sshj/SshKey.kt
@pando85
pando85 merged commit c1b371e into main Oct 27, 2026
5 checks passed
@pando85
pando85 deleted the sync/upstream-2026-10-27 branch October 27, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants