Commit Graph
561 Commits
Author SHA1 Message Date
TrezyandTangled 71cd282d1e feat: show repo actions narrowed out by client metadata on consent
Signed-off-by: Trezy <tre@trezy.com>
2026-09-16 16:20:17 +00:00
TrezyandTangled 0e40bdca19 fix: store filtered scopes on tokens so refresh can skip the client metadata check
Signed-off-by: Trezy <tre@trezy.com>
2026-09-16 16:20:17 +00:00
TrezyandTangled 156066fe1b fix: reject PAR requests missing the atproto scope
Signed-off-by: Trezy <tre@trezy.com>
2026-09-16 16:20:17 +00:00
TrezyandTangled 311530a9a9 test: give the mock client a scope so NotRegistered actually gets exercised
Signed-off-by: Trezy <tre@trezy.com>
2026-09-16 16:20:17 +00:00
TrezyandTangled 08cd3fa100 chore: remove unreachable scope format check in consent
Signed-off-by: Trezy <tre@trezy.com>
2026-09-16 16:20:17 +00:00
TrezyandTangled 12a8712eae fix: unrecognized scopes can no longer fail PAR
Signed-off-by: Trezy <tre@trezy.com>
2026-09-16 16:20:17 +00:00
LunaandTangled cdd5fa70c9 fix: add MIME version to outgoing mail 2026-09-14 13:40:08 +00:00
xan.lolandTangled 218741050d add a period (spelling fix) 2026-09-13 22:47:12 +00:00
Johanna LarssonandTangled b3ff62c221 Simplify blob migration 2026-09-12 15:34:46 +00:00
Johanna LarssonandTangled 2088f59197 Stop deleting logo blob when switching
This also means we can clean up the last blob operations that were per cid rather than user+cid 🪓

We should be setting ourselves up to be able to go garbage collect blobs safely so deleting the logo blobs manually won't matter anyway.
2026-09-12 15:34:46 +00:00
Johanna LarssonandTangled 2fc5f2e308 Wrap in counter lock and stop deleting blobs by cid 2026-09-12 15:34:46 +00:00
Johanna LarssonandTangled 877b587481 Ensure listing missing blobs always checks per user blobs 2026-09-12 15:34:46 +00:00
Johanna LarssonandTangled 695a7d981c Allow blobs to be owned by multiple accounts
The current tranquil database design only allows each blob to be owned by one account. This means that if a second account also has that blob, tranquil skips associated the blob with the account. That works fine a lot of the time, since blobs are looked up by cid and the blob exists. However, it can lead to loss of data under certain scenarios.

One example is where I upload a blob, the blob already exists in my instance so insertion is skipped (postgres requires cid to be unique in blobs, fjall only allows one owner per blob cid), I then decide to migrate off tranquil, the blob does not come with me since it is not mine.

Another example is where an account is deleted. If a blob was uploaded for account a, then account b uploads the same blob tranquil skips storing it since it exists. Then I delete account a, now account b's blob is missing.

I accidentally stumbled upon this when I migrated my account to my own tranuil instance and list blobs now lists 2 fewer blobs than before, two images that had been uploaded by accounts already on the PDS.

ps I found record_blobs a bit confusing, at first it looked like a blob ownership table, but then it turns out to just be used for migrations!

This PR makes the blob primary key be cid+user for postgres, and updates the queries to account for there being multiple "blobs" with the same cid. For queries that just care about the blob existing, it doesn't matter "whose" blob it is, so limit 1.

Most of the work is on the metastore side. Adds ref_count to track how many are referencing the blob since we can't just check for other rows. Instead of storing blobs directly, we now store a per account cid, and the blob reference itself is shared and keyed by cid only. This means some of these operations now require updating two places, so they're done in `batch`es.

With the new layout get_blob_value becomes simpler, all blob data is a single "table" or whatever it's called, so we just grab it using cid instead of looking it up for the user.

Migrates blobs rather than maintaining two different versions of the tables, although it seems like that could be supported.

I removed a test that asserted the old behavior, and added a reasonable (?) set of new tests that assert the new behavior, including a parity test.
2026-09-12 15:34:46 +00:00
Johanna LarssonandTangled 04689cbe25 Improve logging and correct translation string 2026-09-11 19:54:37 +00:00
Johanna LarssonandTangled 3474ed588d Make legacy login alerts configurable
This adds security alerts section to the communication settings, with one new item: a toggle for enabling/disabling legacy login alerts. It's enabled by default. Disabling it means that you no longer get emails when logging in through a non-2FA enabled login flow, like createSession.

