Fix Super admins being blocked from editing proclamations

This commit is contained in:
NeilClack
2026-09-10 14:50:08 -05:00
parent 9cd5397395
commit 9de0e2e25a
2 changed files with 37 additions and 5 deletions
@@ -13,8 +13,16 @@ const ProclamationSchema = z.object({
content: z.string().optional().default('')
});
function isSuper(locals: App.Locals): boolean {
return ((locals.user as { roleId?: number } | null)?.roleId ?? 4) <= 1;
async function isSuper(locals: App.Locals): Promise<boolean> {
if (!locals.user?.id) return false;
// The Better Auth session user does not include `roleId`, so read the
// current role from the database.
const user = await prisma.user.findUnique({
where: { id: locals.user.id },
select: { roleId: true }
});
return (user?.roleId ?? 4) <= 1;
}
export const load: PageServerLoad = async ({ locals }) => {
@@ -40,7 +48,7 @@ export const load: PageServerLoad = async ({ locals }) => {
const records = proclamations as unknown as Record<string, unknown>[];
// Strip content from non-Super users
if (!isSuper(locals)) {
if (!(await isSuper(locals))) {
for (const record of records) {
delete record.content;
}
@@ -55,7 +63,7 @@ export const actions = {
return { success: false, action: 'upsert', error: 'Unauthorized' };
}
if (!isSuper(locals)) {
if (!(await isSuper(locals))) {
return {
success: false,
action: 'upsert',
@@ -98,7 +106,7 @@ export const actions = {
return { success: true, action: 'upsert' };
},
delete: async ({ request, locals }) => {
if (!isSuper(locals)) {
if (!(await isSuper(locals))) {
return {
success: false,
action: 'delete',
@@ -18,6 +18,9 @@ vi.mock('$lib/db', () => ({
},
proclamationGroup: {
findMany: vi.fn()
},
user: {
findUnique: vi.fn()
}
}
}));
@@ -33,6 +36,7 @@ const mockProclamationDelete = prisma.proclamation.delete as ReturnType<typeof v
const mockFreqFindMany = prisma.solfeggioFrequency.findMany as ReturnType<typeof vi.fn>;
const mockCatFindMany = prisma.proclamationCategory.findMany as ReturnType<typeof vi.fn>;
const mockGroupFindMany = prisma.proclamationGroup.findMany as ReturnType<typeof vi.fn>;
const mockUserFindUnique = prisma.user.findUnique as ReturnType<typeof vi.fn>;
const frequencies = [{ id: 1, name: 'UT', value: 396 }];
const categories = [{ id: 1, name: 'Healing' }];
@@ -52,6 +56,8 @@ function validRequest(overrides: Record<string, string> = {}) {
describe('proclamations admin page server', () => {
beforeEach(() => {
vi.clearAllMocks();
// Default the caller to SUPER (1); override per test as needed.
mockUserFindUnique.mockResolvedValue({ roleId: 1 });
});
describe('load', () => {
@@ -68,6 +74,7 @@ describe('proclamations admin page server', () => {
});
it('strips content for non-Super users', async () => {
mockUserFindUnique.mockResolvedValue({ roleId: 4 });
const locals = createLocals(mockUser({ roleId: 4 }) as any);
const result = await load({ locals } as any);
@@ -109,6 +116,7 @@ describe('proclamations admin page server', () => {
});
it('rejects non-Super users', async () => {
mockUserFindUnique.mockResolvedValue({ roleId: 4 });
const locals = createLocals(mockUser({ roleId: 4 }) as any);
const req = createFormRequest({ name: 'test' });
@@ -149,6 +157,21 @@ describe('proclamations admin page server', () => {
});
});
it('allows a Super user whose session user has no roleId', async () => {
mockProclamationCreate.mockResolvedValue({ id: 'p1' });
// The real Better Auth session user does not carry `roleId`; the
// action must look the role up in the database instead.
const locals = createLocals(mockUser({ roleId: null }) as any);
const result = await actions.upsert({ request: validRequest(), locals } as any);
expect(result).toEqual({ success: true, action: 'upsert' });
expect(mockUserFindUnique).toHaveBeenCalledWith({
where: { id: 'user-1' },
select: { roleId: true }
});
});
it('updates an existing proclamation for a Super user', async () => {
mockProclamationFindUnique.mockResolvedValue(mockProclamation());
mockProclamationUpdate.mockResolvedValue({});
@@ -200,6 +223,7 @@ describe('proclamations admin page server', () => {
describe('delete action', () => {
it('rejects non-Super users', async () => {
mockUserFindUnique.mockResolvedValue({ roleId: 4 });
const locals = createLocals(mockUser({ roleId: 4 }) as any);
const req = createFormRequest({ id: '1' });