94 lines
3.5 KiB
TypeScript
94 lines
3.5 KiB
TypeScript
import { fail, redirect } from '@sveltejs/kit';
|
|
import { randomUUID } from 'node:crypto';
|
|
import { getSessionUser } from '$lib/server/auth/session';
|
|
import { getPermissions } from '$lib/server/auth/authorization';
|
|
import { getDatabase } from '$lib/server/database';
|
|
import {
|
|
CONTRIBUTOR_GUIDELINES_VERSION,
|
|
getContributorMode,
|
|
} from '$lib/server/contributor-mode';
|
|
import { recordIsacAudit } from '$lib/server/audit';
|
|
import type { Actions, PageServerLoad } from './$types';
|
|
|
|
const safeReturn = (value: FormDataEntryValue | null) => {
|
|
const path = String(value ?? '/isac/attributes');
|
|
return path.startsWith('/isac/') && !path.startsWith('//')
|
|
? path
|
|
: '/isac/attributes';
|
|
};
|
|
|
|
export const load: PageServerLoad = async ({ cookies, url }) => {
|
|
const user = await getSessionUser(cookies);
|
|
if (!user) redirect(303, '/sign-in');
|
|
const permissions = await getPermissions(user);
|
|
const eligible =
|
|
permissions.includes('*') || permissions.includes('data.propose');
|
|
if (!eligible) redirect(303, '/isac/attributes');
|
|
return {
|
|
contributorMode: await getContributorMode(user.id),
|
|
returnTo: safeReturn(url.searchParams.get('returnTo')),
|
|
};
|
|
};
|
|
|
|
export const actions: Actions = {
|
|
enable: async ({ cookies, request }) => {
|
|
const user = await getSessionUser(cookies);
|
|
if (!user) redirect(303, '/sign-in');
|
|
const permissions = await getPermissions(user);
|
|
if (!permissions.includes('*') && !permissions.includes('data.propose'))
|
|
return fail(403, {
|
|
contributorError: 'This account is not eligible to contribute data.',
|
|
});
|
|
const form = await request.formData();
|
|
if (form.get('acceptGuidelines') !== 'on')
|
|
return fail(400, {
|
|
contributorError:
|
|
'Accept the contributor guidelines to enable contributor mode.',
|
|
});
|
|
const returnTo = safeReturn(form.get('returnTo'));
|
|
const database = await getDatabase();
|
|
const before = await getContributorMode(user.id);
|
|
const now = new Date().toISOString();
|
|
await (
|
|
await database.prepare(`INSERT INTO contributor_agreements(user_id,guidelines_version,accepted_at,enabled,enabled_at,disabled_at)
|
|
VALUES(?,?,?,1,?,NULL)
|
|
ON CONFLICT(user_id) DO UPDATE SET guidelines_version=excluded.guidelines_version,accepted_at=excluded.accepted_at,
|
|
enabled=1,enabled_at=excluded.enabled_at,disabled_at=NULL`)
|
|
).run(user.id, CONTRIBUTOR_GUIDELINES_VERSION, now, now);
|
|
await recordIsacAudit({
|
|
actorId: user.id,
|
|
category: 'data_moderation',
|
|
action: before.accepted
|
|
? 'contributor.enabled'
|
|
: 'contributor.guidelines_accepted',
|
|
entityId: user.id,
|
|
before,
|
|
after: await getContributorMode(user.id),
|
|
});
|
|
redirect(303, returnTo);
|
|
},
|
|
disable: async ({ cookies, request }) => {
|
|
const user = await getSessionUser(cookies);
|
|
if (!user) redirect(303, '/sign-in');
|
|
const returnTo = safeReturn((await request.formData()).get('returnTo'));
|
|
const database = await getDatabase();
|
|
const before = await getContributorMode(user.id);
|
|
if (before.enabled) {
|
|
await (
|
|
await database.prepare(
|
|
'UPDATE contributor_agreements SET enabled=0,disabled_at=? WHERE user_id=?',
|
|
)
|
|
).run(new Date().toISOString(), user.id);
|
|
await recordIsacAudit({
|
|
actorId: user.id,
|
|
category: 'data_moderation',
|
|
action: 'contributor.disabled',
|
|
entityId: user.id,
|
|
before,
|
|
after: await getContributorMode(user.id),
|
|
});
|
|
}
|
|
redirect(303, returnTo);
|
|
},
|
|
};
|