mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 08:00:18 +00:00
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:
@@ -575,13 +575,13 @@ describe("FailOpenPrivilegeChecker#resolveClanTag", () => {
|
||||
expect(result).toEqual({ tag: "ABC", dropped: false });
|
||||
});
|
||||
|
||||
it("drops a non-member's tag fail-closed (no reserved set while infra is down)", () => {
|
||||
it("keeps a non-member's tag fail-open (no reserved set while infra is down)", () => {
|
||||
const result = checker.resolveClanTag("ABC", ["other"]);
|
||||
expect(result).toEqual({ tag: null, dropped: true });
|
||||
expect(result).toEqual({ tag: "ABC", dropped: false });
|
||||
});
|
||||
|
||||
it("drops an anonymous user's tag fail-closed", () => {
|
||||
it("keeps an anonymous user's tag fail-open", () => {
|
||||
const result = checker.resolveClanTag("ABC", []);
|
||||
expect(result.dropped).toBe(true);
|
||||
expect(result).toEqual({ tag: "ABC", dropped: false });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -152,15 +152,15 @@ describe("checkClanTagOwnership", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects on an inconclusive existence check", async () => {
|
||||
it("fails open on an inconclusive existence check (API unavailable)", async () => {
|
||||
vi.mocked(getUserMe).mockResolvedValue(false);
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn(() => Promise.resolve(status(503))),
|
||||
);
|
||||
await expect(checkClanTagOwnership("ABC")).resolves.toEqual({
|
||||
tag: null,
|
||||
error: "username.tag_check_failed",
|
||||
tag: "ABC",
|
||||
error: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user