Merge branch 'develop' of https://github.com/NodeBB/NodeBB into develop

This commit is contained in:
Barış Soner Uşaklı
2026-02-26 14:42:07 -05:00
64 changed files with 804 additions and 351 deletions

View File

@@ -14,6 +14,7 @@ const adminController = {
groups: require('./admin/groups'),
digest: require('./admin/digest'),
appearance: require('./admin/appearance'),
federation: require('./admin/federation'),
extend: {
widgets: require('./admin/widgets'),
rewards: require('./admin/rewards'),

View File

@@ -0,0 +1,43 @@
'use strict';
const activitypub = require('../../activitypub');
const federationController = module.exports;
federationController.general = function (req, res) {
res.render(`admin/federation/general`, {
title: '[[admin/menu:federation/general]]',
});
};
federationController.rules = async function (req, res) {
const rules = await activitypub.rules.list();
res.render(`admin/federation/rules`, {
title: '[[admin/menu:federation/rules]]',
rules,
hideSave: true,
});
};
federationController.relays = async function (req, res) {
const relays = await activitypub.relays.list();
res.render(`admin/federation/relays`, {
title: '[[admin/menu:federation/relays]]',
relays,
hideSave: true,
});
};
federationController.pruning = function (req, res) {
res.render(`admin/federation/pruning`, {
title: '[[admin/menu:federation/pruning]]',
});
};
federationController.safety = function (req, res) {
res.render(`admin/federation/safety`, {
title: '[[admin/menu:federation/safety]]',
});
};

View File

@@ -52,6 +52,12 @@ module.exports = function (app, name, middleware, controllers) {
helpers.setupAdminPageRoute(app, `/${name}/settings/web-crawler`, middlewares, controllers.admin.settings.webCrawler);
helpers.setupAdminPageRoute(app, `/${name}/settings/advanced`, middlewares, controllers.admin.settings.advanced);
helpers.setupAdminPageRoute(app, `/${name}/federation/general`, middlewares, controllers.admin.federation.general);
helpers.setupAdminPageRoute(app, `/${name}/federation/rules`, middlewares, controllers.admin.federation.rules);
helpers.setupAdminPageRoute(app, `/${name}/federation/relays`, middlewares, controllers.admin.federation.relays);
helpers.setupAdminPageRoute(app, `/${name}/federation/pruning`, middlewares, controllers.admin.federation.pruning);
helpers.setupAdminPageRoute(app, `/${name}/federation/safety`, middlewares, controllers.admin.federation.safety);
helpers.setupAdminPageRoute(app, `/${name}/appearance/themes`, middlewares, controllers.admin.appearance.themes);
helpers.setupAdminPageRoute(app, `/${name}/appearance/skins`, middlewares, controllers.admin.appearance.skins);
helpers.setupAdminPageRoute(app, `/${name}/appearance/customise`, middlewares, controllers.admin.appearance.customise);

View File

@@ -0,0 +1,49 @@
<div class="acp-page-container">
<!-- IMPORT admin/partials/settings/header.tpl -->
<div class="row settings m-0">
<div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
<p class="lead">[[admin/settings/activitypub:intro-lead]]</p>
<p>[[admin/settings/activitypub:intro-body]]</p>
<hr />
<div id="general" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:general]]</h5>
<form>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" data-field="activitypubEnabled">
<label class="form-check-label">[[admin/settings/activitypub:enabled]]</label>
<p class="form-text">[[admin/settings/activitypub:enabled-help]]</p>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" data-field="activitypubAllowLoopback">
<label class="form-check-label">[[admin/settings/activitypub:allowLoopback]]</label>
<p class="form-text">[[admin/settings/activitypub:allowLoopback-help]]</p>
</div>
</form>
</div>
<div id="probe" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:probe]]</h5>
<form>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" data-field="activitypubProbe">
<label class="form-check-label">[[admin/settings/activitypub:probe-enabled]]</label>
<p class="form-text">[[admin/settings/activitypub:probe-enabled-help]]</p>
</div>
<div class="mb-3">
<label class="form-label" for="activitypubProbeTimeout">[[admin/settings/activitypub:probe-timeout]]</label>
<input type="number" id="activitypubProbeTimeout" name="activitypubProbeTimeout" data-field="activitypubProbeTimeout" title="[[admin/settings/activitypub:probe-timeout]]" class="form-control" />
<div class="form-text">
[[admin/settings/activitypub:probe-timeout-help]]
</div>
</div>
</form>
</div>
</div>
<!-- IMPORT admin/partials/settings/toc.tpl -->
</div>
</div>

View File