The reason I tackled this is that I have a bot account that automatically refreshes its session, using username and app password, and I'm close to having 100 of these emails in my inbox. I also tried to just disable TOTP but I wasn't allowed (I fixed that in a different PR).

English and Swedish translations were me, the rest were MyMemory. I imagine someone can improve on them after this is merged!
2026-09-11 19:54:37 +00:00
Johanna LarssonandTangled 09ba5e4521 Allow disabling TOTP even if last session was legacy
This removes the `require_legacy_session_mfa` call on the TOTP disable path. It looks at the last session, which isn't really relevant, and we're getting a fresh TOTP from the form anyway, which should be enough proof to allow disabling TOTP.

The way I bumped into this was having a "bot account" log in with app password on some app on a schdule, triggering lots of warning emails. So I tried to disable TOTP to stop the flood and wasn't allowed.
2026-09-05 18:16:56 +00:00
SteffoandTangled 6750aeccaf fix: Use "registered notification channel" where applicable 2026-09-03 13:37:09 +00:00
LewisandTangled 8c3386a3ab caddy: on-demand TLS endpoint
Lewis: May this revision serve well! <did:plc:3fwecdnvtcscjnrx2p4n7alz>
2026-09-01 16:31:10 +00:00
TrezyandTangled eba8167da8 chore: clean up supersedence shtuff
Signed-off-by: Trezy <tre@trezy.com>
2026-08-29 20:11:10 +00:00
TrezyandTangled 2e92310518 fix: allow transition:generic to be used with granular scopes
Signed-off-by: Trezy <tre@trezy.com>
2026-08-29 20:11:10 +00:00
nelindandTangled 0e82a38add fix(api): dont do rotation key validation in signPlcOperation as it blocks migrations 2026-08-29 05:42:03 +00:00
TrezyandTangled 1866d2bf0e test: i dunno what youre talking about i would never leave prints in production code 🙃
Signed-off-by: Trezy <tre@trezy.com>
2026-08-28 20:28:54 +00:00
TrezyandTangled dc2f924130 fix: add transition: scopes to owner-level delegates
Signed-off-by: Trezy <tre@trezy.com>
2026-08-28 20:28:54 +00:00
TrezyandTangled 97224551bf test: verify taxonomy entries parse to the correct type
Signed-off-by: Trezy <tre@trezy.com>
2026-08-28 20:28:54 +00:00
TrezyandTangled 68ae485a52 fix: restore rpc: scopes for delegation
Signed-off-by: Trezy <tre@trezy.com>
2026-08-28 20:28:54 +00:00
Johanna LarssonandTangled 228c1bbbf5 Normalize the allow private IPs flag application 2026-08-28 12:36:47 +00:00
Johanna LarssonandTangled 093484388f Allow private IPs in dev
Running tranquil with `just run-dev` using `pds.test` seems to be broken due to a recent change that blocks requests to private ips. Inside the compose network `pds.test` resolves to the traefik container's private IP. So it can't make requests to stuff like `https://pds.test/oauth-client-metadata.json` or the local plc.

Introduces a new flag, default off, that allows connecting to private IPs, set to true for the dev compose.
2026-08-28 12:36:47 +00:00
Johanna LarssonandTangled 0f0c50f7d4 Loosen CORS header requirements
Bluesky started sending `x-bsky-is-beta-user` for some users on XRPC requests, but tranquil has a strict allowlist of CORS headers. The spec doesn't (?) specify any requirements around CORS headers, so we can avoid trouble when Bluesky make changes by just allowing all headers.

This PR replaces the allowlist with the request mirror behavior, where any headers sent on a CORS request are echoed back. This also matches the reference PDS.
2026-08-28 07:16:50 +00:00
Jack PlattenandTangled 26aa399cda Fix name of test 2026-08-27 20:07:59 +00:00
Jack PlattenandTangled f296bb68df fix: allow path-empty URIs and drop authority/path charset checks
RFC 3986 lets hier-part be path-empty, so "urn:" alone is a valid
URI; treat it as one.
2026-08-27 20:07:59 +00:00
Jack PlattenandTangled d979cb969a add underscore to scheme support.
adds tests for mbid directly, as well as underscore scheme.

