mirror of
https://github.com/block/buzz.git
synced 2026-11-05 00:41:28 +00:00
fix(invites): run the unknown-code check inside the admitted transaction
989412f3 ran the pre-lock `SELECT EXISTS` on the bare pool before
`begin_community_write_transaction`. That answered claims on fenced
(quiescing/deleting) tenants with `invite_invalid` instead of the fence
rejection, and acquired a writer connection outside a typed
`WriterOperation`. Open the admitted transaction first, which enforces
the tenant fence and attribution without taking the invite admission
lock, then check the code on `tx.conn()` before `lock_admission`.
Co-authored-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Luke Tornquist <tornquist@squareup.com>
This commit is contained in:
@@ -423,21 +423,6 @@ pub async fn claim_relay_invite_with_owner(
|
||||
verified_owner: Option<&str>,
|
||||
relay_keypair: &nostr::Keys,
|
||||
) -> Result<MembershipWrite<InviteClaimResult>> {
|
||||
// Unknown codes are free to forge, so reject them before taking the
|
||||
// community-wide admission lock; the locked read below stays authoritative.
|
||||
let known: bool = sqlx::query_scalar(
|
||||
"SELECT EXISTS (SELECT 1 FROM relay_invites \
|
||||
WHERE community_id = $1 AND token_hash = $2)",
|
||||
)
|
||||
.bind(community.as_uuid())
|
||||
.bind(token_hash)
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
if !known {
|
||||
log_claim_outcome(community, None, "invalid", None, None);
|
||||
return Ok(MembershipWrite::unchanged(ClaimOutcome::Invalid.into()));
|
||||
}
|
||||
|
||||
let mut tx = crate::begin_community_write_transaction(
|
||||
pool,
|
||||
community,
|
||||
@@ -445,6 +430,23 @@ pub async fn claim_relay_invite_with_owner(
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Unknown codes are free to forge, so reject them after the tenant fence
|
||||
// but before the community-wide admission lock; the locked read below
|
||||
// stays authoritative.
|
||||
let known: bool = sqlx::query_scalar(
|
||||
"SELECT EXISTS (SELECT 1 FROM relay_invites \
|
||||
WHERE community_id = $1 AND token_hash = $2)",
|
||||
)
|
||||
.bind(community.as_uuid())
|
||||
.bind(token_hash)
|
||||
.fetch_one(tx.conn())
|
||||
.await?;
|
||||
if !known {
|
||||
tx.rollback().await?;
|
||||
log_claim_outcome(community, None, "invalid", None, None);
|
||||
return Ok(MembershipWrite::unchanged(ClaimOutcome::Invalid.into()));
|
||||
}
|
||||
|
||||
lock_admission(tx.conn(), community).await?;
|
||||
if claim_owner::claimant_restricted(tx.conn(), community, claimer_pubkey, verified_owner)
|
||||
.await?
|
||||
|
||||
Reference in New Issue
Block a user