import {describe, expect, it, beforeEach} from 'vitest'; import * as CredentialService from '../../src/models/calendar/events/credentials.service.js'; /** * The public calendar is read anonymously by nachklang.art to show the next * upcoming event. That is a load-bearing property, not an accident: the step 4 * cutover moved every signed-in path onto session cookies and left these shared * passwords behind only for iCal subscriptions, and the failure mode of getting * it wrong is the public website silently losing its events feed. * * So this pins both halves: public needs nothing, and the restricted calendars * still need something. */ describe('hasAccess', () => { beforeEach(() => { process.env.MEMBER_CREDENTIAL = 'member-secret'; process.env.CHOIR_CREDENTIAL = 'choir-secret'; process.env.MANAGEMENT_CREDENTIAL = 'management-secret'; }); it('lets anyone read the public calendar with no password at all', async () => { await expect(CredentialService.hasAccess('public', '')).resolves.toBe(true); }); it.each([ ['members', 'member-secret'], ['choir', 'choir-secret'], ['management', 'management-secret'], ['birthdays', 'choir-secret'] ])('refuses %s without the credential and allows it with one', async (calendar, secret) => { await expect(CredentialService.hasAccess(calendar, '')).resolves.toBe(false); await expect(CredentialService.hasAccess(calendar, 'wrong')).resolves.toBe(false); await expect(CredentialService.hasAccess(calendar, secret)).resolves.toBe(true); }); it('refuses an unknown calendar outright', async () => { await expect(CredentialService.hasAccess('nope', 'member-secret')).resolves.toBe(false); }); it('refuses a calendar whose credential is not configured', async () => { // An unset MEMBER_CREDENTIAL must not become "any password works", and in // particular must not become "an absent password works". delete process.env.MEMBER_CREDENTIAL; await expect(CredentialService.hasAccess('members', '')).resolves.toBe(false); await expect(CredentialService.hasAccess('members', undefined as any)).resolves.toBe(false); }); });