Followup:
`scheme:` is not currently passing this function, but can wait for now
2026-08-27 20:07:59 +00:00
739db41130 fix: accept RFC 3986 scheme:opaque-part URIs without //
is_valid_uri required a literal "://", but the atproto uri string
format follows RFC 3986's generic URI grammar, which also allows
"scheme:opaque-part" forms with no authority (e.g. urn:isbn:...).
Records using such values were rejected once production lexicons
enable strict validation.

Reported as #130.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 20:07:59 +00:00
Johanna LarssonandTangled c0caa93228 Dev compose improvements
1. Set the max connections to 20, I frequently see

db-1            | 2026-08-23 08:57:02.784 UTC [12641] FATAL:  sorry, too many clients already

2. Add a wildcard route in Traefik to serve DID documents locally.

3. Expose the PLC port locally so I can point an app at `http://localhost:2582` and be able to do full OAuth flows.
2026-08-23 09:50:08 +00:00
blooym.devandTangled 3ade3d10c1 docs: clarify the postgres seq fix command
There was a syntax error in this command, so I updated the doc to clarify it and also show it needs an integer, not a string like it implied before.
2026-08-21 17:35:46 +00:00
Jack PlattenandTangled 0189aa9f96 Update config commit to create new round 2026-08-21 16:16:45 +00:00
Jack PlattenandTangled d495d7d729 Use crate::types::queuedcomms export
also generate example.toml
2026-08-21 16:16:45 +00:00
73cb89c9b7 resolve review feedback.
- eliminates panic opportunity on receiving email
- strict enum
- added unit test for ensuring that atmos headers don't leak onto
  directmx

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 16:16:45 +00:00
Jack PlattenandTangled ecb7934a20 fix: fix missing test failure 2026-08-21 16:16:45 +00:00
Jack PlattenandTangled 9edc7dcdd8 comms: add comail.at category support
Adds a defaulted to off option to add the `X-Atmos-Category` headers
to emails sent via smarthost, for proper categorization by comail.

Category breakdown is as follows:

verification: EmailVerification, ChannelVerification, ChannelVerified,
  MigrationVerification, LegacyLoginAlert, EmailUpdate, PlcOperation,
  AccountDeletion
password-reset: PasswordReset, PasskeyRecovery
mfa-otp: TwoFactorCode
bulk: Welcome
untagged: AdminEmail
2026-08-21 16:16:45 +00:00
Matan KushnerandTangled 479fa3ed22 fix: require DPoP for loopback clients 2026-08-21 11:41:29 +00:00
Louis EscherandTangled aa815931e0 Update lib.rs 2026-08-20 08:21:53 +00:00
Louis EscherandTangled 0ce725174d fix: DID length test, service test, cloning, dead code (should be it!) 2026-08-20 08:21:53 +00:00
Louis EscherandTangled dae3cc7e08 fix: aud fragment matching 2026-08-20 08:21:53 +00:00
Louis EscherandTangled b9e7955606 fix: pass exp to token creation 2026-08-20 08:21:53 +00:00
Louis EscherandTangled 32c58b1d0b fix: make thingy allow list 2026-08-20 08:21:53 +00:00
Louis EscherandTangled 1b5a2b319c fix: getServiceAuth aud parsing 2026-08-20 08:21:53 +00:00
LewisandTangled ed3d129594 just: clippy over all targets, lint the bsky-off build
Lewis: May this revision serve well! <did:plc:3fwecdnvtcscjnrx2p4n7alz>
2026-08-16 17:15:23 +00:00
LewisandTangled 8d0b6f8322 cache: DID, SSO, & OAuth client metadata caches onto shared cache
Lewis: May this revision serve well! <did:plc:3fwecdnvtcscjnrx2p4n7alz>
2026-08-16 17:15:23 +00:00
LewisandTangled 0fc577316e lexicon: schema docs & negative results via cluster cache
Lewis: May this revision serve well! <did:plc:3fwecdnvtcscjnrx2p4n7alz>
2026-08-16 17:15:23 +00:00
LewisandTangled 52d5236e89 plc: dedup fetch paths, cache TTL from config
Lewis: May this revision serve well! <did:plc:3fwecdnvtcscjnrx2p4n7alz>
2026-08-16 17:15:23 +00:00