feat(portal): add SSR operations and exclusive groups
This commit is contained in:
@@ -111,8 +111,8 @@ export function hashToken(token: string) {
|
||||
return createHash("sha256").update(token).digest("hex");
|
||||
}
|
||||
|
||||
export function enabledAccessGroup<T extends { accessEnabled: boolean }>(assignedGroups: T[]) {
|
||||
return assignedGroups.find((group) => group.accessEnabled) ?? null;
|
||||
export function resolveEffectiveGroup<T>(explicitGroup: T | null, defaultGroup: T | null) {
|
||||
return explicitGroup ?? defaultGroup;
|
||||
}
|
||||
|
||||
export function verifyHashedToken(providedToken: string, expectedHash: string) {
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { enabledAccessGroup } from "../src/index";
|
||||
import { resolveEffectiveGroup } from "../src/index";
|
||||
|
||||
describe("group-based admission", () => {
|
||||
it("denies default-off users and allows access when any assigned group is enabled", () => {
|
||||
expect(enabledAccessGroup([{ name: "everyone", accessEnabled: false }])).toBeNull();
|
||||
expect(enabledAccessGroup([
|
||||
{ name: "everyone", accessEnabled: false },
|
||||
{ name: "ops", accessEnabled: true },
|
||||
])).toEqual({ name: "ops", accessEnabled: true });
|
||||
const everyone = { name: "everyone", accessEnabled: false };
|
||||
|
||||
it("uses the default group only when a user has no explicit assignment", () => {
|
||||
expect(resolveEffectiveGroup(null, everyone)).toEqual(everyone);
|
||||
expect(resolveEffectiveGroup({ name: "limited", accessEnabled: true }, everyone)).toEqual({
|
||||
name: "limited",
|
||||
accessEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("does not combine default and explicitly assigned group access", () => {
|
||||
const enabledDefault = { name: "everyone", accessEnabled: true };
|
||||
const limited = { name: "limited", accessEnabled: false };
|
||||
expect(resolveEffectiveGroup(limited, enabledDefault)?.accessEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
DROP INDEX "user_group_memberships_user_group_uidx";--> statement-breakpoint
|
||||
DELETE FROM "user_group_memberships"
|
||||
WHERE ctid IN (
|
||||
SELECT ctid
|
||||
FROM (
|
||||
SELECT ctid, row_number() OVER (PARTITION BY "user_id" ORDER BY "created_at" DESC, "group_id") AS assignment_rank
|
||||
FROM "user_group_memberships"
|
||||
) ranked_assignments
|
||||
WHERE assignment_rank > 1
|
||||
);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "user_group_memberships_user_uidx" ON "user_group_memberships" USING btree ("user_id");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,13 @@
|
||||
"when": 1785623198008,
|
||||
"tag": "0002_simple_queen_noir",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1785625186545,
|
||||
"tag": "0003_smiling_silver_samurai",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -91,7 +91,7 @@ export const userGroupMemberships = pgTable(
|
||||
createdAt: createdAt(),
|
||||
},
|
||||
(table) => [
|
||||
uniqueIndex("user_group_memberships_user_group_uidx").on(table.userId, table.groupId),
|
||||
uniqueIndex("user_group_memberships_user_uidx").on(table.userId),
|
||||
index("user_group_memberships_group_idx").on(table.groupId),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -43,7 +43,7 @@ export function formatManagedDiscordNickname(
|
||||
minecraftUsername: string | null,
|
||||
) {
|
||||
if (minecraftUsername) return formatDiscordNickname(firstName, minecraftUsername);
|
||||
return [...firstName.trim()].slice(0, DISCORD_NICKNAME_LIMIT).join("").trimEnd();
|
||||
return formatDiscordNickname(firstName, "TBD");
|
||||
}
|
||||
|
||||
export interface DiscordGuildIdentity {
|
||||
|
||||
@@ -28,8 +28,9 @@ describe("Java Edition profiles", () => {
|
||||
expect(formatDiscordNickname("Sam", "Notch")).toBe("Sam (Notch)");
|
||||
});
|
||||
|
||||
it("falls back to the user's name when an admin removes their final account", () => {
|
||||
expect(formatManagedDiscordNickname("Alexandria Catherine", null)).toBe("Alexandria Catherine");
|
||||
expect(formatManagedDiscordNickname("A name that is definitely longer than Discord allows", null)).toHaveLength(32);
|
||||
it("marks the Discord nickname TBD when the user has no Minecraft account", () => {
|
||||
expect(formatManagedDiscordNickname("Alexandria Catherine", null)).toBe("Alexandria Catherine (TBD)");
|
||||
expect(formatManagedDiscordNickname("A name that is definitely longer than Discord allows", null).length).toBeLessThanOrEqual(32);
|
||||
expect(formatManagedDiscordNickname("A name that is definitely longer than Discord allows", null)).toMatch(/ \(TBD\)$/);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user