feat: add settings GET/POST controller
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Settings controller — admin page for ActivityPub plugin configuration.
|
||||
*
|
||||
* GET: loads settings from ap_settings, renders form with defaults
|
||||
* POST: validates, saves settings, redirects with success message
|
||||
*/
|
||||
import { getSettings, saveSettings, DEFAULTS } from "../settings.js";
|
||||
import { getToken, validateToken } from "../csrf.js";
|
||||
|
||||
export function settingsGetController(mountPath) {
|
||||
return async (request, response, next) => {
|
||||
try {
|
||||
const { application } = request.app.locals;
|
||||
const settings = await getSettings(application.collections);
|
||||
|
||||
response.render("activitypub-settings", {
|
||||
title: response.locals.__("activitypub.settings.title"),
|
||||
settings,
|
||||
defaults: DEFAULTS,
|
||||
mountPath,
|
||||
saved: request.query.saved === "true",
|
||||
csrfToken: getToken(request.session),
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function settingsPostController(mountPath) {
|
||||
return async (request, response, next) => {
|
||||
try {
|
||||
if (!validateToken(request)) {
|
||||
return response.status(403).render("error", {
|
||||
title: "Error",
|
||||
content: "Invalid CSRF token",
|
||||
});
|
||||
}
|
||||
|
||||
const { application } = request.app.locals;
|
||||
const body = request.body;
|
||||
|
||||
const settings = {
|
||||
// Instance & Client API
|
||||
instanceLanguages: (body.instanceLanguages || "en")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean),
|
||||
maxCharacters:
|
||||
parseInt(body.maxCharacters, 10) || DEFAULTS.maxCharacters,
|
||||
maxMediaAttachments:
|
||||
parseInt(body.maxMediaAttachments, 10) || DEFAULTS.maxMediaAttachments,
|
||||
defaultVisibility: body.defaultVisibility || DEFAULTS.defaultVisibility,
|
||||
defaultLanguage: (body.defaultLanguage || DEFAULTS.defaultLanguage).trim(),
|
||||
|
||||
// Federation & Delivery
|
||||
timelineRetention: parseInt(body.timelineRetention, 10) || 0,
|
||||
notificationRetentionDays:
|
||||
parseInt(body.notificationRetentionDays, 10) || 0,
|
||||
activityRetentionDays:
|
||||
parseInt(body.activityRetentionDays, 10) || 0,
|
||||
replyChainDepth:
|
||||
parseInt(body.replyChainDepth, 10) || DEFAULTS.replyChainDepth,
|
||||
broadcastBatchSize:
|
||||
parseInt(body.broadcastBatchSize, 10) || DEFAULTS.broadcastBatchSize,
|
||||
broadcastBatchDelay:
|
||||
parseInt(body.broadcastBatchDelay, 10) || DEFAULTS.broadcastBatchDelay,
|
||||
parallelWorkers:
|
||||
parseInt(body.parallelWorkers, 10) || DEFAULTS.parallelWorkers,
|
||||
logLevel: body.logLevel || DEFAULTS.logLevel,
|
||||
|
||||
// Migration
|
||||
refollowBatchSize:
|
||||
parseInt(body.refollowBatchSize, 10) || DEFAULTS.refollowBatchSize,
|
||||
refollowDelay:
|
||||
parseInt(body.refollowDelay, 10) || DEFAULTS.refollowDelay,
|
||||
refollowBatchDelay:
|
||||
parseInt(body.refollowBatchDelay, 10) || DEFAULTS.refollowBatchDelay,
|
||||
|
||||
// Security
|
||||
refreshTokenTtlDays:
|
||||
parseInt(body.refreshTokenTtlDays, 10) || DEFAULTS.refreshTokenTtlDays,
|
||||
};
|
||||
|
||||
await saveSettings(application.collections, settings);
|
||||
|
||||
response.redirect(`${mountPath}/admin/settings?saved=true`);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user