Fail open on clan tag ownership checks when API is unavailable

The clan-tag ownership check previously failed closed: when the API
service was unreachable (e.g. during local development), the client
dropped the tag with a "couldn't verify" error and the server's
FailOpenPrivilegeChecker treated every unverifiable tag as reserved.
This made clan tags unusable whenever the API was down.

- Client: checkClanTagOwnership keeps the tag when the existence
  probe is inconclusive; the server still re-checks authoritatively.
- Server: FailOpenPrivilegeChecker passes tags through instead of
  dropping non-member tags; decideClanTag now takes a non-nullable
  reserved set since the null case is gone.
- Remove the now-unused username.tag_check_failed translation key.
- Update Privilege and ClanApiQueries tests for fail-open behavior.

Trade-off: if the reserved-tag list is unavailable in production,
real clan tags can be impersonated until the first successful
PrivilegeRefresher load; after that the last good checker is retained.
This commit is contained in:
evanpelle
2026-06-11 12:22:33 -07:00
parent 625d54c128
commit 3c0ff7a6f2
5 changed files with 22 additions and 22 deletions
+4 -2
View File
@@ -162,9 +162,11 @@ export async function checkClanTagOwnership(
}
const exists = await fetchClanExists(tag);
if (exists === false) return { tag, error: null };
if (exists === true) return { tag: null, error: "username.tag_not_member" };
return { tag: null, error: "username.tag_check_failed" };
// Tag doesn't exist (fictional) or the check was inconclusive (API
// unavailable, e.g. during development) — fail open and keep the tag;
// the server re-checks authoritatively.
return { tag, error: null };
}
export type ClanMemberSort =