@@ -0,0 +1,28 @@
<div class="acp-page-container">
<!-- IMPORT admin/partials/settings/header.tpl -->
<div class="row settings m-0">
<div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
<div id="pruning" class="mb-4">
<form>
<div class="mb-3">
<label class="form-label" for="activitypubContentPruneDays">[[admin/settings/activitypub:content-pruning]]</label>
<input type="number" id="activitypubContentPruneDays" name="activitypubContentPruneDays" data-field="activitypubContentPruneDays" title="[[admin/settings/activitypub:content-pruning]]" class="form-control" />
<div class="form-text">
[[admin/settings/activitypub:content-pruning-help]]
</div>
</div>
<div class="mb-3">
<label class="form-label" for="activitypubUserPruneDays">[[admin/settings/activitypub:user-pruning]]</label>
<input type="number" id="activitypubUserPruneDays" name="activitypubUserPruneDays" data-field="activitypubUserPruneDays" title="[[admin/settings/activitypub:user-pruning]]" class="form-control" />
<div class="form-text">
[[admin/settings/activitypub:user-pruning-help]]
</div>
</div>
</form>
</div>
</div>
<!-- IMPORT admin/partials/settings/toc.tpl -->
</div>
</div>

View File

@@ -0,0 +1,39 @@
<div class="acp-page-container">
<!-- IMPORT admin/partials/settings/header.tpl -->
<div class="row settings m-0">
<div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
<div id="relays" class="mb-4">
<p class="lead">[[admin/settings/activitypub:relays.intro]]</p>
<p class="text-warning">[[admin/settings/activitypub:relays.warning]]</p>
<div class="mb-3">
<table class="table table-striped" id="relays">
<thead>
<th>[[admin/settings/activitypub:relays.relay]]</th>
<th>[[admin/settings/activitypub:relays.state]]</th>
<th></th>
</thead>
<tbody>
{{{ each relays }}}
<tr data-url="{./url}">
<td>{./url}</td>
<td>{./label}</td>
<td><a href="#" data-action="relays.remove"><i class="fa fa-trash link-danger"></i></a></td>
</tr>
{{{ end }}}
</tbody>
<tfoot>
<tr>
<td colspan="3">
<button class="btn btn-sm btn-primary" data-action="relays.add">[[admin/settings/activitypub:relays.add]]</button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<!-- IMPORT admin/partials/settings/toc.tpl -->
</div>
</div>

View File

@@ -0,0 +1,45 @@
<div class="acp-page-container">
<!-- IMPORT admin/partials/settings/header.tpl -->
<div class="row settings m-0">
<div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
<div id="rules" class="mb-4">
<p class="lead">[[admin/settings/activitypub:rules-intro]]</p>
<div class="mb-3">
<table class="table table-striped" id="rules">
<thead>
<th></th>
<th>[[admin/settings/activitypub:rules.type]]</th>
<th>[[admin/settings/activitypub:rules.value]]</th>
<th>[[admin/settings/activitypub:rules.cid]]</th>
<th></th>
</thead>
<tbody>
{{{ each rules }}}
<tr data-rid="{./rid}">
<td class="align-items-center" style="cursor: move;">
<i class="fa fa-grip-lines text-muted drag-handle"></i>
</td>
<td>{./type}</td>
<td>{./value}</td>
<td>{./cid}</td>
<td><a href="#" data-action="rules.delete"><i class="fa fa-trash link-danger"></i></a></td>
</tr>
{{{ end }}}
</tbody>
<tfoot>
<tr>
<td colspan="5">
<button class="btn btn-sm btn-primary" data-action="rules.add">[[admin/settings/activitypub:rules.add]]</button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<!-- IMPORT admin/partials/settings/toc.tpl -->
</div>
</div>

View File

@@ -0,0 +1,26 @@
<div class="acp-page-container">
<!-- IMPORT admin/partials/settings/header.tpl -->
<div class="row settings m-0">
<div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
<div id="server-filtering" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:server-filtering]]</h5>
<form>
<div class="mb-3">
<p>[[admin/settings/activitypub:server.filter-help]]</p>
<p>[[admin/settings/activitypub:server.filter-help-hostname]]</p>
<p>[[admin/settings/activitypub:count, {instanceCount}]]</p>
<label for="activitypubFilterList" class="form-label">Filtering list</label>
<textarea class="form-control" id="activitypubFilterList" data-field="activitypubFilterList" rows="10"></textarea>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="activitypubFilter" data-field="activitypubFilter" />
<label class="form-check-label" for="activitypubFilter">[[admin/settings/activitypub:server.filter-allow-list]]</label>
</div>
</form>
</div>
</div>
<!-- IMPORT admin/partials/settings/toc.tpl -->
</div>
</div>

