444 Commits

Author SHA1 Message Date
Alex van de Sandt 8ae9ce9c8f fix: enable autocomplete in totp verification 2026-07-02 20:29:22 +03:00
Lewis 6ec4484cad sqlx: add missing file
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-29 08:31:30 +03:00
Lewis f3af04e4ae dns: fall back to defaults if smth bad
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-28 10:12:00 +03:00
Lewis aab1a945c2 session: deletes scope to did, route muts by did
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-28 09:55:11 +03:00
ave 9dc184ee33 bsky(auth): add grace period to legacy session refresh
Concurrent or retried com.atproto.server.refreshSession calls presenting the
same refresh token hit the reuse-detection path, which deleted the session and
returned "Refresh token has been revoked due to suspected compromise" —
logging users out at random. The legacy flow had no grace period, unlike OAuth.

Mirror the reference atproto PDS: every rotated refresh token gets a 2h grace
window measured from its own rotation time (used_refresh_tokens.used_at in
postgres; a rotated_at_ms field appended to the metastore used-marker, with
old-format markers decoding as outside the window). A refresh presenting a
recently-rotated token is served the session's current tokens, re-minted on
the fly with the same jti/expiry — signed JWTs are never persisted. Reuse
outside the window still revokes the session.

The grace lookup returns the session's encrypted signing key so the handler
verifies the presented token's signature before minting replacement tokens or
revoking a session; a forged token bearing a known jti gets a generic
rejection with no side effects.

Integration tests asserting the old replay-gets-401 behavior are reworked to
the new contract and now also cover forged-signature replays and
out-of-window revocation.
2026-06-27 23:54:22 +03:00
Lewis ab4eba6dc4 delegation: preset scopes grant identity & account
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-27 23:11:24 +03:00
Lewis a171518290 tranquil-store/repo: repair tolerates corrupt/missing blocks
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-26 20:50:30 +03:00
Lewis 28f2e04019 plc: always keep signing key in rotationKeys
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-26 18:52:12 +03:00
Lewis 39a2e40b35 invite codes: dedup consumption, iron out kinks
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-26 13:28:49 +03:00
isabel 05ab0b7423 nix: use systemd-nspawn tests
this speeds tests up like 10 fold; had to swap from sudo to runuser
since sudo wanted passwords
2026-06-22 20:31:06 +03:00
Lewis 221b32d66f build: smaller faster prod container
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-19 09:16:30 +03:00
Lewis 1b489776c5 server healthcheck in-bin
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-18 09:34:36 +03:00
nelind 2ca15fe7a0 fix(nix): disable the nixpkgs tranquil module when the repo module is used 2026-06-17 11:53:58 +02:00
ave 48ae1e8b7b Move Dockerfile(s) from musl to glibc
Musl is tier 2 on rust support, and glibc is tier 1.
https://doc.rust-lang.org/nightly/rustc/platform-support.html
Generally, glibc rust is reported to be more performant. Could vary due
to any other reason, but in my testing, builds were up to 50% faster
(for docker cross-compilation amd64->arm64 at least).
2026-06-16 14:31:32 +03:00
ave 6838976969 fix(cors): Allow User-Agent header in CORS 2026-06-15 13:27:31 +03:00
Jim Severino 3045ee25c0 Fix(docs): Add correctly TOML-formatted values for first string and array examples 2026-06-15 11:04:59 +03:00
Jim Severino 04a90b1563 Fix(docs): Change symlinks to SSL cert files from absolute to relative 2026-06-15 11:04:59 +03:00
Lewis e13ba7f4c7 ripple: anti-entropy gossip sync
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-14 18:46:41 +03:00
Lewis a3f729c3cd ripple: fail-closed startup, bind policy
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-14 18:46:41 +03:00
Lewis 637b817a33 ripple: cluster-key oomf authentication
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-14 18:46:41 +03:00
Lewis 562f970bc3 ripple: transport backpressure & connect coalesing
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-14 18:46:41 +03:00
Lewis 06fd6a1ce9 ripple: transport from tcp to quic
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-14 18:46:41 +03:00
nelind 3b07cdfb24 fix(api): dont verify signature or DID during importRepo 2026-06-13 23:33:57 +03:00
nelind 4a8826b7a1 fix(docs): i forgor auto links need absolute URIs ... lets use normal links instead 2026-06-12 01:00:24 +02:00
nelind 80afd764d3 fix(nix): provide a jemalloc build in the dev shell 2026-06-10 19:56:40 +02:00
Lewis 5bbe2146ff server: serve xrpc over http/3
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-10 13:18:49 +03:00
Lewis b009ccdaf2 repo: the pg side of MST structural repair
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-08 16:58:51 +03:00
nelind 39f74b5adf feat(nix): pratice what i preach. expose lib.mkPackages 2026-06-07 22:14:27 +02:00
ave a231d7da29 feat(auth): accept totp/backup codes in legacy login createSession 2026-06-06 10:42:24 +03:00
ave 63d84d38fb refactor(auth): unify short-code generation onto util::generate_token_code
Collapse the three ad-hoc short-code generators into one canonical generator
plus a shared normalizer:

- util::generate_token_code now emits the uppercase base32 XXXXX-XXXXX display
  form; new util::normalize_token_code canonicalizes user input (uppercase,
  strip hyphen/whitespace).
- email_token and legacy_2fa now generate via util, store the normalized form,
  and compare normalized input. Their private generate_short_token/generate_code
  (and BASE32_CHARS/CODE_LENGTH) are removed.
- PLC (request/sign) and password reset inline util::generate_token_code,
  persist the normalized form, email the display form, and normalize input
  before lookup. The generate_plc_token/generate_reset_code wrappers are removed.

Behavior changes: legacy login-2FA codes go from 8-digit numeric to XXXXX-XXXXX;
PLC and password-reset codes go from lowercase to uppercase. All four code types
are now accepted case-/hyphen-insensitively. OAuth web-login 2FA, account
deletion, and the long verification_token blobs are intentionally untouched.

Tests: add util normalize tests + email_token/legacy_2fa case/hyphen tests;
update integration tests to expect the canonical stored form and the new
emailed format.
2026-06-06 09:36:08 +03:00
ave fe9b88141c chore(auth): align at+jwt/refresh+jwt expiry with reference PDS 2026-06-06 01:43:46 +03:00
ave 72f5dce32b add ave.zone to contributors list in README 2026-06-06 01:42:54 +03:00
nelind cd7e01100e chore(auth): also mention that atproto spec requiers typ be "JWT" for inter-service tokens 2026-06-05 12:49:25 +02:00
ave 7c248be153 fix(auth): emit uppercase "JWT" typ in service-auth header
RFC 7519 §5.1 recommends the uppercase "JWT" typ for compatibility with
legacy implementations, and it matches the reference @atproto/pds. Parsing
already lowercases, so existing lowercase "jwt" tokens still verify.
2026-06-05 13:34:43 +03:00
ave 91999819c6 fix(proxy): limit audience of getFeed service-auth to the feed generator v0.6.5 2026-06-04 22:39:14 +03:00
nelind ffce1d5d05 feat(docs): add some general PDS debugging documentation 2026-06-04 13:45:08 +03:00
Tyler 8e6ace2fe2 fix: derive lexicon DNS authority from all-but-last NSID segment
Permission-set expansion resolved the lexicon's DNS authority using a
fixed `parts[..2]`, which only works for three-segment NSIDs. For a
four-segment NSID such as community.lexicon.bookmarks.authManageBookmarks
this dropped a segment and queried _lexicon.lexicon.community instead of
_lexicon.bookmarks.lexicon.community, failing with "DNS resolution
failed: ... no record found".

The authority is every NSID segment except the last (the name),
reversed. Use parts[..parts.len() - 1] to match the spec and the
existing extract_namespace_authority helper, and update the DNS
authority test with three/four-segment and bookmarks regression cases.
2026-06-04 01:28:13 +03:00
Lewis 3018a20843 fix(plc): allow arbitrary services to sign
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-03 11:23:51 +03:00
Lewis 37fc06fb39 fix(store): unblock eventlog sync&freeze when writer dies
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-02 17:29:21 +03:00
Lewis 728a8c4d3b test(store): cross-store, firehose, read-validation coverage w/ faults
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-02 17:29:21 +03:00
Lewis 3d49e99cc3 test(store): generic consistency checker, gauntlet fault/read
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-02 17:29:21 +03:00
Lewis 7e823673ca test(store): untested metastore, eventlog, & archival stuff
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-02 17:29:21 +03:00
Lewis 320933598c fix(auth): error num 401 for oauth
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-01 19:38:45 +03:00
Lewis 500dc2e0e6 test(store): gauntlet sweep configs for time-travel & fsync repro
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-01 19:01:04 +03:00
Lewis a220611a8b test(store): D gauntlet faults, crash-loss oracley, recoverable scenarios
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-01 19:01:04 +03:00
Lewis ca7a4b4b73 fix(store): recover eventlog lastseq from tail not sidecar
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-01 19:01:04 +03:00
Lewis 8ff02610e4 feat(store): inline-commit mode, committed-extent recovery, failsafe verify&rollback
Lewis: May this revision serve well! <lu5a@proton.me>
2026-06-01 19:01:04 +03:00
Lewis 22f82489d5 test(pds): e2e & durability coverage for MST self-heal
Lewis: May this revision serve well! <lu5a@proton.me>
2026-05-31 21:11:36 +03:00
Lewis cee483e358 feat(pds): selfhealing repo writing by detecting corruption & retrying
Lewis: May this revision serve well! <lu5a@proton.me>
2026-05-31 21:11:36 +03:00
Lewis 7f8e858137 test(store): gauntlet MST-repairable & misdirected-write scenario
Lewis: May this revision serve well! <lu5a@proton.me>
2026-05-31 21:11:36 +03:00