WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto

feat(web): add canManageRoles session helper (ATB-43)

+51 -1
+42 -1
apps/web/src/lib/__tests__/session.test.ts
··· 1 1 import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; 2 - import { getSession, getSessionWithPermissions, canLockTopics, canModeratePosts, canBanUsers, hasAnyAdminPermission, canManageMembers, canManageCategories, canViewModLog } from "../session.js"; 2 + import { getSession, getSessionWithPermissions, canLockTopics, canModeratePosts, canBanUsers, hasAnyAdminPermission, canManageMembers, canManageCategories, canViewModLog, canManageRoles } from "../session.js"; 3 + import type { WebSessionWithPermissions } from "../session.js"; 3 4 import { logger } from "../logger.js"; 4 5 5 6 vi.mock("../logger.js", () => ({ ··· 402 403 it("returns false for user with only an unrelated permission", () => 403 404 expect(hasAnyAdminPermission(makeSinglePermSession("space.atbb.permission.someOtherThing"))).toBe(false)); 404 405 }); 406 + 407 + describe("canManageRoles", () => { 408 + it("returns false for unauthenticated session", () => { 409 + const auth: WebSessionWithPermissions = { 410 + authenticated: false, 411 + permissions: new Set(), 412 + }; 413 + expect(canManageRoles(auth)).toBe(false); 414 + }); 415 + 416 + it("returns false when authenticated but missing manageRoles", () => { 417 + const auth: WebSessionWithPermissions = { 418 + authenticated: true, 419 + did: "did:plc:x", 420 + handle: "x.bsky.social", 421 + permissions: new Set(["space.atbb.permission.manageMembers"]), 422 + }; 423 + expect(canManageRoles(auth)).toBe(false); 424 + }); 425 + 426 + it("returns true with manageRoles permission", () => { 427 + const auth: WebSessionWithPermissions = { 428 + authenticated: true, 429 + did: "did:plc:x", 430 + handle: "x.bsky.social", 431 + permissions: new Set(["space.atbb.permission.manageRoles"]), 432 + }; 433 + expect(canManageRoles(auth)).toBe(true); 434 + }); 435 + 436 + it("returns true with wildcard (*) permission", () => { 437 + const auth: WebSessionWithPermissions = { 438 + authenticated: true, 439 + did: "did:plc:x", 440 + handle: "x.bsky.social", 441 + permissions: new Set(["*"]), 442 + }; 443 + expect(canManageRoles(auth)).toBe(true); 444 + }); 445 + });
+9
apps/web/src/lib/session.ts
··· 197 197 auth.permissions.has("*")) 198 198 ); 199 199 } 200 + 201 + /** Returns true if the session grants permission to assign member roles. */ 202 + export function canManageRoles(auth: WebSessionWithPermissions): boolean { 203 + return ( 204 + auth.authenticated && 205 + (auth.permissions.has("space.atbb.permission.manageRoles") || 206 + auth.permissions.has("*")) 207 + ); 208 + }