View File

@@ -63,8 +63,8 @@
</div>
{{{ end }}}
<!-- settings menu -->
{{{ if user.privileges.admin:settings }}}
<!-- settings menu -->
<div class="d-flex flex-column">
<button class="btn btn-ghost btn-sm d-flex gap-2 align-items-center" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSettings" aria-expanded="true" aria-controls="collapseSettings">
<i class="fa fa-fw fa-sliders"></i>
@@ -86,7 +86,6 @@
<a class="btn btn-ghost btn-sm text-start" href="{relative_path}/admin/settings/pagination">[[admin/menu:settings/pagination]]</a>
<a class="btn btn-ghost btn-sm text-start" href="{relative_path}/admin/settings/notifications">[[admin/menu:settings/notifications]]</a>
<a class="btn btn-ghost btn-sm text-start" href="{relative_path}/admin/settings/api">[[admin/menu:settings/api]]</a>
<a class="btn btn-ghost btn-sm text-start" href="{relative_path}/admin/settings/activitypub">[[admin/menu:settings/activitypub]]</a>
<a class="btn btn-ghost btn-sm text-start" href="{relative_path}/admin/settings/cookies">[[admin/menu:settings/cookies]]</a>
<a class="btn btn-ghost btn-sm text-start" href="{relative_path}/admin/settings/web-crawler">[[admin/menu:settings/web-crawler]]</a>
<a class="btn btn-ghost btn-sm text-start" href="{relative_path}/admin/settings/advanced">[[admin/menu:settings/advanced]]</a>
@@ -95,6 +94,25 @@
</div>
<!-- federation menu -->
<div class="d-flex flex-column">
<button class="btn btn-ghost btn-sm d-flex gap-2 align-items-center" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFederation" aria-expanded="true" aria-controls="collapseFederation">
<i class="fa fa-fw fa-circle-nodes"></i>
<div class="flex-1 font-serif text-sm fw-semibold text-start">[[admin/menu:section-federation]]</div>
</button>
<div id="collapseFederation" class="accordion-collapse collapse" data-bs-parent="#accordionACP">
<div class="accordion-body p-0 d-grid">
<a class="btn btn-ghost btn-sm text-start" id="federation-general" href="{relative_path}/admin/federation/general">[[admin/menu:federation/general]]</a>
<a class="btn btn-ghost btn-sm text-start" id="federation-rules" href="{relative_path}/admin/federation/rules">[[admin/menu:federation/rules]]</a>
<a class="btn btn-ghost btn-sm text-start" id="federation-relays" href="{relative_path}/admin/federation/relays">[[admin/menu:federation/relays]]</a>
<a class="btn btn-ghost btn-sm text-start" id="federation-pruning" href="{relative_path}/admin/federation/pruning">[[admin/menu:federation/pruning]]</a>
<a class="btn btn-ghost btn-sm text-start" id="federation-safety" href="{relative_path}/admin/federation/safety">[[admin/menu:federation/safety]]</a>
</div>
</div>
</div>
<!-- appearance menu -->
<div class="d-flex flex-column">
<button class="btn btn-ghost btn-sm d-flex gap-2 align-items-center" type="button" data-bs-toggle="collapse" data-bs-target="#collapseAppearance" aria-expanded="true" aria-controls="collapseAppearance">

View File

@@ -2,7 +2,9 @@
<div class="col-12 col-md-8 px-0 mb-1 mb-md-0">
<h4 class="fw-bold tracking-tight mb-0">{title}</h4>
</div>
{{{ if !hideSave }}}
<div class="col-12 col-md-4 px-0 px-md-3">
<button id="save" class="btn btn-primary btn-sm fw-semibold ff-secondary w-100 text-center text-nowrap">[[admin/admin:save-changes]]</button>
</div>
{{{ end }}}
</div>

View File

@@ -1,153 +0,0 @@
<div class="acp-page-container">
<!-- IMPORT admin/partials/settings/header.tpl -->
<div class="row settings m-0">
<div id="spy-container" class="col-12 col-md-8 px-0 mb-4" tabindex="0">
<p class="lead">[[admin/settings/activitypub:intro-lead]]</p>
<p>[[admin/settings/activitypub:intro-body]]</p>
<hr />
<div id="general" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:general]]</h5>
<form>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" data-field="activitypubEnabled">
<label class="form-check-label">[[admin/settings/activitypub:enabled]]</label>
<p class="form-text">[[admin/settings/activitypub:enabled-help]]</p>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" data-field="activitypubAllowLoopback">
<label class="form-check-label">[[admin/settings/activitypub:allowLoopback]]</label>
<p class="form-text">[[admin/settings/activitypub:allowLoopback-help]]</p>
</div>
</form>
</div>
<div id="probe" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:probe]]</h5>
<form>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" data-field="activitypubProbe">
<label class="form-check-label">[[admin/settings/activitypub:probe-enabled]]</label>
<p class="form-text">[[admin/settings/activitypub:probe-enabled-help]]</p>
</div>
<div class="mb-3">
<label class="form-label" for="activitypubProbeTimeout">[[admin/settings/activitypub:probe-timeout]]</label>
<input type="number" id="activitypubProbeTimeout" name="activitypubProbeTimeout" data-field="activitypubProbeTimeout" title="[[admin/settings/activitypub:probe-timeout]]" class="form-control" />
<div class="form-text">
[[admin/settings/activitypub:probe-timeout-help]]
</div>
</div>
</form>
</div>
<div id="rules" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:rules]]</h5>
<div class="mb-3">
<p>[[admin/settings/activitypub:rules-intro]]</p>
<table class="table table-striped" id="rules">
<thead>
<th></th>
<th>[[admin/settings/activitypub:rules.type]]</th>
<th>[[admin/settings/activitypub:rules.value]]</th>
<th>[[admin/settings/activitypub:rules.cid]]</th>
<th></th>
</thead>
<tbody>
{{{ each rules }}}
<tr data-rid="{./rid}">
<td class="align-items-center" style="cursor: move;">
<i class="fa fa-grip-lines text-muted drag-handle"></i>
</td>
<td>{./type}</td>
<td>{./value}</td>
<td>{./cid}</td>
<td><a href="#" data-action="rules.delete"><i class="fa fa-trash link-danger"></i></a></td>
</tr>
{{{ end }}}
</tbody>
<tfoot>
<tr>
<td colspan="5">
<button class="btn btn-sm btn-primary" data-action="rules.add">[[admin/settings/activitypub:rules.add]]</button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div id="relays" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:relays]]</h5>
<p>[[admin/settings/activitypub:relays.intro]]</p>
<p class="text-warning">[[admin/settings/activitypub:relays.warning]]</p>
<div class="mb-3">
<table class="table table-striped" id="relays">
<thead>
<th>[[admin/settings/activitypub:relays.relay]]</th>
<th>[[admin/settings/activitypub:relays.state]]</th>
<th></th>
</thead>
<tbody>
{{{ each relays }}}
<tr data-url="{./url}">
<td>{./url}</td>
<td>{./label}</td>
<td><a href="#" data-action="relays.remove"><i class="fa fa-trash link-danger"></i></a></td>
</tr>
{{{ end }}}
</tbody>
<tfoot>
<tr>
<td colspan="3">
<button class="btn btn-sm btn-primary" data-action="relays.add">[[admin/settings/activitypub:relays.add]]</button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div id="pruning" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:pruning]]</h5>
<form>
<div class="mb-3">
<label class="form-label" for="activitypubContentPruneDays">[[admin/settings/activitypub:content-pruning]]</label>
<input type="number" id="activitypubContentPruneDays" name="activitypubContentPruneDays" data-field="activitypubContentPruneDays" title="[[admin/settings/activitypub:content-pruning]]" class="form-control" />
<div class="form-text">
[[admin/settings/activitypub:content-pruning-help]]
</div>
</div>
<div class="mb-3">
<label class="form-label" for="activitypubUserPruneDays">[[admin/settings/activitypub:user-pruning]]</label>
<input type="number" id="activitypubUserPruneDays" name="activitypubUserPruneDays" data-field="activitypubUserPruneDays" title="[[admin/settings/activitypub:user-pruning]]" class="form-control" />
<div class="form-text">
[[admin/settings/activitypub:user-pruning-help]]
</div>
</div>
</form>
</div>
<div id="server-filtering" class="mb-4">
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/activitypub:server-filtering]]</h5>
<form>
<div class="mb-3">
<p>[[admin/settings/activitypub:server.filter-help]]</p>
<p>[[admin/settings/activitypub:server.filter-help-hostname]]</p>
<p>[[admin/settings/activitypub:count, {instanceCount}]]</p>
<label for="activitypubFilterList" class="form-label">Filtering list</label>
<textarea class="form-control" id="activitypubFilterList" data-field="activitypubFilterList" rows="10"></textarea>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="activitypubFilter" data-field="activitypubFilter" />
<label class="form-check-label" for="activitypubFilter">[[admin/settings/activitypub:server.filter-allow-list]]</label>
</div>
</form>
</div>
</div>
<!-- IMPORT admin/partials/settings/toc.tpl -->
</div>
</div>