New option to use and configure Prosody mod_firewall WIP ():

* new setting
* new configuration screen for Peertube admins
* include the mod_firewall module
* load mod_firewall if enabled
* sys admin can disable the firewall config editing by creating a
  special file on the disk
* user documentation
This commit is contained in:
John Livingston 2024-08-12 18:17:31 +02:00
parent 481f265a44
commit 8e99199f29
No known key found for this signature in database
GPG Key ID: B17B5640CE66CDBC
76 changed files with 7577 additions and 300 deletions

@ -32,3 +32,7 @@ License: AGPL-3.0-only
Files: .github/PULL_REQUEST_TEMPLATE.md
Copyright: 2024 John Livingston <https://www.john-livingston.fr/>
License: AGPL-3.0-only
Files: prosody-modules/mod_firewall/*
Copyright: Prosody Community Modules <https://modules.prosody.im/mod_firewall>
License: MIT

@ -2,7 +2,9 @@
## 11.0.0 (Not Released Yet)
TODO: actions related to #144 and #145 must be added in the occupant list (waiting for some work on Converse to do this).
### Importante Notes
With the new [mod_firewall](https://livingston.frama.io/peertube-plugin-livechat/documentation/admin/mod_firewall/) feature, Peertube admins can write firewall rules for the Prosody server. These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory. Check the documentation for more information. This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin.
### New features
@ -11,6 +13,7 @@ TODO: actions related to #144 and #145 must be added in the occupant list (waiti
* #137: option to hide moderator name who made actions (kick, ban, message moderation, ...).
* #144: [moderator notes](https://livingston.frama.io/peertube-plugin-livechat/documentation/user/streamers/moderation_notes/).
* #145: action for moderators to find all messages from a given participant.
* #97: option to use and configure [mod_firewall](https://livingston.frama.io/peertube-plugin-livechat/documentation/admin/mod_firewall/) at the server level.
### Minor changes and fixes

@ -0,0 +1,94 @@
/*
* SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* stylelint-disable custom-property-pattern */
@use "sass:color";
@use "../../variables";
.peertube-plugin-livechat-admin-firewall {
h1 {
padding-top: 40px;
/* See Peertube sub-menu-h1 mixin */
font-size: 1.3rem;
border-bottom: 2px solid var(--greyBackgroundColor);
padding-bottom: 15px;
}
textarea[name^="_content_"] {
min-height: 10rem;
}
input[type="submit"],
input[type="reset"],
button[type="submit"],
button[type="reset"] {
// Peertube rounded-line-height-1-5 mixins
line-height: variables.$button-calc-line-height;
// Peertube peertube-button mixin
padding: 4px 13px;
border: 0;
font-weight: variables.$font-semibold;
border-radius: 3px !important;
text-align: center;
cursor: pointer;
font-size: variables.$button-font-size;
}
input[type="submit"],
button[type="submit"] {
// Peertube orange-button mixin
&,
&:active,
&:focus {
color: #fff;
background-color: var(--mainColor);
}
&:hover {
color: #fff;
background-color: var(--mainHoverColor);
}
&[disabled],
&.disabled {
cursor: default;
color: #fff;
background-color: var(--inputBorderColor);
}
}
input[type="reset"],
button[type="reset"] {
// Peertube grey-button mixin
background-color: var(--greyBackgroundColor);
color: var(--greyForegroundColor);
&:hover,
&:active,
&:focus,
&[disabled],
&.disabled {
color: var(--greyForegroundColor);
background-color: var(--greySecondaryBackgroundColor);
}
&[disabled],
&.disabled {
cursor: default;
}
}
.peertube-livechat-admin-firewall-col-name {
width: 25%;
}
.peertube-livechat-admin-firewall-col-content {
width: 65%;
}
}

@ -9,4 +9,5 @@
@use "elements/index";
@use "video";
@use "configuration/configuration";
@use "admin/firewall/firewall";
@use "list-rooms/list-rooms.scss";

@ -135,3 +135,11 @@ declare const LOC_MODERATION_DELAY: string
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_MODERATION_DELAY_DESC: string
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_ANONYMIZE_MODERATION_LABEL: string
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_ANONYMIZE_MODERATION_DESC: string
declare const LOC_PROSODY_FIREWALL_CONFIGURATION: string
declare const LOC_PROSODY_FIREWALL_CONFIGURATION_HELP: string
declare const LOC_PROSODY_FIREWALL_DISABLED_WARNING: string
declare const LOC_PROSODY_FIREWALL_FILE_ENABLED: string
declare const LOC_PROSODY_FIREWALL_NAME: string
declare const LOC_PROSODY_FIREWALL_NAME_DESC: string
declare const LOC_PROSODY_FIREWALL_CONTENT: string

@ -270,6 +270,8 @@ function register (clientOptions: RegisterClientOptions): void {
return !(options.formValues['chat-all-lives'] === true && options.formValues['chat-per-live-video'] === true)
case 'auto-ban-anonymous-ip':
return options.formValues['chat-no-anonymous'] !== false
case 'prosody-firewall-configure-button':
return options.formValues['prosody-firewall-enabled'] !== true
}
if (name?.startsWith('external-auth-')) {

@ -8,6 +8,7 @@ import { registerConfiguration } from './common/configuration/register'
import { registerVideoWatch } from './common/videowatch/register'
import { registerRoom } from './common/room/register'
import { initPtContext } from './common/lib/contexts/peertube'
import { registerAdminFirewall } from './common/admin/firewall/register'
import './common/lib/elements' // Import shared elements.
async function register (clientOptions: RegisterClientOptions): Promise<void> {
@ -69,7 +70,8 @@ async function register (clientOptions: RegisterClientOptions): Promise<void> {
await Promise.all([
registerVideoWatch(),
registerRoom(clientOptions),
registerConfiguration(clientOptions)
registerConfiguration(clientOptions),
registerAdminFirewall(clientOptions)
])
}

@ -0,0 +1,131 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { AdminFirewallConfiguration } from 'shared/lib/types'
import { AdminFirewallService } from '../services/admin-firewall'
import { LivechatElement } from '../../../lib/elements/livechat'
import { ValidationError, ValidationErrorType } from '../../../lib/models/validation'
import { tplAdminFirewall } from '../templates/admin-firewall'
import { TemplateResult, html, nothing } from 'lit'
import { customElement, state } from 'lit/decorators.js'
import { Task } from '@lit/task'
@customElement('livechat-admin-firewall')
export class AdminFirewallElement extends LivechatElement {
private _adminFirewallService?: AdminFirewallService
@state()
public firewallConfiguration?: AdminFirewallConfiguration
@state()
public validationError?: ValidationError
@state()
public actionDisabled: boolean = false
private _asyncTaskRender: Task
constructor () {
super()
this._asyncTaskRender = this._initTask()
}
protected _initTask (): Task {
return new Task(this, {
task: async () => {
this._adminFirewallService = new AdminFirewallService(this.ptOptions)
this.firewallConfiguration = await this._adminFirewallService.fetchConfiguration()
this.actionDisabled = false // in case of reset
},
args: () => []
})
}
/**
* Resets the form by reloading data from backend.
*/
public async reset (event?: Event): Promise<void> {
event?.preventDefault()
this.actionDisabled = true
this._asyncTaskRender = this._initTask()
this.requestUpdate()
}
/**
* Resets the validation errors.
* @param ev the vent
*/
public resetValidation (_ev?: Event): void {
if (this.validationError) {
this.validationError = undefined
this.requestUpdate('_validationError')
}
}
/**
* Saves the configuration.
* @param event event
*/
public readonly saveConfig = async (event?: Event): Promise<void> => {
event?.preventDefault()
if (!this.firewallConfiguration || !this._adminFirewallService) {
return
}
this.actionDisabled = true
this._adminFirewallService.saveConfiguration(this.firewallConfiguration)
.then((result: AdminFirewallConfiguration) => {
this.validationError = undefined
this.ptTranslate(LOC_SUCCESSFULLY_SAVED).then((msg) => {
this.ptNotifier.info(msg)
}, () => {})
this.firewallConfiguration = result
this.requestUpdate('firewallConfiguration')
this.requestUpdate('_validationError')
})
.catch(async (error: Error) => {
this.validationError = undefined
if (error instanceof ValidationError) {
this.validationError = error
}
this.logger.warn(`A validation error occurred in saving configuration. ${error.name}: ${error.message}`)
this.ptNotifier.error(
error.message
? error.message
: await this.ptTranslate(LOC_ERROR)
)
this.requestUpdate('_validationError')
})
.finally(() => {
this.actionDisabled = false
})
}
public readonly getInputValidationClass = (propertyName: string): { [key: string]: boolean } => {
const validationErrorTypes: ValidationErrorType[] | undefined =
this.validationError?.properties[`${propertyName}`]
return validationErrorTypes ? (validationErrorTypes.length ? { 'is-invalid': true } : { 'is-valid': true }) : {}
}
public readonly renderFeedback = (feedbackId: string,
propertyName: string): TemplateResult | typeof nothing => {
const errorMessages: TemplateResult[] = []
const validationErrorTypes: ValidationErrorType[] | undefined =
this.validationError?.properties[`${propertyName}`] ?? undefined
// FIXME: this code is duplicated in dymamic table form
if (validationErrorTypes && validationErrorTypes.length !== 0) {
return html`<div id=${feedbackId} class="invalid-feedback">${errorMessages}</div>`
} else {
return nothing
}
}
protected override render = (): unknown => {
return this._asyncTaskRender.render({
pending: () => html`<livechat-spinner></livechat-spinner>`,
error: () => html`<livechat-error></livechat-error>`,
complete: () => tplAdminFirewall(this)
})
}
}

@ -0,0 +1,5 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import './admin-firewall'

@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
import { html, render } from 'lit'
import './elements' // Import all needed elements.
/**
* Registers stuff related to mod_firewall configuration.
* @param clientOptions Peertube client options
*/
async function registerAdminFirewall (clientOptions: RegisterClientOptions): Promise<void> {
const { registerClientRoute } = clientOptions
registerClientRoute({
route: 'livechat/admin/firewall',
onMount: async ({ rootEl }) => {
render(html`<livechat-admin-firewall .registerClientOptions=${clientOptions}></livechat-admin-firewall>`, rootEl)
}
})
}
export {
registerAdminFirewall
}

@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
import type { AdminFirewallConfiguration } from 'shared/lib/types'
import {
maxFirewallFileSize, maxFirewallNameLength, maxFirewallFiles, firewallNameRegexp
} from 'shared/lib/admin-firewall'
import { ValidationError, ValidationErrorType } from '../../../lib/models/validation'
import { getBaseRoute } from '../../../../utils/uri'
export class AdminFirewallService {
public _registerClientOptions: RegisterClientOptions
private readonly _headers: any = {}
constructor (registerClientOptions: RegisterClientOptions) {
this._registerClientOptions = registerClientOptions
this._headers = this._registerClientOptions.peertubeHelpers.getAuthHeader() ?? {}
this._headers['content-type'] = 'application/json;charset=UTF-8'
}
async validateConfiguration (adminFirewallConfiguration: AdminFirewallConfiguration): Promise<boolean> {
const propertiesError: ValidationError['properties'] = {}
if (adminFirewallConfiguration.files.length > maxFirewallFiles) {
const validationError = new ValidationError(
'AdminFirewallConfigurationValidationError',
await this._registerClientOptions.peertubeHelpers.translate(LOC_TOO_MANY_ENTRIES),
propertiesError
)
throw validationError
}
const seen = new Map<string, true>()
for (const [i, e] of adminFirewallConfiguration.files.entries()) {
propertiesError[`files.${i}.name`] = []
if (e.name === '') {
propertiesError[`files.${i}.name`].push(ValidationErrorType.Missing)
} else if (e.name.length > maxFirewallNameLength) {
propertiesError[`files.${i}.name`].push(ValidationErrorType.TooLong)
} else if (!firewallNameRegexp.test(e.name)) {
propertiesError[`files.${i}.name`].push(ValidationErrorType.WrongFormat)
} else if (seen.has(e.name)) {
propertiesError[`files.${i}.name`].push(ValidationErrorType.Duplicate)
} else {
seen.set(e.name, true)
}
propertiesError[`files.${i}.content`] = []
if (e.content.length > maxFirewallFileSize) {
propertiesError[`files.${i}.content`].push(ValidationErrorType.TooLong)
}
}
if (Object.values(propertiesError).find(e => e.length > 0)) {
const validationError = new ValidationError(
'AdminFirewallConfigurationValidationError',
await this._registerClientOptions.peertubeHelpers.translate(LOC_VALIDATION_ERROR),
propertiesError
)
throw validationError
}
return true
}
async saveConfiguration (
adminFirewallConfiguration: AdminFirewallConfiguration
): Promise<AdminFirewallConfiguration> {
if (!await this.validateConfiguration(adminFirewallConfiguration)) {
throw new Error('Invalid form data')
}
const response = await fetch(
getBaseRoute(this._registerClientOptions) + '/api/admin/firewall/',
{
method: 'POST',
headers: this._headers,
body: JSON.stringify(adminFirewallConfiguration)
}
)
if (!response.ok) {
throw new Error('Failed to save configuration.')
}
return response.json()
}
async fetchConfiguration (): Promise<AdminFirewallConfiguration> {
const response = await fetch(
getBaseRoute(this._registerClientOptions) + '/api/admin/firewall/',
{
method: 'GET',
headers: this._headers
}
)
if (!response.ok) {
throw new Error('Can\'t get firewall configuration.')
}
return response.json()
}
}

@ -0,0 +1,88 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { AdminFirewallElement } from '../elements/admin-firewall'
import type { TemplateResult } from 'lit'
import type { DynamicFormHeader, DynamicFormSchema } from '../../../lib/elements/dynamic-table-form'
import { maxFirewallFiles, maxFirewallNameLength, maxFirewallFileSize } from 'shared/lib/admin-firewall'
import { ptTr } from '../../../lib/directives/translation'
import { html } from 'lit'
export function tplAdminFirewall (el: AdminFirewallElement): TemplateResult {
const tableHeaderList: DynamicFormHeader = {
enabled: {
colName: ptTr(LOC_PROSODY_FIREWALL_FILE_ENABLED)
},
name: {
colName: ptTr(LOC_PROSODY_FIREWALL_NAME),
description: ptTr(LOC_PROSODY_FIREWALL_NAME_DESC),
headerClassList: ['peertube-livechat-admin-firewall-col-name']
},
content: {
colName: ptTr(LOC_PROSODY_FIREWALL_CONTENT),
headerClassList: ['peertube-livechat-admin-firewall-col-content']
}
}
const tableSchema: DynamicFormSchema = {
enabled: {
inputType: 'checkbox',
default: true
},
name: {
inputType: 'text',
default: '',
maxlength: maxFirewallNameLength
},
content: {
inputType: 'textarea',
default: '',
maxlength: maxFirewallFileSize
}
}
return html`
<div class="margin-content peertube-plugin-livechat-admin-firewall">
<h1>
${ptTr(LOC_PROSODY_FIREWALL_CONFIGURATION)}
</h1>
<p>
${ptTr(LOC_PROSODY_FIREWALL_CONFIGURATION_HELP, true)}
<livechat-help-button .page=${'documentation/admin/mod_firewall'}>
</livechat-help-button>
</p>
${
el.firewallConfiguration?.enabled
? ''
: html`<p class="peertube-plugin-livechat-warning">${ptTr(LOC_PROSODY_FIREWALL_DISABLED_WARNING, true)}</p>`
}
<form role="form" @submit=${el.saveConfig} @change=${el.resetValidation}>
<livechat-dynamic-table-form
.header=${tableHeaderList}
.schema=${tableSchema}
.maxLines=${maxFirewallFiles}
.validation=${el.validationError?.properties}
.validationPrefix=${'files'}
.rows=${el.firewallConfiguration?.files}
@update=${(e: CustomEvent) => {
el.resetValidation(e)
if (el.firewallConfiguration) {
el.firewallConfiguration.files = e.detail
el.requestUpdate('firewallConfiguration')
}
}
}
></livechat-dynamic-table-form>
<div class="form-group mt-5">
<button type="reset" @click=${el.reset} ?disabled=${el.actionDisabled}>
${ptTr(LOC_CANCEL)}
</button>
<button type="submit" ?disabled=${el.actionDisabled}>
${ptTr(LOC_SAVE)}
</button>
</div>
</form>
</div>`
}

@ -64,7 +64,7 @@ interface DynamicTableRowData {
interface DynamicFormHeaderCellData {
colName: TemplateResult | DirectiveResult
description: TemplateResult | DirectiveResult
description?: TemplateResult | DirectiveResult
headerClassList?: string[]
}
@ -236,7 +236,7 @@ export class DynamicTableFormElement extends LivechatElement {
classList.push(...headerCellData.headerClassList)
}
return html`<th scope="col" class=${classList.join(' ')}>
${headerCellData.description}
${headerCellData.description ?? ''}
</th>`
}

@ -31,7 +31,7 @@ CONVERSE_COMMIT="5017efb780973d704f237c478ba52b23d901e1bf"
CONVERSE_VERSION="livechat_converse_11"
CONVERSE_COMMIT="1625f9b6ee81fa9ebd8df5cba306bde478f1943b"
# 2024-08-06: including new getOccupantActionButtons hook (waiting for merge in Converse upstream)
CONVERSE_COMMIT="82f69c49f5e316180fb561c3796ef8ed9335bf1f"
CONVERSE_COMMIT="5b35bd31c7e26c1f5396cd65eef69293d8b388c1"
rootdir="$(pwd)"
src_dir="$rootdir/conversejs"

@ -614,3 +614,24 @@ moderator_note_original_nick: 'Nickname of the participant at the time of the no
search_occupant_message: 'Search all messages'
message_search: 'Message search'
message_search_original_nick: Nickname of the participant when the message was sent
prosody_firewall_label: 'Enable Prosody mod_firewall'
prosody_firewall_description: |
You can enable <a href="https://modules.prosody.im/mod_firewall" target="_blank">mod_firewall</a> on your Prosody server.
For more information, please check <a href="https://livingston.frama.io/peertube-plugin-livechat/documentation/admin/mod_firewall/" target="_blank">the documentation</a>.
prosody_firewall_configure_button: |
<a class="peertube-button-link orange-button" href="/p/livechat/admin/firewall" target="_blank">Configure mod_firewall</a>
prosody_firewall_configuration: Prosody mod_firewall configuration
prosody_firewall_configuration_help: |
Here you can configure Prosody <a href="https://modules.prosody.im/mod_firewall" target="_blank">mod_firewall</a> module.
You can create multiple configuration files bellow, and change their order.
Don't hesitate to share your configurations with the community (for example by adding some examples in the plugin documentation).
prosody_firewall_disabled_warning: |
Warning: mod_firewall is disabled in the livechat <a href="/admin/plugins/show/peertube-plugin-livechat" target="_blank">plugin settings</a>, you have to enable it if you want this configuration to be taken into account.
prosody_firewall_file_enabled: Enabled
prosody_firewall_name: Name
prosody_firewall_name_desc: |
Can only contain: alphanumerical characters, underscores and hyphens.
Scripts will be loaded in alphabetical order.
prosody_firewall_content: File content

@ -0,0 +1,820 @@
---
labels:
- 'Stage-Alpha'
summary: 'A rule-based stanza filtering module'
rockspec:
build:
modules:
mod_firewall.actions: actions.lib.lua
mod_firewall.conditions: conditions.lib.lua
mod_firewall.definitions: definitions.lib.lua
mod_firewall.marks: marks.lib.lua
mod_firewall.test: test.lib.lua
copy_directories:
- scripts
---
------------------------------------------------------------------------
**Note:** mod\_firewall is in its very early stages. This documentation
is liable to change, and some described functionality may be missing,
incomplete or contain bugs.
------------------------------------------------------------------------
Introduction
============
A firewall is an invaluable tool in the sysadmin's toolbox. However
while low-level firewalls such as iptables and pf are incredibly good at
what they do, they are generally not able to handle application-layer
rules.
The goal of mod\_firewall is to provide similar services at the XMPP
layer. Based on rule scripts it can efficiently block, bounce, drop,
forward, copy, redirect stanzas and more! Furthermore all rules can be
applied and updated dynamically at runtime without restarting the
server.
Details
=======
mod\_firewall loads one or more scripts, and compiles these to Lua code
that reacts to stanzas flowing through Prosody. The firewall script
syntax is unusual, but straightforward.
A firewall script is dominated by rules. Each rule has two parts:
conditions, and actions. When a stanza matches all of the conditions,
all of the actions are executed in order.
Here is a simple example to block stanzas from spammer@example.com:
FROM: spammer@example.com
DROP.
FROM is a condition, and DROP is an action. This is about as simple as
it gets. How about heading to the other extreme? Let's demonstrate
something more complex that mod\_firewall can do for you:
%ZONE myorganisation: staff.myorg.example, support.myorg.example
ENTERING: myorganisation
KIND: message
TIME: 12am-9am, 5pm-12am, Saturday, Sunday
REPLY=Sorry, I am afraid our office is closed at the moment. If you need assistance, please call our 24-hour support line on 123-456-789.
This rule will reply with a short message whenever someone tries to send
a message to someone at any of the hosts defined in the 'myorganisation'
outside of office hours.
Specifying rule sets
--------------------
Firewall rules should be written into text files, e.g. `ruleset.pfw` file.
One or more rule files can be specified in the configuration using:
firewall_scripts = { "path/to/ruleset.pfw", "path/to/ruleset2.pfw" }
If multiple files are specified and they both add rules to the same [chains](#chains),
each file's rules will be processed in order, but the order of files is undefined.
Reloading Prosody's configuration also reloads firewall rules.
Make sure that `firewall_scripts` is in the global section of the configuration file
and not below a virtual host or a component - unless you want per-vhost
firewall rules.
Conditions
----------
All conditions must come before any action in a rule block. The
condition name is followed by a colon (':'), and the value to test for.
A condition can be preceded or followed by `NOT` to negate its match.
For example:
NOT FROM: user@example.com
KIND NOT: message
Some conditions do not take parameters, and these should end with just a
question mark, like:
IN ROSTER?
### Zones
A 'zone' is one or more hosts or JIDs. It is possible to match when a
stanza is entering or leaving a zone, while at the same time not
matching traffic passing between JIDs in the same zone.
Zones are defined at the top of a script with the following syntax (they
are not part of a rule block):
%ZONE myzone: host1, host2, user@host3, foo.bar.example
There is an automatic zone named `$local`, which automatically includes
all of the current server's active hosts (including components). It can
be used to match stanzas entering or leaving the current server.
A host listed in a zone also matches all users on that host (but not
subdomains).
The following zone-matching conditions are supported:
Condition Matches
------------ ------------------------------------------
`ENTERING` When a stanza is entering the named zone
`LEAVING` When a stanza is leaving the named zone
### Lists
It is possible to create or load lists of strings for use in scripts. For
example, you might load a list of blocked JIDs, malware URLs or simple words
that you want to filter messages on.
List type Example
----------- -----------------------
memory %LIST spammers: memory
file %LIST spammers: file:/etc/spammers.txt
http %LIST spammers: http://example.com/spammers.txt
#### List types
##### memory
```
%LIST name: memory (limit: number)
```
A memory-only list, with an optional limit. Supports addition and removal of items by scripts.
If a limit is provided, the oldest item will be discarded to make room for a new item if the
list is full. The limit is useful to prevent infinite memory growth on busy servers.
##### file
```
%LIST name: file:/path/to/file (missing: string)
```
Reads a list from a file. The list can be added to and removed from by scripts, but
these changes do not persist between restarts.
If the file is missing, an error will be raised. The optional 'missing' parameter can be set
to 'ignore' (e.g. `(missing: ignore)`) to ignore a missing file.
##### http
```
%LIST name: http://example.com/ (ttl: number, pattern: pat, hash: sha1, checkcerts: when-sni)
```
Fetches a list from a HTTP or HTTPS URL. The following options are accepted:
Option Description
------- -----------
ttl Seconds to cache the list for. After expiry, it will be refetched. Default 3600 (1 hour).
pattern Optional pattern used to extract list entries from the response. Default is to treat each line as a single item.
hash Optional hash to be applied to items before looking them up in the list, e.g. sha1 or sha256.
checkcert Whether to verify HTTPS certificates. May be "always", "never" or "when-sni". Default "when-sni".
The "when-sni" default disables certificate verification when Prosody's HTTP client API doesn't support SNI,
as in Prosody 0.11.6 and earlier.
#### CHECK LIST
Checks whether a simple [expression](#expressions) is found in a given list.
Example:
%LIST blocked_jids: file:/etc/prosody/blocked_jids.txt
# Rule to block presence subscription requests from blocked JIDs
KIND: presence
TYPE: subscribe
CHECK LIST: blocked_jids contains $<@from>
BOUNCE=policy-violation (Your JID is blocked)
#### SCAN
SCAN allows you to search inside a stanza for a given pattern, and check each result against a list. For example,
you could scan a message body for words and check if any of the words are found in a given list.
Before using SCAN, you need to define a search location and a pattern. The search location uses the same 'path'
format as documented under the 'INSPECT' condition. Patterns can be any valid Lua pattern.
To use the above example:
# Define a search location called 'body' which fetches the text of the 'body' element
%SEARCH body: body#
# Define a pattern called 'word' which matches any sequence of letters
%PATTERN word: [A-Za-z]+
# Finally, we also need our list of "bad" words:
%LIST badwords: file:/etc/prosody/bad_words.txt
# Now we can use these to SCAN incoming stanzas
# If it finds a match, bounce the stanza
SCAN: body for word in badwords
BOUNCE=policy-violation (This word is not allowed!)
#### COUNT
COUNT is similar to SCAN, in that it uses a defined SEARCH and breaks it up according to a PATTERN. Then it
counts the number of results.
For example, to block every message with more than one URL:
# Define a search location called 'body' which fetches the text of the 'body' element
%SEARCH body: body#
# Define a pattern called 'url' which matches HTTP links
%PATTERN url: https?://%S+
COUNT: url in body > 1
BOUNCE=policy-violation (Up to one HTTP URL is allowed in messages)
### Stanza matching
Condition Matches
----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------
`KIND` The kind of stanza. May be 'message', 'presence' or 'iq'
`TYPE` The type of stanza. This varies depending on the kind of stanza. See 'Stanza types' below for more information.
`PAYLOAD` The stanza contains a child with the given namespace. Useful for determining the type of an iq request, or whether a message contains a certain extension.
`INSPECT` The node at the specified path exists or matches a given string. This allows you to look anywhere inside a stanza. See below for examples and more.
#### Stanza types
Stanza Valid types
---------- ------------------------------------------------------------------------------------------
iq get, set, result, error
presence *available*, unavailable, probe, subscribe, subscribed, unsubscribe, unsubscribed, error
message normal, chat, groupchat, headline, error
**Note:** The type 'available' for presence does not actually appear in
the protocol. Available presence is signalled by the omission of a type.
Similarly, a message stanza with no type is equivalent to one of type
'normal'. mod\_firewall handles these cases for you automatically.
#### Sender/recipient matching
Condition Matches
--------------- -------------------------------------------------------
`FROM` The JID in the 'from' attribute matches the given JID.
`TO` The JID in the 'to' attribute matches the given JID.
`TO SELF` The stanza is sent by any of a user's resources to their own bare JID.
`TO FULL JID` The stanza is addressed to a **valid** full JID on the local server (full JIDs include a resource at the end, and only exist for the lifetime of a single session, therefore the recipient **must be online**, or this check will not match).
`FROM FULL JID` The stanza is from a full JID (unlike `TO FULL JID` this check is on the format of the JID only).
The TO and FROM conditions both accept wildcards in the JID when it is
enclosed in angle brackets ('\<...\>'). For example:
# All users at example.com
FROM: <*>@example.com
# The user 'admin' on any subdomain of example.com
FROM: admin@<*.example.com>
You can also use [Lua's pattern
matching](http://www.lua.org/manual/5.1/manual.html#5.4.1) for more
powerful matching abilities. Patterns are a lightweight
regular-expression alternative. Simply contain the pattern in double
angle brackets. The pattern is automatically anchored at the start and
end (so it must match the entire portion of the JID).
# Match admin@example.com, and admin1@example.com, etc.
FROM: <<admin%d*>>@example.com
**Note:** It is important to know that 'example.com' is a valid JID on
its own, and does **not** match 'user@example.com'. To efficiently match
domains we recommend defining them as [Zones](#zones).
Condition Matches
---------------- ---------------------------------------------------------------
`FROM_EXACTLY` The JID in the 'from' attribute exactly matches the given JID
`TO_EXACTLY` The JID in the 'to' attribute exactly matches the given JID
These additional conditions do not support pattern matching, but are
useful to match the exact to/from address on a stanza. For example, if
no resource is specified then only bare JIDs will be matched. TO and FROM
match all resources if no resource is specified to match.
**Note:** Some chains execute before Prosody has performed any
normalisation or validity checks on the to/from JIDs on an incoming
stanza. It is not advisable to perform access control or similar rules
on JIDs in these chains (see the [chain documentation](#chains) for more info).
#### GeoIP matching
Condition Matches
---------------- --------------------------------------------------------------
`FROM COUNTRY` Two or three letter country code looked up in GeoIP database
This condition uses a GeoIP database to look up the origin country of
the IP attached to the current session.
For example:
# 3 letter country code
FROM COUNTRY: SWE
# or 2 letter
FROM COUNTRY: SE
# Explicit
FROM COUNTRY: code=SE
FROM COUNTRY: code3=SWE
**Note:** This requires that the `lua-geoip` and `geoip-database`
packages are installed (on Debian, package names may differ on other
operating systems).
#### INSPECT
INSPECT takes a 'path' through the stanza to get a string (an attribute
value or text content). An example is the best way to explain. Let's
check that a user is not trying to register an account with the username
'admin'. This stanza comes from [XEP-0077: In-band
Registration](http://xmpp.org/extensions/xep-0077.html#example-4):
``` xml
<iq type='set' id='reg2'>
<query xmlns='jabber:iq:register'>
<username>bill</username>
<password>Calliope</password>
<email>bard@shakespeare.lit</email>
</query>
</iq>
```
KIND: iq
TYPE: set
PAYLOAD: jabber:iq:register
INSPECT: {jabber:iq:register}query/username#=admin
BOUNCE=not-allowed (The username 'admin' is reserved.)
That weird string deserves some explanation. It is a path, divided into
segments by '/'. Each segment describes an element by its name,
optionally prefixed by its namespace in curly braces ('{...}'). If the
path ends with a '\#' then the text content of the last element will be
returned. If the path ends with '@name' then the value of the attribute
'name' will be returned.
You can use INSPECT to test for the existence of an element or attribute,
or you can check if it matches a specific value, e.g. by appending `=VALUE`
(like in the example above, that checks if the content of username is 'admin').
#### INSPECT comparison operators
As well as checking for an exact string match, there are some other modifiers
you can apply to the comparison:
Comparison Matches when
------------- -------------------------------------------------------
`=` The value is exactly the given string.
`/=` The value is or *contains* the given string (e.g. `/=admin` would match `administrator` or `myadmin`).
`~=` The value matches the given [Lua pattern](https://www.lua.org/manual/5.2/manual.html#6.4.1).
Finally, if the comparison operator is preceded by a `$` character, [expressions](#expressions)
will be interpreted in the string following the comparison operator.
e.g. `INSPECT: {jabber:iq:register}query/username}$/=$(session.host)` would match
if the username of an account registration contained the session's current hostname
somewhere in it.
#### INSPECT performance
INSPECT can be somewhat slower than the other stanza matching conditions. To
minimise performance impact, always place it below other faster
condition checks where possible (e.g. in the example above we first checked KIND,
TYPE and PAYLOAD matched what we wanted before reaching the INSPECT rule).
### Roster
These conditions access the roster of the recipient (only). Therefore they cannot (currently)
be used in some [chains](#chains), such as for outgoing messages (the recipient may be on another server).
Performance note: these checks can potentially cause storage access (especially if the recipient
is currently offline), so you may want to limit their use in high-traffic situations, and place rules
containing a roster check below other rules (such as a rate limiter). The storage access is
performed unconditionally just before evaluation of the first rule that contains a roster-based
condition, even if earlier conditions in that rule do not match.
#### IN ROSTER
Tests whether the sender is in the recipient's roster.
IN ROSTER?
#### IN ROSTER GROUP
Tests whether the sender is in the recipient's roster, and in the named group.
IN ROSTER GROUP: Friends
#### SUBSCRIBED
Tests whether the recipient is subscribed to the sender, ie will receive
presence updates from them.
Note that this *does* work, regardless of direction and which [chain](#chain) is
used, since both the sender and the recipient will have mirrored roster
entries.
### Groups
Using Prosody's mod\_groups it is possible to define groups of users on the server. You can
match based on these groups in firewall rules.
Condition Matches
----------------- ----------------------------
`FROM GROUP` When the stanza is being sent from a member of the named group
`TO GROUP` When the stanza is being sent to a member of the named group
`CROSSING GROUPS` When the stanza is being sent between users of different named groups
#### CROSSING GROUPS
The `CROSSING GROUPS` condition takes a comma-separated list of groups to check. If the
sender and recipient are not in the same group (only the listed groups are checked), then the
this condition matches and the stanza is deemed to be crossing between groups.
For example, if you had three groups: Engineering, Marketing and Employees. All users are
members of the 'Employees' group, and the others are for employees of the named department only.
To prevent employees in the marketing department from communicating with engineers, you could use
the following rule:
```
CROSSING GROUPS: Marketing, Engineering
BOUNCE=policy-violation (no communication between these groups is allowed!)
```
This works, even though both the users are in the 'Employees' group, because that group is not listed
in the condition.
In the above example, a user who is member of both groups is not restricted.
#### SENT DIRECTED PRESENCE TO SENDER
This condition matches if the recipient of a stanza has previously sent directed presence to the sender of the stanza. This
is often done in XMPP to exchange presence information with JIDs that are not on your roster, such as MUC rooms.
This condition does not take a parameter - end the condition name with a question mark:
# Rule to bounce messages from senders not in the roster who haven't been sent directed presence
NOT IN ROSTER?
NOT SENT DIRECTED PRESENCE TO SENDER?
BOUNCE=service-unavailable
### Permissions
Rules can consult Prosody's internal role and permissions system to check whether a certain action may
be performed. The acting entity, their role, and appropriate context is automatically inferred. All you
need to do is provide the identifier of the permission that should be checked.
Condition Description
----------------------- --------------------------------------------------------------------
`MAY=permission` Checks whether 'permission' is allowed in the current context.
As with all other conditions, `MAY` can be combined with `NOT` to negate the result of the check.
Example, blocking outgoing stanzas from users with roles that do not allow the 'xmpp:federate' permission:
```
::deliver_remote
MAY NOT: xmpp:federate
BOUNCE=policy-violation (You are not allowed access to the federation)
```
### Roles
Condition Matches
---------------- -------------------------------------------------------------------------------------
`TO ROLE` When the recipient JID of the stanza has the named role
`FROM ROLE` When the sender JID of the stanza has the named role
**Note:** In most cases, you should avoid checking for specific roles, and instead check for
permissions granted by those roles (using the 'MAY' condition).
### Admins
**Deprecated:** These conditions should no longer be used. Prefer 'MAY', 'TO ROLE' or 'FROM ROLE'.
Prosody allows certain JIDs to be declared as administrators of a host, component or the whole server.
Condition Matches
---------------- -------------------------------------------------------------------------------------
`TO ADMIN` When the recipient of the stanza is admin of the current host
`FROM ADMIN` When the sender of the stanza is admin of the current host
`FROM ADMIN OF` When the sender of the stanza is an admin of the named host on the current server
`TO ADMIN OF` When the recipient of the stanza is an admin of the named host on the current server
### Time and date
#### TIME
Matches stanzas sent during certain time periods.
Condition Matches
----------- -------------------------------------------------------------------------------------------
TIME When the current server local time is within one of the comma-separated time ranges given
TIME: 10pm-6am, 14:00-15:00
REPLY=Zzzz.
#### DAY
It is also possible to match only on certain days of the week.
Condition Matches
----------- -----------------------------------------------------------------------------------------------------
DAY When the current day matches one, or falls within a rage, in the given comma-separated list of days
Example:
DAY: Sat-Sun, Wednesday
REPLY=Sorry, I'm out enjoying life!
All times and dates are handled in the server's local time.
### Rate-limiting
It is possible to selectively rate-limit stanzas, and use rules to
decide what to do with stanzas when over the limit.
First, you must define any rate limits that you are going to use in your
script. Here we create a limiter called 'normal' that will allow 2
stanzas per second, and then we define a rule to bounce messages when
over this limit. Note that the `RATE` definition is not part of a rule
(multiple rules can share the same limiter).
%RATE normal: 2 (burst 3)
KIND: message
LIMIT: normal
BOUNCE=policy-violation (Sending too fast!)
The 'burst' parameter on the rate limit allows you to spread the limit
check over a given time period. For example the definition shown above
will allow the limit to be temporarily surpassed, as long as it is
within the limit after 3 seconds. You will almost always want to specify
a burst factor.
Both the rate and the burst can be fractional values. For example a rate
of 0.1 means only one event is allowed every 10 seconds.
The LIMIT condition actually does two things; first it counts against
the given limiter, and then it checks to see if the limiter over its
limit yet. If it is, the condition matches, otherwise it will not.
Condition Matches
----------- --------------------------------------------------------------------------------------------------
`LIMIT` When the named limit is 'used up'. Using this condition automatically counts against that limit.
**Note:** Reloading mod\_firewall resets the current state of any
limiters.
#### Dynamic limits
Sometimes you may want to have multiple throttles in a single condition, using some property of the session or stanza
to determine which throttle to use. For example, you might have a limit for incoming stanzas, but you want to limit by
sending JID, instead of all incoming stanzas sharing the same limit.
You can use the 'on' keyword for this, like so:
LIMIT: normal on EXPRESSION
For more information on [expressions](#expressions), see the section later in this document.
Each value of 'EXPRESSION' has to be tracked individually in a table, which uses a small amount of memory. To prevent
memory exhaustion, the number of tracked values is limited to 1000 by default. You can override this by setting the
maximum number of table entries when you define the rate:
%RATE normal: 2 (burst 3) (entries 4096)
Old values are automatically removed from the tracking table. However if the tracking table becomes full, new entries
will be rejected - it will behave as if the rate limit was reached, even for values that have not been seen before. Since
this opens up a potential denial of service (innocent users may be affected if malicious users can fill up the tracking
table within the limit period). You can choose to instead "fail open", and allow the rate limit to be temporarily bypassed
when the table is full. To choose this behaviour, add `(allow overflow)` to the RATE definition.
### Session marking
It is possible to 'mark' sessions (see the MARK_ORIGIN action below). To match stanzas from marked sessions, use the
`ORIGIN_MARKED` condition.
Condition Description
------------------------------- ---------------------------------------------------------------
ORIGIN MARKED: markname Matches if the origin has been marked with 'markname'.
ORIGIN MARKED: markname (Xs) Matches if the origin has been marked with 'markname' within the past X seconds.
Example usage:
# This rule drops messages from sessions that have been marked as spammers in the past hour
ORIGIN MARKED: spammer (3600s)
DROP.
# This rule marks the origin session as a spammer if they send a message to a honeypot JID
KIND: message
TO: honeypot@example.com
MARK ORIGIN=spammer
Actions
-------
Actions come after all conditions in a rule block. There must be at
least one action, though conditions are optional.
An action without parameters ends with a full-stop/period ('.'), and one
with parameters uses an equals sign ('='):
# An action with no parameters:
DROP.
# An action with a parameter:
REPLY=Hello, this is a reply.
### Route modification
The following common actions modify the stanza's route in some way. These
rules will halt further processing of the stanza - no further actions will be
executed, and no further rules will be checked.
Action Description
----------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------
`PASS.` Stop executing actions and rules on this stanza, and let it through this chain and any calling chains.
`DROP.` Stop executing actions and rules on this stanza, and discard it.
`DEFAULT.` Stop executing actions and rules on this stanza, prevent any other scripts/modules from handling it, to trigger the appropriate default "unhandled stanza" behaviour. Do not use in custom chains (it is treated as PASS).
`REDIRECT=jid` Redirect the stanza to the given JID.
`BOUNCE.` Bounce the stanza with the default error (usually service-unavailable)
`BOUNCE=error` Bounce the stanza with the given error (MUST be a defined XMPP stanza error, see [RFC6120](http://xmpp.org/rfcs/rfc6120.html#stanzas-error-conditions).
`BOUNCE=error (text)` As above, but include the supplied human-readable text with a description of the error
**Note:** It is incorrect behaviour to reply to an 'error' stanza with another error, so BOUNCE will simply act the same as 'DROP' for stanzas that should not be bounced (error stanzas and iq results).
### Replying and forwarding
These actions cause a new stanza to be generated and sent somewhere.
Processing of the original stanza will continue beyond these actions.
Action Description
------------------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------
`REPLY=text` Reply to the stanza (assumed to be a message) with the given text.
`COPY=jid` Make a copy of the stanza and send the copy to the specified JID. The copied stanza flows through Prosody's routing code, and as such is affected by firewall rules. Be careful to avoid loops.
`FORWARD=jid` Forward a copy of the stanza to the given JID (using XEP-0297). The stanza will be sent from the current host's JID.
### Reporting
Action Description
------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------
`REPORT TO=jid [reason] [text]` Forwards the full stanza to `jid` with a XEP-0377 abuse report attached.
Only the `jid` is mandatory. The `reason` parameter should be either `abuse`, `spam` or a custom URI. If not specified, it defaults to `abuse`.
After the reason, some human-readable text may be included to explain the report.
Example:
```
KIND: message
TO: honeypot@example.com
REPORT TO=antispam.example.com spam Caught by the honeypot!
DROP.
```
### Stanza modification
These actions make it possible to modify the content and structure of a
stanza.
Action Description
------------------------ ------------------------------------------------------------------------
`STRIP=name` Remove any child elements with the given name in the default namespace
`STRIP=name namespace` Remove any child elements with the given name and the given namespace
`INJECT=xml` Inject the given XML into the stanza as a child element
### Sessions
It is possible to mark sessions, and then use these marks to match rules later on.
Action Description
------------------------ --------------------------------------------------------------------------
`MARK ORIGIN=mark` Marks the originating session with the given flag.
`UNMARK ORIGIN=mark` Removes the given mark from the origin session (if it is set).
**Note:** Marks apply to sessions, not JIDs. E.g. if marking in a rule that matches a stanza received
over s2s, it is the s2s session that is marked.
It is possible to have multiple marks on an origin at any given time.
### Informational
Action Description
--------------- ------------------------------------------------------------------------------------------------------------------------
`LOG=message` Logs the given message to Prosody's log file. Optionally prefix it with a log level in square brackets, e.g. `[debug]`
You can include [expressions](#expressions) in log messages, using `$(...)` syntax. For example, to log the stanza that matched the rule,
you can use `$(stanza)`, or to log just the top tag of the stanza, use `$(stanza:top_tag())`. To fetch the sender JID, use `$(stanza.attr.from)`.
Example:
# Log all stanzas to user@example.com:
TO: user@example.com
LOG=[debug] User received: $(stanza)
More info about expressions can be found below.
Chains
------
Rules are grouped into "chains", which are injected at particular points in Prosody's routing code.
Available built-in chains are:
Chain Description
-------------- -------------------------------------------------------------------------------------------
deliver Applies to stanzas delivered to local recipients (regardless of the stanza's origin)
deliver_remote Applies to stanzas delivered to remote recipients (just before they leave the local server)
preroute Applies to incoming stanzas from local users, before any routing rules are applied
A chain is begun by a line `::name` where 'name' is the name of the chain you want the following rules to be
inserted into. If no chain is specified, rules are put into the 'deliver' chain.
It is possible to create custom chains (useful with the `JUMP CHAIN` action described below). User-created
chains must begin with "user/", e.g. "user/spam_filtering".
Example of chain use:
# example.com's firewall script
# This line is optional, because 'deliver' is the default chain anyway:
::deliver
# This rule matches any stanzas delivered to our local user bob:
TO: bob@example.com
DROP.
# Oops! This rule will never match, because alice is not a local user,
# and only stanzas to local users go through the 'deliver' chain:
TO: alice@remote.example.com
DROP.
# Create a 'preroute' chain of rules (matched for incoming stanzas from local clients):
::preroute
# These rules are matched for outgoing stanzas from local clients
# This will match any stanzas sent to alice from a local user:
TO: alice@remote.example.com
DROP.
Action Description
------------------------ ------------------------------------------------------------------------
`JUMP CHAIN=name` Switches chains, and passes the stanza through the rules in chain 'name'. If the new chain causes the stanza to be dropped/redirected, the current chain halts further processing.
`RETURN.` Stops executing the current chain and returns to the parent chain. For built-in chains, equivalent to PASS. RETURN is implicit at the end of every chain.
It is possible to jump to chains defined by other scripts and modules.
Expressions
-----------
Some conditions and actions in rules support "expressions" in their parameters (their documentation will indicate if this is the case). Most parameters
are static once the firewall script is loaded and compiled internally, however parameters that allow expressions can be dynamically calculated when a
rule is being run.
There are two kinds of expression that you can use: stanza expressions, and code expressions.
### Stanza expressions
Stanza expressions are of the form `$<...>`, where `...` is a stanza path. For syntax of stanza paths, see the documentation for the 'INSPECT' condition
above.
Example:
LOG=Matched a stanza from $<@from> to $<@to>
There are built in functions which can be applied to the output of a stanza expression, by appending the pipe ('|') operator, followed by the function
name. These functions are:
Function Description
------------ ---------------------------------------
bare Given a JID, strip any resource
node Return the node ('user part') of a JID
host Return the host ('domain') part of a JID
resource Return the resource part of a JID
For example, to apply a rate limit to stanzas per sender domain:
LIMIT normal on $<@from|host>
If the path does not match (e.g. the element isn't found, or the attribute doesn't exist) or any of the functions fail to produce an output (e.g. an invalid
JID was passed to a function that only handles valid JIDs) the expression will return the text `<undefined>`. You can override this by ending the expression
with a double pipe ('||') followed by a quoted string to use as a default instead. E.g. to default to the string "normal" when there is no 'type' attribute:
LOG=Stanza type is $<@type||"normal">
### Code expressions
Code expressions use `$(...)` syntax. Code expressions are powerful, and allow unconstrained access to Prosody's internal environment. Therefore
code expressions are typically for advanced use-cases only. You may want to refer to Prosody's [developer documentation](https://prosody.im/doc/developers)
for more information. In particular, within code expressions you may access the 'session' object, which is the session object of the origin of the stanza,
and the 'stanza' object, which is the stanza being considered within the current rule. Whatever value the expression returns will be converted to a string.
Example to limit stanzas per session type:
LIMIT: normal on $(session.type)

@ -0,0 +1,280 @@
local unpack = table.unpack or unpack;
local interpolation = require "util.interpolation";
local template = interpolation.new("%b$$", function (s) return ("%q"):format(s) end);
--luacheck: globals meta idsafe
local action_handlers = {};
-- Takes an XML string and returns a code string that builds that stanza
-- using st.stanza()
local function compile_xml(data)
local code = {};
local first, short_close = true, nil;
for tagline, text in data:gmatch("<([^>]+)>([^<]*)") do
if tagline:sub(-1,-1) == "/" then
tagline = tagline:sub(1, -2);
short_close = true;
end
if tagline:sub(1,1) == "/" then
code[#code+1] = (":up()");
else
local name, attr = tagline:match("^(%S*)%s*(.*)$");
local attr_str = {};
for k, _, v in attr:gmatch("(%S+)=([\"'])([^%2]-)%2") do
if #attr_str == 0 then
table.insert(attr_str, ", { ");
else
table.insert(attr_str, ", ");
end
if k:find("^%a%w*$") then
table.insert(attr_str, string.format("%s = %q", k, v));
else
table.insert(attr_str, string.format("[%q] = %q", k, v));
end
end
if #attr_str > 0 then
table.insert(attr_str, " }");
end
if first then
code[#code+1] = (string.format("st.stanza(%q %s)", name, #attr_str>0 and table.concat(attr_str) or ", nil"));
first = nil;
else
code[#code+1] = (string.format(":tag(%q%s)", name, table.concat(attr_str)));
end
end
if text and text:find("%S") then
code[#code+1] = (string.format(":text(%q)", text));
elseif short_close then
short_close = nil;
code[#code+1] = (":up()");
end
end
return table.concat(code, "");
end
function action_handlers.PASS()
return "do return pass_return end"
end
function action_handlers.DROP()
return "do return true end";
end
function action_handlers.DEFAULT()
return "do return false end";
end
function action_handlers.RETURN()
return "do return end"
end
function action_handlers.STRIP(tag_desc)
local code = {};
local name, xmlns = tag_desc:match("^(%S+) (.+)$");
if not name then
name, xmlns = tag_desc, nil;
end
if name == "*" then
name = nil;
end
code[#code+1] = ("local stanza_xmlns = stanza.attr.xmlns; ");
code[#code+1] = "stanza:maptags(function (tag) if ";
if name then
code[#code+1] = ("tag.name == %q and "):format(name);
end
if xmlns then
code[#code+1] = ("(tag.attr.xmlns or stanza_xmlns) == %q "):format(xmlns);
else
code[#code+1] = ("tag.attr.xmlns == stanza_xmlns ");
end
code[#code+1] = "then return nil; end return tag; end );";
return table.concat(code);
end
function action_handlers.INJECT(tag)
return "stanza:add_child("..compile_xml(tag)..")", { "st" };
end
local error_types = {
["bad-request"] = "modify";
["conflict"] = "cancel";
["feature-not-implemented"] = "cancel";
["forbidden"] = "auth";
["gone"] = "cancel";
["internal-server-error"] = "cancel";
["item-not-found"] = "cancel";
["jid-malformed"] = "modify";
["not-acceptable"] = "modify";
["not-allowed"] = "cancel";
["not-authorized"] = "auth";
["payment-required"] = "auth";
["policy-violation"] = "modify";
["recipient-unavailable"] = "wait";
["redirect"] = "modify";
["registration-required"] = "auth";
["remote-server-not-found"] = "cancel";
["remote-server-timeout"] = "wait";
["resource-constraint"] = "wait";
["service-unavailable"] = "cancel";
["subscription-required"] = "auth";
["undefined-condition"] = "cancel";
["unexpected-request"] = "wait";
};
local function route_modify(make_new, to, drop)
local reroute, deps = "session.send(newstanza)", { "st" };
if to then
reroute = ("newstanza.attr.to = %q; core_post_stanza(session, newstanza)"):format(to);
deps[#deps+1] = "core_post_stanza";
end
return ([[do local newstanza = st.%s; %s;%s end]])
:format(make_new, reroute, drop and " return true" or ""), deps;
end
function action_handlers.BOUNCE(with)
local error = with and with:match("^%S+") or "service-unavailable";
local error_type = error:match(":(%S+)");
if not error_type then
error_type = error_types[error] or "cancel";
else
error = error:match("^[^:]+");
end
error, error_type = string.format("%q", error), string.format("%q", error_type);
local text = with and with:match(" %((.+)%)$");
if text then
text = string.format("%q", text);
else
text = "nil";
end
local route_modify_code, deps = route_modify(("error_reply(stanza, %s, %s, %s)"):format(error_type, error, text), nil, true);
deps[#deps+1] = "type";
deps[#deps+1] = "name";
return [[if type == "error" or (name == "iq" and type == "result") then return true; end -- Don't reply to 'error' stanzas, or iq results
]]..route_modify_code, deps;
end
function action_handlers.REDIRECT(where)
return route_modify("clone(stanza)", where, true);
end
function action_handlers.COPY(where)
return route_modify("clone(stanza)", where, false);
end
function action_handlers.REPLY(with)
return route_modify(("reply(stanza):body(%q)"):format(with));
end
function action_handlers.FORWARD(where)
local code = [[
local newstanza = st.stanza("message", { to = %q, from = current_host }):tag("forwarded", { xmlns = "urn:xmpp:forward:0" });
local tmp_stanza = st.clone(stanza); tmp_stanza.attr.xmlns = "jabber:client"; newstanza:add_child(tmp_stanza);
core_post_stanza(session, newstanza);
]];
return code:format(where), { "core_post_stanza", "current_host" };
end
function action_handlers.LOG(string)
local level = string:match("^%[(%a+)%]") or "info";
string = string:gsub("^%[%a+%] ?", "");
local meta_deps = {};
local code = meta(("(session.log or log)(%q, '%%s', %q);"):format(level, string), meta_deps);
return code, meta_deps;
end
function action_handlers.RULEDEP(dep)
return "", { dep };
end
function action_handlers.EVENT(name)
return ("fire_event(%q, event)"):format(name);
end
function action_handlers.JUMP_EVENT(name)
return ("do return fire_event(%q, event); end"):format(name);
end
function action_handlers.JUMP_CHAIN(name)
return template([[do
local ret = fire_event($chain_event$, event);
if ret ~= nil then
if ret == false then
log("debug", "Chain %q accepted stanza (ret %s)", $chain_name$, tostring(ret));
return pass_return;
end
log("debug", "Chain %q rejected stanza (ret %s)", $chain_name$, tostring(ret));
return ret;
end
end]], { chain_event = "firewall/chains/"..name, chain_name = name });
end
function action_handlers.MARK_ORIGIN(name)
return [[session.firewall_marked_]]..idsafe(name)..[[ = current_timestamp;]], { "timestamp" };
end
function action_handlers.UNMARK_ORIGIN(name)
return [[session.firewall_marked_]]..idsafe(name)..[[ = nil;]]
end
function action_handlers.MARK_USER(name)
return ([[if session.username and session.host == current_host then
fire_event("firewall/marked/user", {
username = session.username;
mark = %q;
timestamp = current_timestamp;
});
else
log("warn", "Attempt to MARK a remote user - only local users may be marked");
end]]):format(assert(idsafe(name), "Invalid characters in mark name: "..name)), {
"current_host";
"timestamp";
};
end
function action_handlers.UNMARK_USER(name)
return ([[if session.username and session.host == current_host then
fire_event("firewall/unmarked/user", {
username = session.username;
mark = %q;
});
else
log("warn", "Attempt to UNMARK a remote user - only local users may be marked");
end]]):format(assert(idsafe(name), "Invalid characters in mark name: "..name));
end
function action_handlers.ADD_TO(spec)
local list_name, value = spec:match("(%S+) (.+)");
local meta_deps = {};
value = meta(("%q"):format(value), meta_deps);
return ("list_%s:add(%s);"):format(list_name, value), { "list:"..list_name, unpack(meta_deps) };
end
function action_handlers.UNSUBSCRIBE_SENDER()
return "rostermanager.unsubscribed(to_node, to_host, bare_from);\
rostermanager.roster_push(to_node, to_host, bare_from);\
core_post_stanza(session, st.presence({ from = bare_to, to = bare_from, type = \"unsubscribed\" }));",
{ "rostermanager", "core_post_stanza", "st", "split_to", "bare_to", "bare_from" };
end
function action_handlers.REPORT_TO(spec)
local where, reason, text = spec:match("^%s*(%S+) *(%S*) *(.*)$");
if reason == "spam" then
reason = "urn:xmpp:reporting:spam";
elseif reason == "abuse" or not reason or reason == "" then
reason = "urn:xmpp:reporting:abuse";
end
local code = [[
local newstanza = st.stanza("message", { to = %q, from = current_host, id = new_short_id() }):tag("forwarded", { xmlns = "urn:xmpp:forward:0" });
local tmp_stanza = st.clone(stanza); tmp_stanza.attr.xmlns = "jabber:client"; newstanza:add_child(tmp_stanza):up();
newstanza:tag("report", { xmlns = "urn:xmpp:reporting:1", reason = %q })
do local text = %q; if text ~= "" then newstanza:text_tag("text", text); end end
newstanza:up();
core_post_stanza(session, newstanza);
]];
return code:format(where, reason, text), { "core_post_stanza", "current_host", "st", "new_short_id" };
end
return action_handlers;

@ -0,0 +1,410 @@
--luacheck: globals meta idsafe
local condition_handlers = {};
local jid = require "util.jid";
local unpack = table.unpack or unpack;
-- Helper to convert user-input strings (yes/true//no/false) to a bool
local function string_to_boolean(s)
s = s:lower();
return s == "yes" or s == "true";
end
-- Return a code string for a condition that checks whether the contents
-- of variable with the name 'name' matches any of the values in the
-- comma/space/pipe delimited list 'values'.
local function compile_comparison_list(name, values)
local conditions = {};
for value in values:gmatch("[^%s,|]+") do
table.insert(conditions, ("%s == %q"):format(name, value));
end
return table.concat(conditions, " or ");
end
function condition_handlers.KIND(kind)
assert(kind, "Expected stanza kind to match against");
return compile_comparison_list("name", kind), { "name" };
end
local wildcard_equivs = { ["*"] = ".*", ["?"] = "." };
local function compile_jid_match_part(part, match)
if not match then
return part.." == nil";
end
local pattern = match:match("^<(.*)>$");
if pattern then
if pattern == "*" then
return part;
end
if pattern:find("^<.*>$") then
pattern = pattern:match("^<(.*)>$");
else
pattern = pattern:gsub("%p", "%%%0"):gsub("%%(%p)", wildcard_equivs);
end
return ("(%s and %s:find(%q))"):format(part, part, "^"..pattern.."$");
else
return ("%s == %q"):format(part, match);
end
end
local function compile_jid_match(which, match_jid)
local match_node, match_host, match_resource = jid.split(match_jid);
local conditions = {};
conditions[#conditions+1] = compile_jid_match_part(which.."_node", match_node);
conditions[#conditions+1] = compile_jid_match_part(which.."_host", match_host);
if match_resource then
conditions[#conditions+1] = compile_jid_match_part(which.."_resource", match_resource);
end
return table.concat(conditions, " and ");
end
function condition_handlers.TO(to)
return compile_jid_match("to", to), { "split_to" };
end
function condition_handlers.FROM(from)
return compile_jid_match("from", from), { "split_from" };
end
function condition_handlers.FROM_FULL_JID()
return "not "..compile_jid_match_part("from_resource", nil), { "split_from" };
end
function condition_handlers.FROM_EXACTLY(from)
local metadeps = {};
return ("from == %s"):format(metaq(from, metadeps)), { "from", unpack(metadeps) };
end
function condition_handlers.TO_EXACTLY(to)
local metadeps = {};
return ("to == %s"):format(metaq(to, metadeps)), { "to", unpack(metadeps) };
end
function condition_handlers.TO_SELF()
-- Intentionally not using 'to' here, as that defaults to bare JID when nil
return ("stanza.attr.to == nil");
end
function condition_handlers.TYPE(type)
assert(type, "Expected 'type' value to match against");
return compile_comparison_list("(type or (name == 'message' and 'normal') or (name == 'presence' and 'available'))", type), { "type", "name" };
end
local function zone_check(zone, which)
local zone_var = zone;
if zone == "$local" then zone_var = "_local" end
local which_not = which == "from" and "to" or "from";
return ("(zone_%s[%s_host] or zone_%s[%s] or zone_%s[bare_%s]) "
.."and not(zone_%s[%s_host] or zone_%s[%s] or zone_%s[bare_%s])"
)
:format(zone_var, which, zone_var, which, zone_var, which,
zone_var, which_not, zone_var, which_not, zone_var, which_not), {
"split_to", "split_from", "bare_to", "bare_from", "zone:"..zone
};
end
function condition_handlers.ENTERING(zone)
return zone_check(zone, "to");
end
function condition_handlers.LEAVING(zone)
return zone_check(zone, "from");
end
-- IN ROSTER? (parameter is deprecated)
function condition_handlers.IN_ROSTER(yes_no)
local in_roster_requirement = string_to_boolean(yes_no or "yes"); -- COMPAT w/ older scripts
return "not "..(in_roster_requirement and "not" or "").." roster_entry", { "roster_entry" };
end
function condition_handlers.IN_ROSTER_GROUP(group)
return ("not not (roster_entry and roster_entry.groups[%q])"):format(group), { "roster_entry" };
end
function condition_handlers.SUBSCRIBED()
return "(bare_to == bare_from or to_node and rostermanager.is_contact_subscribed(to_node, to_host, bare_from))",
{ "rostermanager", "split_to", "bare_to", "bare_from" };
end
function condition_handlers.PENDING_SUBSCRIPTION_FROM_SENDER()
return "(bare_to == bare_from or to_node and rostermanager.is_contact_pending_in(to_node, to_host, bare_from))",
{ "rostermanager", "split_to", "bare_to", "bare_from" };
end
function condition_handlers.PAYLOAD(payload_ns)
return ("stanza:get_child(nil, %q)"):format(payload_ns);
end
function condition_handlers.INSPECT(path)
if path:find("=") then
local query, match_type, value = path:match("(.-)([~/$]*)=(.*)");
if not(query:match("#$") or query:match("@[^/]+")) then
error("Stanza path does not return a string (append # for text content or @name for value of named attribute)", 0);
end
local meta_deps = {};
local quoted_value = ("%q"):format(value);
if match_type:find("$", 1, true) then
match_type = match_type:gsub("%$", "");
quoted_value = meta(quoted_value, meta_deps);
end
if match_type == "~" then -- Lua pattern match
return ("(stanza:find(%q) or ''):match(%s)"):format(query, quoted_value), meta_deps;
elseif match_type == "/" then -- find literal substring
return ("(stanza:find(%q) or ''):find(%s, 1, true)"):format(query, quoted_value), meta_deps;
elseif match_type == "" then -- exact match
return ("stanza:find(%q) == %s"):format(query, quoted_value), meta_deps;
else
error("Unrecognised comparison '"..match_type.."='", 0);
end
end
return ("stanza:find(%q)"):format(path);
end
function condition_handlers.FROM_GROUP(group_name)
return ("group_contains(%q, bare_from)"):format(group_name), { "group_contains", "bare_from" };
end
function condition_handlers.TO_GROUP(group_name)
return ("group_contains(%q, bare_to)"):format(group_name), { "group_contains", "bare_to" };
end
function condition_handlers.CROSSING_GROUPS(group_names)
local code = {};
for group_name in group_names:gmatch("([^, ][^,]+)") do
group_name = group_name:match("^%s*(.-)%s*$"); -- Trim leading/trailing whitespace
-- Just check that's it is crossing from outside group to inside group
table.insert(code, ("(group_contains(%q, bare_to) and group_contains(%q, bare_from))"):format(group_name, group_name))
end
return "not "..table.concat(code, " or "), { "group_contains", "bare_to", "bare_from" };
end
-- COMPAT w/0.12: Deprecated
function condition_handlers.FROM_ADMIN_OF(host)
return ("is_admin(bare_from, %s)"):format(host ~= "*" and metaq(host) or nil), { "is_admin", "bare_from" };
end
-- COMPAT w/0.12: Deprecated
function condition_handlers.TO_ADMIN_OF(host)
return ("is_admin(bare_to, %s)"):format(host ~= "*" and metaq(host) or nil), { "is_admin", "bare_to" };
end
-- COMPAT w/0.12: Deprecated
function condition_handlers.FROM_ADMIN()
return ("is_admin(bare_from, current_host)"), { "is_admin", "bare_from", "current_host" };
end
-- COMPAT w/0.12: Deprecated
function condition_handlers.TO_ADMIN()
return ("is_admin(bare_to, current_host)"), { "is_admin", "bare_to", "current_host" };
end
-- MAY: permission_to_check
function condition_handlers.MAY(permission_to_check)
return ("module:may(%q, event)"):format(permission_to_check);
end
function condition_handlers.TO_ROLE(role_name)
return ("recipient_role and recipient_role.name == %q"):format(role_name), { "recipient_role" };
end
function condition_handlers.FROM_ROLE(role_name)
return ("sender_role and sender_role.name == %q"):format(role_name), { "sender_role" };
end
local day_numbers = { sun = 0, mon = 2, tue = 3, wed = 4, thu = 5, fri = 6, sat = 7 };
local function current_time_check(op, hour, minute)
hour, minute = tonumber(hour), tonumber(minute);
local adj_op = op == "<" and "<" or ">="; -- Start time inclusive, end time exclusive
if minute == 0 then
return "(current_hour"..adj_op..hour..")";
else
return "((current_hour"..op..hour..") or (current_hour == "..hour.." and current_minute"..adj_op..minute.."))";
end
end
local function resolve_day_number(day_name)
return assert(day_numbers[day_name:sub(1,3):lower()], "Unknown day name: "..day_name);
end
function condition_handlers.DAY(days)
local conditions = {};
for day_range in days:gmatch("[^,]+") do
local day_start, day_end = day_range:match("(%a+)%s*%-%s*(%a+)");
if day_start and day_end then
local day_start_num, day_end_num = resolve_day_number(day_start), resolve_day_number(day_end);
local op = "and";
if day_end_num < day_start_num then
op = "or";
end
table.insert(conditions, ("current_day >= %d %s current_day <= %d"):format(day_start_num, op, day_end_num));
elseif day_range:find("%a") then
local day = resolve_day_number(day_range:match("%a+"));
table.insert(conditions, "current_day == "..day);
else
error("Unable to parse day/day range: "..day_range);
end
end
assert(#conditions>0, "Expected a list of days or day ranges");
return "("..table.concat(conditions, ") or (")..")", { "time:day" };
end
function condition_handlers.TIME(ranges)
local conditions = {};
for range in ranges:gmatch("([^,]+)") do
local clause = {};
range = range:lower()
:gsub("(%d+):?(%d*) *am", function (h, m) return tostring(tonumber(h)%12)..":"..(tonumber(m) or "00"); end)
:gsub("(%d+):?(%d*) *pm", function (h, m) return tostring(tonumber(h)%12+12)..":"..(tonumber(m) or "00"); end);
local start_hour, start_minute = range:match("(%d+):(%d+) *%-");
local end_hour, end_minute = range:match("%- *(%d+):(%d+)");
local op = tonumber(start_hour) > tonumber(end_hour) and " or " or " and ";
if start_hour and end_hour then
table.insert(clause, current_time_check(">", start_hour, start_minute));
table.insert(clause, current_time_check("<", end_hour, end_minute));
end
if #clause == 0 then
error("Unable to parse time range: "..range);
end
table.insert(conditions, "("..table.concat(clause, " "..op.." ")..")");
end
return table.concat(conditions, " or "), { "time:hour,min" };
end
function condition_handlers.LIMIT(spec)
local name, param = spec:match("^(%w+) on (.+)$");
local meta_deps = {};
if not name then
name = spec:match("^%w+$");
if not name then
error("Unable to parse LIMIT specification");
end
else
param = meta(("%q"):format(param), meta_deps);
end
if not param then
return ("not global_throttle_%s:poll(1)"):format(name), { "globalthrottle:"..name, unpack(meta_deps) };
end
return ("not multi_throttle_%s:poll_on(%s, 1)"):format(name, param), { "multithrottle:"..name, unpack(meta_deps) };
end
function condition_handlers.ORIGIN_MARKED(name_and_time)
local name, time = name_and_time:match("^%s*([%w_]+)%s+%(([^)]+)s%)%s*$");
if not name then
name = name_and_time:match("^%s*([%w_]+)%s*$");
end
if not name then
error("Error parsing mark name, see documentation for usage examples");
end
if time then
return ("(current_timestamp - (session.firewall_marked_%s or 0)) < %d"):format(idsafe(name), tonumber(time)), { "timestamp" };
end
return ("not not session.firewall_marked_"..idsafe(name));
end
function condition_handlers.USER_MARKED(name_and_time)
local name, time = name_and_time:match("^%s*([%w_]+)%s+%(([^)]+)s%)%s*$");
if not name then
name = name_and_time:match("^%s*([%w_]+)%s*$");
end
if not name then
error("Error parsing mark name, see documentation for usage examples");
end
if time then
return ([[(
current_timestamp - (session.firewall_marks and session.firewall_marks.%s or 0)
) < %d]]):format(idsafe(name), tonumber(time)), { "timestamp" };
end
return ("not not (session.firewall_marks and session.firewall_marks."..idsafe(name)..")");
end
function condition_handlers.SENT_DIRECTED_PRESENCE_TO_SENDER()
return "not not (session.directed and session.directed[from])", { "from" };
end
-- TO FULL JID?
function condition_handlers.TO_FULL_JID()
return "not not full_sessions[to]", { "to", "full_sessions" };
end
-- CHECK LIST: spammers contains $<@from>
function condition_handlers.CHECK_LIST(list_condition)
local list_name, expr = list_condition:match("(%S+) contains (.+)$");
if not (list_name and expr) then
error("Error parsing list check, syntax: LISTNAME contains EXPRESSION");
end
local meta_deps = {};
expr = meta(("%q"):format(expr), meta_deps);
return ("list_%s:contains(%s) == true"):format(list_name, expr), { "list:"..list_name, unpack(meta_deps) };
end
-- SCAN: body for word in badwords
function condition_handlers.SCAN(scan_expression)
local search_name, pattern_name, list_name = scan_expression:match("(%S+) for (%S+) in (%S+)$");
if not (search_name) then
error("Error parsing SCAN expression, syntax: SEARCH for PATTERN in LIST");
end
return ("scan_list(list_%s, %s)"):format(
list_name,
"tokens_"..search_name.."_"..pattern_name
), {
"scan_list",
"tokens:"..search_name.."-"..pattern_name, "list:"..list_name
};
end
-- COUNT: lines in body < 10
local valid_comp_ops = { [">"] = ">", ["<"] = "<", ["="] = "==", ["=="] = "==", ["<="] = "<=", [">="] = ">=" };
function condition_handlers.COUNT(count_expression)
local pattern_name, search_name, comparator_expression = count_expression:match("(%S+) in (%S+) (.+)$");
if not (pattern_name) then
error("Error parsing COUNT expression, syntax: PATTERN in SEARCH COMPARATOR");
end
local value;
comparator_expression = comparator_expression:gsub("%d+", function (value_string)
value = tonumber(value_string);
return "";
end);
if not value then
error("Error parsing COUNT expression, expected value");
end
local comp_op = comparator_expression:gsub("%s+", "");
assert(valid_comp_ops[comp_op], "Error parsing COUNT expression, unknown comparison operator: "..comp_op);
return ("it_count(search_%s:gmatch(pattern_%s)) %s %d"):format(
search_name, pattern_name, comp_op, value
), {
"it_count",
"search:"..search_name, "pattern:"..pattern_name
};
end
-- FROM COUNTRY: SE
-- FROM COUNTRY: code=SE
-- FROM COUNTRY: SWE
-- FROM COUNTRY: code3=SWE
-- FROM COUNTRY: continent=EU
-- FROM COUNTRY? --> NOT FROM COUNTRY: -- (for unknown/invalid)
-- TODO list support?
function condition_handlers.FROM_COUNTRY(geoip_spec)
local condition = "==";
if not geoip_spec then
geoip_spec = "--";
condition = "~=";
end
local field, country = geoip_spec:match("(%w+)=(%w+)");
if not field then
if #geoip_spec == 3 then
field, country = "code3", geoip_spec;
elseif #geoip_spec == 2 then
field, country = "code", geoip_spec;
else
error("Unknown country code type");
end
end
return ("get_geoip(session.ip, %q) %s %q"):format(field:lower(), condition, country:upper()), { "geoip_country" };
end
return condition_handlers;

@ -0,0 +1,335 @@
-- Name arguments are unused here
-- luacheck: ignore 212
local definition_handlers = {};
local http = require "net.http";
local timer = require "util.timer";
local set = require"util.set";
local new_throttle = require "util.throttle".create;
local hashes = require "util.hashes";
local jid = require "util.jid";
local lfs = require "lfs";
local multirate_cache_size = module:get_option_number("firewall_multirate_cache_limit", 1000);
function definition_handlers.ZONE(zone_name, zone_members)
local zone_member_list = {};
for member in zone_members:gmatch("[^, ]+") do
zone_member_list[#zone_member_list+1] = member;
end
return set.new(zone_member_list)._items;
end
-- Helper function used by RATE handler
local function evict_only_unthrottled(name, throttle)
throttle:update();
-- Check whether the throttle is at max balance (i.e. totally safe to forget about it)
if throttle.balance < throttle.max then
-- Not safe to forget
return false;
end
end
function definition_handlers.RATE(name, line)
local rate = assert(tonumber(line:match("([%d.]+)")), "Unable to parse rate");
local burst = tonumber(line:match("%(%s*burst%s+([%d.]+)%s*%)")) or 1;
local max_throttles = tonumber(line:match("%(%s*entries%s+([%d]+)%s*%)")) or multirate_cache_size;
local deny_when_full = not line:match("%(allow overflow%)");
return {
single = function ()
return new_throttle(rate*burst, burst);
end;
multi = function ()
local cache = require "util.cache".new(max_throttles, deny_when_full and evict_only_unthrottled or nil);
return {
poll_on = function (_, key, amount)
assert(key, "no key");
local throttle = cache:get(key);
if not throttle then
throttle = new_throttle(rate*burst, burst);
if not cache:set(key, throttle) then
module:log("warn", "Multirate '%s' has hit its maximum number of active throttles (%d), denying new events", name, max_throttles);
return false;
end
end
return throttle:poll(amount);
end;
}
end;
};
end
local list_backends = {
-- %LIST name: memory (limit: number)
memory = {
init = function (self, type, opts)
if opts.limit then
local have_cache_lib, cache_lib = pcall(require, "util.cache");
if not have_cache_lib then
error("In-memory lists with a size limit require Prosody 0.10");
end
self.cache = cache_lib.new((assert(tonumber(opts.limit), "Invalid list limit")));
if not self.cache.table then
error("In-memory lists with a size limit require a newer version of Prosody 0.10");
end
self.items = self.cache:table();
else
self.items = {};
end
end;
add = function (self, item)
self.items[item] = true;
end;
remove = function (self, item)
self.items[item] = nil;
end;
contains = function (self, item)
return self.items[item] == true;
end;
};
-- %LIST name: http://example.com/ (ttl: number, pattern: pat, hash: sha1)
http = {
init = function (self, url, opts)
local poll_interval = assert(tonumber(opts.ttl or "3600"), "invalid ttl for <"..url.."> (expected number of seconds)");
local pattern = opts.pattern or "([^\r\n]+)\r?\n";
assert(pcall(string.match, "", pattern), "invalid pattern for <"..url..">");
if opts.hash then
assert(opts.hash:match("^%w+$") and type(hashes[opts.hash]) == "function", "invalid hash function: "..opts.hash);
self.hash_function = hashes[opts.hash];
end
local etag;
local failure_count = 0;
local retry_intervals = { 60, 120, 300 };
-- By default only check the certificate if net.http supports SNI
local sni_supported = http.feature and http.features.sni;
local insecure = false;
if opts.checkcert == "never" then
insecure = true;
elseif (opts.checkcert == nil or opts.checkcert == "when-sni") and not sni_supported then
insecure = false;
end
local function update_list()
http.request(url, {
insecure = insecure;
headers = {
["If-None-Match"] = etag;
};
}, function (body, code, response)
local next_poll = poll_interval;
if code == 200 and body then
etag = response.headers.etag;
local items = {};
for entry in body:gmatch(pattern) do
items[entry] = true;
end
self.items = items;
module:log("debug", "Fetched updated list from <%s>", url);
elseif code == 304 then
module:log("debug", "List at <%s> is unchanged", url);
elseif code == 0 or (code >= 400 and code <=599) then
module:log("warn", "Failed to fetch list from <%s>: %d %s", url, code, tostring(body));
failure_count = failure_count + 1;
next_poll = retry_intervals[failure_count] or retry_intervals[#retry_intervals];
end
if next_poll > 0 then
timer.add_task(next_poll+math.random(0, 60), update_list);
end
end);
end
update_list();
end;
add = function ()
end;
remove = function ()
end;
contains = function (self, item)
if self.hash_function then
item = self.hash_function(item);
end
return self.items and self.items[item] == true;
end;
};
-- %LIST: file:/path/to/file
file = {
init = function (self, file_spec, opts)
local n, items = 0, {};
self.items = items;
local filename = file_spec:gsub("^file:", "");
if opts.missing == "ignore" and not lfs.attributes(filename, "mode") then
module:log("debug", "Ignoring missing list file: %s", filename);
return;
end
local file, err = io.open(filename);
if not file then
module:log("warn", "Failed to open list from %s: %s", filename, err);
return;
else
for line in file:lines() do
if not items[line] then
n = n + 1;
items[line] = true;
end
end
end
module:log("debug", "Loaded %d items from %s", n, filename);
end;
add = function (self, item)
self.items[item] = true;
end;
remove = function (self, item)
self.items[item] = nil;
end;
contains = function (self, item)
return self.items and self.items[item] == true;
end;
};
-- %LIST: pubsub:pubsub.example.com/node
-- TODO or the actual URI scheme? Bit overkill maybe?
-- TODO Publish items back to the service?
-- Step 1: Receiving pubsub events and storing them in the list
-- We'll start by using only the item id.
-- TODO Invent some custom schema for this? Needed for just a set of strings?
pubsubitemid = {
init = function(self, pubsub_spec, opts)
local service_addr, node = pubsub_spec:match("^pubsubitemid:([^/]*)/(.*)");
if not service_addr then
module:log("warn", "Invalid list specification (expected 'pubsubitemid:<service>/<node>', got: '%s')", pubsub_spec);
return;
end
module:depends("pubsub_subscription");
module:add_item("pubsub-subscription", {
service = service_addr;
node = node;
on_subscribed = function ()
self.items = {};
end;
on_item = function (event)
self:add(event.item.attr.id);
end;
on_retract = function (event)
self:remove(event.item.attr.id);
end;
on_purge = function ()
self.items = {};
end;
on_unsubscribed = function ()
self.items = nil;
end;
on_delete= function ()
self.items = nil;
end;
});
-- TODO Initial fetch? Or should mod_pubsub_subscription do this?
end;
add = function (self, item)
if self.items then
self.items[item] = true;
end
end;
remove = function (self, item)
if self.items then
self.items[item] = nil;
end
end;
contains = function (self, item)
return self.items and self.items[item] == true;
end;
};
};
list_backends.https = list_backends.http;
local normalize_functions = {
upper = string.upper, lower = string.lower;
md5 = hashes.md5, sha1 = hashes.sha1, sha256 = hashes.sha256;
prep = jid.prep, bare = jid.bare;
};
local function wrap_list_method(list_method, filter)
return function (self, item)
return list_method(self, filter(item));
end
end
local function create_list(list_backend, list_def, opts)
if not list_backends[list_backend] then
error("Unknown list type '"..list_backend.."'", 0);
end
local list = setmetatable({}, { __index = list_backends[list_backend] });
if list.init then
list:init(list_def, opts);
end
if opts.filter then
local filters = {};
for func_name in opts.filter:gmatch("[%w_]+") do
if func_name == "log" then
table.insert(filters, function (s)
--print("&&&&&", s);
module:log("debug", "Checking list <%s> for: %s", list_def, s);
return s;
end);
else
assert(normalize_functions[func_name], "Unknown list filter: "..func_name);
table.insert(filters, normalize_functions[func_name]);
end
end
local filter;
local n = #filters;
if n == 1 then
filter = filters[1];
else
function filter(s)
for i = 1, n do
s = filters[i](s or "");
end
return s;
end
end
list.add = wrap_list_method(list.add, filter);
list.remove = wrap_list_method(list.remove, filter);
list.contains = wrap_list_method(list.contains, filter);
end
return list;
end
--[[
%LIST spammers: memory (source: /etc/spammers.txt)
%LIST spammers: memory (source: /etc/spammers.txt)
%LIST spammers: http://example.com/blacklist.txt
]]
function definition_handlers.LIST(list_name, list_definition)
local list_backend = list_definition:match("^%w+");
local opts = {};
local opt_string = list_definition:match("^%S+%s+%((.+)%)");
if opt_string then
for opt_k, opt_v in opt_string:gmatch("(%w+): ?([^,]+)") do
opts[opt_k] = opt_v;
end
end
return create_list(list_backend, list_definition:match("^%S+"), opts);
end
function definition_handlers.PATTERN(name, pattern)
local ok, err = pcall(string.match, "", pattern);
if not ok then
error("Invalid pattern '"..name.."': "..err);
end
return pattern;
end
function definition_handlers.SEARCH(name, pattern)
return pattern;
end
return definition_handlers;

@ -0,0 +1,35 @@
local mark_storage = module:open_store("firewall_marks");
local mark_map_storage = module:open_store("firewall_marks", "map");
local user_sessions = prosody.hosts[module.host].sessions;
module:hook("firewall/marked/user", function (event)
local user = user_sessions[event.username];
local marks = user and user.firewall_marks;
if user and not marks then
-- Load marks from storage to cache on the user object
marks = mark_storage:get(event.username) or {};
user.firewall_marks = marks; --luacheck: ignore 122
end
if marks then
marks[event.mark] = event.timestamp;
end
local ok, err = mark_map_storage:set(event.username, event.mark, event.timestamp);
if not ok then
module:log("error", "Failed to mark user %q with %q: %s", event.username, event.mark, err);
end
return true;
end, -1);
module:hook("firewall/unmarked/user", function (event)
local user = user_sessions[event.username];
local marks = user and user.firewall_marks;
if marks then
marks[event.mark] = nil;
end
local ok, err = mark_map_storage:set(event.username, event.mark, nil);
if not ok then
module:log("error", "Failed to unmark user %q with %q: %s", event.username, event.mark, err);
end
return true;
end, -1);

@ -0,0 +1,863 @@
local lfs = require "lfs";
local resolve_relative_path = require "core.configmanager".resolve_relative_path;
local envload = require "util.envload".envload;
local logger = require "util.logger".init;
local it = require "util.iterators";
local set = require "util.set";
local have_features, features = pcall(require, "core.features");
features = have_features and features.available or set.new();
-- [definition_type] = definition_factory(param)
local definitions = module:shared("definitions");
-- When a definition instance has been instantiated, it lives here
-- [definition_type][definition_name] = definition_object
local active_definitions = {
ZONE = {
-- Default zone that includes all local hosts
["$local"] = setmetatable({}, { __index = prosody.hosts });
};
};
local default_chains = {
preroute = {
type = "event";
priority = 0.1;
"pre-message/bare", "pre-message/full", "pre-message/host";
"pre-presence/bare", "pre-presence/full", "pre-presence/host";
"pre-iq/bare", "pre-iq/full", "pre-iq/host";
};
deliver = {
type = "event";
priority = 0.1;
"message/bare", "message/full", "message/host";
"presence/bare", "presence/full", "presence/host";
"iq/bare", "iq/full", "iq/host";
};
deliver_remote = {
type = "event"; "route/remote";
priority = 0.1;
};
};
local extra_chains = module:get_option("firewall_extra_chains", {});
local chains = {};
for k,v in pairs(default_chains) do
chains[k] = v;
end
for k,v in pairs(extra_chains) do
chains[k] = v;
end
-- Returns the input if it is safe to be used as a variable name, otherwise nil
function idsafe(name)
return name:match("^%a[%w_]*$");
end
local meta_funcs = {
bare = function (code)
return "jid_bare("..code..")", {"jid_bare"};
end;
node = function (code)
return "(jid_split("..code.."))", {"jid_split"};
end;
host = function (code)
return "(select(2, jid_split("..code..")))", {"jid_split"};
end;
resource = function (code)
return "(select(3, jid_split("..code..")))", {"jid_split"};
end;
};
-- Run quoted (%q) strings through this to allow them to contain code. e.g.: LOG=Received: $(stanza:top_tag())
function meta(s, deps, extra)
return (s:gsub("$(%b())", function (expr)
expr = expr:gsub("\\(.)", "%1");
return [["..tostring(]]..expr..[[).."]];
end)
:gsub("$(%b<>)", function (expr)
expr = expr:sub(2,-2);
local default = "<undefined>";
expr = expr:gsub("||(%b\"\")$", function (default_string)
default = stripslashes(default_string:sub(2,-2));
return "";
end);
local func_chain = expr:match("|[%w|]+$");
if func_chain then
expr = expr:sub(1, -1-#func_chain);
end
local code;
if expr:match("^@") then
-- Skip stanza:find() for simple attribute lookup
local attr_name = expr:sub(2);
if deps and (attr_name == "to" or attr_name == "from" or attr_name == "type") then
-- These attributes may be cached in locals
code = attr_name;
table.insert(deps, attr_name);
else
code = "stanza.attr["..("%q"):format(attr_name).."]";
end
elseif expr:match("^%w+#$") then
code = ("stanza:get_child_text(%q)"):format(expr:sub(1, -2));
else
code = ("stanza:find(%q)"):format(expr);
end
if func_chain then
for func_name in func_chain:gmatch("|(%w+)") do
-- to/from are already available in local variables, use those if possible
if (code == "to" or code == "from") and func_name == "bare" then
code = "bare_"..code;
table.insert(deps, code);
elseif (code == "to" or code == "from") and (func_name == "node" or func_name == "host" or func_name == "resource") then
table.insert(deps, "split_"..code);
code = code.."_"..func_name;
else
assert(meta_funcs[func_name], "unknown function: "..func_name);
local new_code, new_deps = meta_funcs[func_name](code);
code = new_code;
if new_deps and #new_deps > 0 then
assert(deps, "function not supported here: "..func_name);
for _, dep in ipairs(new_deps) do
table.insert(deps, dep);
end
end
end
end
end
return "\"..tostring("..code.." or "..("%q"):format(default)..")..\"";
end)
:gsub("$$(%a+)", extra or {})
:gsub([[^""%.%.]], "")
:gsub([[%.%.""$]], ""));
end
function metaq(s, ...)
return meta(("%q"):format(s), ...);
end
local escape_chars = {
a = "\a", b = "\b", f = "\f", n = "\n", r = "\r", t = "\t",
v = "\v", ["\\"] = "\\", ["\""] = "\"", ["\'"] = "\'"
};
function stripslashes(s)
return (s:gsub("\\(.)", escape_chars));
end
-- Dependency locations:
-- <type lib>
-- <type global>
-- function handler()
-- <local deps>
-- if <conditions> then
-- <actions>
-- end
-- end
local available_deps = {
st = { global_code = [[local st = require "util.stanza";]]};
it = { global_code = [[local it = require "util.iterators";]]};
it_count = { global_code = [[local it_count = it.count;]], depends = { "it" } };
current_host = { global_code = [[local current_host = module.host;]] };
jid_split = {
global_code = [[local jid_split = require "util.jid".split;]];
};
jid_bare = {
global_code = [[local jid_bare = require "util.jid".bare;]];
};
to = { local_code = [[local to = stanza.attr.to or jid_bare(session.full_jid);]]; depends = { "jid_bare" } };
from = { local_code = [[local from = stanza.attr.from;]] };
type = { local_code = [[local type = stanza.attr.type;]] };
name = { local_code = [[local name = stanza.name;]] };
split_to = { -- The stanza's split to address
depends = { "jid_split", "to" };
local_code = [[local to_node, to_host, to_resource = jid_split(to);]];
};
split_from = { -- The stanza's split from address
depends = { "jid_split", "from" };
local_code = [[local from_node, from_host, from_resource = jid_split(from);]];
};
bare_to = { depends = { "jid_bare", "to" }, local_code = "local bare_to = jid_bare(to)"};
bare_from = { depends = { "jid_bare", "from" }, local_code = "local bare_from = jid_bare(from)"};
group_contains = {
global_code = [[local group_contains = module:depends("groups").group_contains]];
};
is_admin = require"core.usermanager".is_admin and { global_code = [[local is_admin = require "core.usermanager".is_admin;]]} or nil;
get_jid_role = require "core.usermanager".get_jid_role and { global_code = [[local get_jid_role = require "core.usermanager".get_jid_role;]] } or nil;
core_post_stanza = { global_code = [[local core_post_stanza = prosody.core_post_stanza;]] };
zone = { global_code = function (zone)
local var = zone;
if var == "$local" then
var = "_local"; -- See #1090
else
assert(idsafe(var), "Invalid zone name: "..zone);
end
return ("local zone_%s = zones[%q] or {};"):format(var, zone);
end };
date_time = { global_code = [[local os_date = os.date]]; local_code = [[local current_date_time = os_date("*t");]] };
time = { local_code = function (what)
local defs = {};
for field in what:gmatch("%a+") do
table.insert(defs, ("local current_%s = current_date_time.%s;"):format(field, field));
end
return table.concat(defs, " ");
end, depends = { "date_time" }; };
timestamp = { global_code = [[local get_time = require "socket".gettime;]]; local_code = [[local current_timestamp = get_time();]]; };
globalthrottle = {
global_code = function (throttle)
assert(idsafe(throttle), "Invalid rate limit name: "..throttle);
assert(active_definitions.RATE[throttle], "Unknown rate limit: "..throttle);
return ("local global_throttle_%s = rates.%s:single();"):format(throttle, throttle);
end;
};
multithrottle = {
global_code = function (throttle)
assert(pcall(require, "util.cache"), "Using LIMIT with 'on' requires Prosody 0.10 or higher");
assert(idsafe(throttle), "Invalid rate limit name: "..throttle);
assert(active_definitions.RATE[throttle], "Unknown rate limit: "..throttle);
return ("local multi_throttle_%s = rates.%s:multi();"):format(throttle, throttle);
end;
};
full_sessions = {
global_code = [[local full_sessions = prosody.full_sessions;]];
};
rostermanager = {
global_code = [[local rostermanager = require "core.rostermanager";]];
};
roster_entry = {
local_code = [[local roster_entry = (to_node and rostermanager.load_roster(to_node, to_host) or {})[bare_from];]];
depends = { "rostermanager", "split_to", "bare_from" };
};
list = { global_code = function (list)
assert(idsafe(list), "Invalid list name: "..list);
assert(active_definitions.LIST[list], "Unknown list: "..list);
return ("local list_%s = lists[%q];"):format(list, list);
end
};
search = {
local_code = function (search_name)
local search_path = assert(active_definitions.SEARCH[search_name], "Undefined search path: "..search_name);
return ("local search_%s = tostring(stanza:find(%q) or \"\")"):format(search_name, search_path);
end;
};
pattern = {
local_code = function (pattern_name)
local pattern = assert(active_definitions.PATTERN[pattern_name], "Undefined pattern: "..pattern_name);
return ("local pattern_%s = %q"):format(pattern_name, pattern);
end;
};
tokens = {
local_code = function (search_and_pattern)
local search_name, pattern_name = search_and_pattern:match("^([^%-]+)-(.+)$");
local code = ([[local tokens_%s_%s = {};
if search_%s then
for s in search_%s:gmatch(pattern_%s) do
tokens_%s_%s[s] = true;
end
end
]]):format(search_name, pattern_name, search_name, search_name, pattern_name, search_name, pattern_name);
return code, { "search:"..search_name, "pattern:"..pattern_name };
end;
};
sender_role = {
local_code = [[local sender_role = get_jid_role(bare_from, current_host)]];
depends = { "bare_from", "current_host", "get_jid_role" };
};
recipient_role = {
local_code = [[local recipient_role = get_jid_role(bare_to, current_host)]];
depends = { "bare_to", "current_host", "get_jid_role" };
};
scan_list = {
global_code = [[local function scan_list(list, items) for item in pairs(items) do if list:contains(item) then return true; end end end]];
};
iplib = {
global_code = [[local iplib = require "util.ip";]];
};
geoip_country = {
global_code = [[
local geoip_country = require "geoip.country";
local geov4 = geoip_country.open(module:get_option_string("geoip_ipv4_country", "/usr/share/GeoIP/GeoIP.dat"));
local geov6 = geoip_country.open(module:get_option_string("geoip_ipv6_country", "/usr/share/GeoIP/GeoIPv6.dat"));
local function get_geoip(ips, what)
if not ips then
return "--";
end
local ip = iplib.new_ip(ips);
if not ip then
return "--";
end
if ip.proto == "IPv6" and geov6 then
local geoinfo = geoinfo:query_by_addr6(ip.addr);
if geoinfo then
return geoinfo[what or "code"];
end
elseif ip.proto == "IPv4" and geov4 then
local geoinfo = geoinfo:query_by_addr(ip.addr);
if geoinfo then
return geoinfo[what or "code"];
end
end
return "--";
end
]];
depends = {
"iplib"
}
};
new_short_id = {
global_code = [[local new_short_id = require "util.id".short;]];
};
new_medium_id = {
global_code = [[local new_medium_id = require "util.id".medium;]];
};
new_long_id = {
global_code = [[local new_long_id = require "util.id".long;]];
};
trace = {
global_code = [[local trace_init = module:require("trace").init;]];
};
};
local function include_dep(dependency, code)
local dep, dep_param = dependency:match("^([^:]+):?(.*)$");
local dep_info = available_deps[dep];
if not dep_info then
module:log("error", "Dependency not found: %s", dep);
return;
end
if code.included_deps[dependency] ~= nil then
if code.included_deps[dependency] ~= true then
module:log("error", "Circular dependency on %s", dep);
end
return;
end
code.included_deps[dependency] = false; -- Pending flag (used to detect circular references)
for _, dep_dep in ipairs(dep_info.depends or {}) do
include_dep(dep_dep, code);
end
if dep_info.global_code then
if dep_param ~= "" then
local global_code, deps = dep_info.global_code(dep_param);
if deps then
for _, dep_dep in ipairs(deps) do
include_dep(dep_dep, code);
end
end
table.insert(code.global_header, global_code);
else
table.insert(code.global_header, dep_info.global_code);
end
end
if dep_info.local_code then
if dep_param ~= "" then
local local_code, deps = dep_info.local_code(dep_param);
if deps then
for _, dep_dep in ipairs(deps) do
include_dep(dep_dep, code);
end
end
table.insert(code, "\n\t\t-- "..dep.."\n\t\t"..local_code.."\n");
else
table.insert(code, "\n\t\t-- "..dep.."\n\t\t"..dep_info.local_code.."\n");
end
end
code.included_deps[dependency] = true;
end
local definition_handlers = module:require("definitions");
local condition_handlers = module:require("conditions");
local action_handlers = module:require("actions");
if module:get_option_boolean("firewall_experimental_user_marks", true) then
module:require"marks";
end
local function new_rule(ruleset, chain, line_no)
assert(chain, "no chain specified");
local rule = { conditions = {}, actions = {}, deps = {}, line_no = line_no };
table.insert(ruleset[chain], rule);
return rule;
end
local function parse_firewall_rules(filename)
local line_no = 0;
local function errmsg(err)
return "Error compiling "..filename.." on line "..line_no..": "..err;
end
local metadata = { debug = {} };
local ruleset = {
deliver = {};
};
local chain = "deliver"; -- Default chain
local rule;
local file, err = io.open(filename);
if not file then return nil, err; end
local state; -- nil -> "rules" -> "actions" -> nil -> ...
local line_hold;
for line in file:lines() do
line = line:match("^%s*(.-)%s*$");
if line_hold and line:sub(-1,-1) ~= "\\" then
line = line_hold..line;
line_hold = nil;
elseif line:sub(-1,-1) == "\\" then
line_hold = (line_hold or "")..line:sub(1,-2);
end
line_no = line_no + 1;
if line_hold or line:find("^[#;]") then -- luacheck: ignore 542
-- No action; comment or partial line
elseif line == "" then
if state == "rules" then
return nil, ("Expected an action on line %d for preceding criteria")
:format(line_no);
end
state = nil;
elseif not(state) and line:sub(1, 2) == "::" then
chain = line:gsub("^::%s*", "");
local chain_info = chains[chain];
if not chain_info then
if chain:match("^user/") then
chains[chain] = { type = "event", priority = 1, pass_return = false };
else
return nil, errmsg("Unknown chain: "..chain);
end
elseif chain_info.type ~= "event" then
return nil, errmsg("Only event chains supported at the moment");
end
ruleset[chain] = ruleset[chain] or {};
elseif not(state) and line:sub(1, 2) == "@@" then
local k, v = line:match("^@@%s*([^%s=]+)%s*=%s*(.+)$");
if not k then
return nil, errmsg("Unable to parse metadata assignment (expected '@@ key = value')");
end
metadata[k] = v;
elseif not(state) and line:sub(1,1) == "%" then -- Definition (zone, limit, etc.)
local what, name = line:match("^%%%s*([%w_]+) +([^ :]+)");
if not definition_handlers[what] then
return nil, errmsg("Definition of unknown object: "..what);
elseif not name or not idsafe(name) then
return nil, errmsg("Invalid "..what.." name");
end
local val = line:match(": ?(.*)$");
if not val and line:find(":<") then -- Read from file
local fn = line:match(":< ?(.-)%s*$");
if not fn then
return nil, errmsg("Unable to parse filename");
end
local f, err = io.open(fn);
if not f then return nil, errmsg(err); end
val = f:read("*a"):gsub("\r?\n", " "):gsub("%s+$", "");
end
if not val then
return nil, errmsg("No value given for definition");
end
val = stripslashes(val);
local ok, ret = pcall(definition_handlers[what], name, val);
if not ok then
return nil, errmsg(ret);
end
if not active_definitions[what] then
active_definitions[what] = {};
end
active_definitions[what][name] = ret;
elseif line:find("^[%w_ ]+[%.=]") then
-- Action
if state == nil then
-- This is a standalone action with no conditions
rule = new_rule(ruleset, chain);
end
state = "actions";
-- Action handlers?
local action = line:match("^[%w_ ]+"):upper():gsub(" ", "_");
if not action_handlers[action] then
return nil, ("Unknown action on line %d: %s"):format(line_no, action or "<unknown>");
end
table.insert(rule.actions, "-- "..line)
local ok, action_string, action_deps = pcall(action_handlers[action], line:match("=(.+)$"));
if not ok then
return nil, errmsg(action_string);
end
table.insert(rule.actions, action_string);
for _, dep in ipairs(action_deps or {}) do
table.insert(rule.deps, dep);
end
elseif state == "actions" then -- state is actions but action pattern did not match
state = nil; -- Awaiting next rule, etc.
table.insert(ruleset[chain], rule); -- FIXME: Is this a bug? Rule should have already been inserted by new_rule()?
rule = nil;
else
-- Condition
if not state then -- Starting a new rule block?
state = "rules";
rule = new_rule(ruleset, chain, line_no);
end
-- Check standard modifiers for the condition (e.g. NOT)
local negated;
local condition = line:match("^[^:=%.?]*");
if condition:find("%f[%w]NOT%f[^%w]") then
local s, e = condition:match("%f[%w]()NOT()%f[^%w]");
condition = (condition:sub(1,s-1)..condition:sub(e+1, -1)):match("^%s*(.-)%s*$");
negated = true;
end
condition = condition:gsub(" ", "_");
if not condition_handlers[condition] then
return nil, ("Unknown condition on line %d: %s"):format(line_no, (condition:gsub("_", " ")));
end
-- Get the code for this condition
local ok, condition_code, condition_deps = pcall(condition_handlers[condition], line:match(":%s?(.+)$"));
if not ok then
return nil, errmsg(condition_code);
end
if negated then condition_code = "not("..condition_code..")"; end
table.insert(rule.conditions, condition_code);
for _, dep in ipairs(condition_deps or {}) do
table.insert(rule.deps, dep);
end
end
end
return ruleset, metadata;
end
local function process_firewall_rules(ruleset, metadata)
-- Compile ruleset and return complete code
local chain_handlers = {};
-- Loop through the chains in the parsed ruleset (e.g. incoming, outgoing)
for chain_name, rules in pairs(ruleset) do
local code = { included_deps = {}, global_header = {} };
local condition_uses = {};
-- This inner loop assumes chain is an event-based, not a filter-based
-- chain (filter-based will be added later)
for _, rule in ipairs(rules) do
for _, condition in ipairs(rule.conditions) do
if condition:find("^not%(.+%)$") then
condition = condition:match("^not%((.+)%)$");
end
condition_uses[condition] = (condition_uses[condition] or 0) + 1;
end
end
if metadata.trace then
include_dep("trace", code);
table.insert(code, ("local trace = trace_init(%q, %q);"):format(metadata.filename, chain_name))
end
local condition_cache, n_conditions = {}, 0;
for rule_n, rule in ipairs(rules) do
for _, dep in ipairs(rule.deps) do
include_dep(dep, code);
end
table.insert(code, "\n\t\t");
local rule_code;
if #rule.conditions > 0 then
for i, condition in ipairs(rule.conditions) do
local negated = condition:match("^not%(.+%)$");
if negated then
condition = condition:match("^not%((.+)%)$");
end
if condition_uses[condition] > 1 then
local name = condition_cache[condition];
if not name then
n_conditions = n_conditions + 1;
name = "condition"..n_conditions;
condition_cache[condition] = name;
table.insert(code, "local "..name.." = "..condition..";\n\t\t");
end
rule.conditions[i] = (negated and "not(" or "")..name..(negated and ")" or "");
else
rule.conditions[i] = (negated and "not(" or "(")..condition..")";
end
if metadata.trace then
-- Wrap each condition in a tracer
rule.conditions[i] = ("trace(%d, %d, %s)"):format(rule_n, i, rule.conditions[i]);
end
end
if metadata.trace then
-- Trace overall action
table.insert(rule.actions, 1, ("trace(%d, nil, true)"):format(rule_n));
table.insert(rule.actions, ("else trace(%d, nil, false)"):format(rule_n));
end
rule_code = "if "..table.concat(rule.conditions, " and ").." then\n\t\t\t"
..table.concat(rule.actions, "\n\t\t\t")
.."\n\t\tend\n";
else
rule_code = table.concat(rule.actions, "\n\t\t");
end
table.insert(code, rule_code);
end
for name in pairs(definition_handlers) do
table.insert(code.global_header, 1, "local "..name:lower().."s = definitions."..name..";");
end
local code_string = "return function (definitions, fire_event, log, module, pass_return)\n\t"
..table.concat(code.global_header, "\n\t")
.."\n\tlocal db = require 'util.debug';\n\n\t"
.."return function (event)\n\t\t"
.."local stanza, session = event.stanza, event.origin;\n"
..table.concat(code, "")
.."\n\tend;\nend";
chain_handlers[chain_name] = code_string;
end
return chain_handlers;
end
local function compile_firewall_rules(filename)
local ruleset, metadata = parse_firewall_rules(filename);
if not ruleset then return nil, metadata; end
local chain_handlers = process_firewall_rules(ruleset, metadata);
return chain_handlers;
end
-- Compile handler code into a factory that produces a valid event handler. Factory accepts
-- a value to be returned on PASS
local function compile_handler(code_string, filename)
-- Prepare event handler function
local chunk, err = envload(code_string, "="..filename, _G);
if not chunk then
return nil, "Error compiling (probably a compiler bug, please report): "..err;
end
local function fire_event(name, data)
return module:fire_event(name, data);
end
local init_ok, initialized_chunk = pcall(chunk);
if not init_ok then
return nil, "Error initializing compiled rules: "..initialized_chunk;
end
return function (pass_return)
return initialized_chunk(active_definitions, fire_event, logger(filename), module, pass_return); -- Returns event handler with upvalues
end
end
local function resolve_script_path(script_path)
local relative_to = prosody.paths.config;
if script_path:match("^module:") then
relative_to = module:get_directory();
script_path = script_path:match("^module:(.+)$");
end
return resolve_relative_path(relative_to, script_path);
end
-- [filename] = { last_modified = ..., events_hooked = { [name] = handler } }
local loaded_scripts = {};
function load_script(script)
script = resolve_script_path(script);
local last_modified = (lfs.attributes(script) or {}).modification or os.time();
if loaded_scripts[script] then
if loaded_scripts[script].last_modified == last_modified then
return; -- Already loaded, and source file hasn't changed
end
module:log("debug", "Reloading %s", script);
-- Already loaded, but the source file has changed
-- unload it now, and we'll load the new version below
unload_script(script, true);
end
local chain_functions, err = compile_firewall_rules(script);
if not chain_functions then
module:log("error", "Error compiling %s: %s", script, err or "unknown error");
return;
end
-- Loop through the chains in the script, and for each chain attach the compiled code to the
-- relevant events, keeping track in events_hooked so we can cleanly unload later
local events_hooked = {};
for chain, handler_code in pairs(chain_functions) do
local new_handler, err = compile_handler(handler_code, "mod_firewall::"..chain);
if not new_handler then
module:log("error", "Compilation error for %s: %s", script, err);
else
local chain_definition = chains[chain];
if chain_definition and chain_definition.type == "event" then
local handler = new_handler(chain_definition.pass_return);
for _, event_name in ipairs(chain_definition) do
events_hooked[event_name] = handler;
module:hook(event_name, handler, chain_definition.priority);
end
elseif not chain:sub(1, 5) == "user/" then
module:log("warn", "Unknown chain %q", chain);
end
local event_name, handler = "firewall/chains/"..chain, new_handler(false);
events_hooked[event_name] = handler;
module:hook(event_name, handler);
end
end
loaded_scripts[script] = { last_modified = last_modified, events_hooked = events_hooked };
module:log("debug", "Loaded %s", script);
end
--COMPAT w/0.9 (no module:unhook()!)
local function module_unhook(event, handler)
return module:unhook_object_event((hosts[module.host] or prosody).events, event, handler);
end
function unload_script(script, is_reload)
script = resolve_script_path(script);
local script_info = loaded_scripts[script];
if not script_info then
return; -- Script not loaded
end
local events_hooked = script_info.events_hooked;
for event_name, event_handler in pairs(events_hooked) do
module_unhook(event_name, event_handler);
events_hooked[event_name] = nil;
end
loaded_scripts[script] = nil;
if not is_reload then
module:log("debug", "Unloaded %s", script);
end
end
-- Given a set of scripts (e.g. from config) figure out which ones need to
-- be loaded, which are already loaded but need unloading, and which to reload
function load_unload_scripts(script_list)
local wanted_scripts = script_list / resolve_script_path;
local currently_loaded = set.new(it.to_array(it.keys(loaded_scripts)));
local scripts_to_unload = currently_loaded - wanted_scripts;
for script in wanted_scripts do
-- If the script is already loaded, this is fine - it will
-- reload the script for us if the file has changed
load_script(script);
end
for script in scripts_to_unload do
unload_script(script);
end
end
function module.load()
if not prosody.arg then return end -- Don't run in prosodyctl
local firewall_scripts = module:get_option_set("firewall_scripts", {});
load_unload_scripts(firewall_scripts);
-- Replace contents of definitions table (shared) with active definitions
for k in it.keys(definitions) do definitions[k] = nil; end
for k,v in pairs(active_definitions) do definitions[k] = v; end
end
function module.save()
return { active_definitions = active_definitions, loaded_scripts = loaded_scripts };
end
function module.restore(state)
active_definitions = state.active_definitions;
loaded_scripts = state.loaded_scripts;
end
module:hook_global("config-reloaded", function ()
load_unload_scripts(module:get_option_set("firewall_scripts", {}));
end);
function module.command(arg)
if not arg[1] or arg[1] == "--help" then
require"util.prosodyctl".show_usage([[mod_firewall <firewall.pfw>]], [[Compile files with firewall rules to Lua code]]);
return 1;
end
local verbose = arg[1] == "-v";
if verbose then table.remove(arg, 1); end
if arg[1] == "test" then
table.remove(arg, 1);
return module:require("test")(arg);
end
local serialize = require "util.serialization".serialize;
if verbose then
print("local logger = require \"util.logger\".init;");
print();
print("local function fire_event(name, data)\n\tmodule:fire_event(name, data)\nend");
print();
end
for _, filename in ipairs(arg) do
filename = resolve_script_path(filename);
print("do -- File "..filename);
local chain_functions = assert(compile_firewall_rules(filename));
if verbose then
print();
print("local active_definitions = "..serialize(active_definitions)..";");
print();
end
local c = 0;
for chain, handler_code in pairs(chain_functions) do
c = c + 1;
print("---- Chain "..chain:gsub("_", " "));
local chain_func_name = "chain_"..tostring(c).."_"..chain:gsub("%p", "_");
if not verbose then
print(("%s = %s;"):format(chain_func_name, handler_code:sub(8)));
else
print(("local %s = (%s)(active_definitions, fire_event, logger(%q));"):format(chain_func_name, handler_code:sub(8), filename));
print();
local chain_definition = chains[chain];
if chain_definition and chain_definition.type == "event" then
for _, event_name in ipairs(chain_definition) do
print(("module:hook(%q, %s, %d);"):format(event_name, chain_func_name, chain_definition.priority or 0));
end
end
print(("module:hook(%q, %s, %d);"):format("firewall/chains/"..chain, chain_func_name, chain_definition.priority or 0));
end
print("---- End of chain "..chain);
print();
end
print("end -- End of file "..filename);
end
end
-- Console
local console_env = module:shared("/*/admin_shell/env");
console_env.firewall = {};
function console_env.firewall:mark(user_jid, mark_name)
local username, host = jid.split(user_jid);
if not username or not hosts[host] then
return nil, "Invalid JID supplied";
elseif not idsafe(mark_name) then
return nil, "Invalid characters in mark name";
end
if not module:context(host):fire_event("firewall/marked/user", {
username = session.username;
mark = mark_name;
timestamp = os.time();
}) then
return nil, "Mark not set - is mod_firewall loaded on that host?";
end
return true, "User marked";
end
function console_env.firewall:unmark(jid, mark_name)
local username, host = jid.split(user_jid);
if not username or not hosts[host] then
return nil, "Invalid JID supplied";
elseif not idsafe(mark_name) then
return nil, "Invalid characters in mark name";
end
if not module:context(host):fire_event("firewall/unmarked/user", {
username = session.username;
mark = mark_name;
}) then
return nil, "Mark not removed - is mod_firewall loaded on that host?";
end
return true, "User unmarked";
end

@ -0,0 +1,17 @@
# This is a simple ruleset to block all traffic from servers
# on the JabberSPAM blocklist. Even traffic from existing user
# contacts will be blocked.
#
# Example config (make sure "firewall" is in modules_enabled):
#
# firewall_scripts = { "module:scripts/jabberspam-simple-blocklist.pfw" }
#
# For a more advanced ruleset, consider using spam-blocking.pfw
# and spam-blocklists.pfw.
%LIST blocklist: https://cdn.jsdelivr.net/gh/jabberspam/blacklist/blacklist.txt
::deliver
CHECK LIST: blocklist contains $<@from|host>
BOUNCE=policy-violation (Your server is blocked due to spam)

@ -0,0 +1,182 @@
#### Anti-spam ruleset ###########################################
#
# This script provides some foundational anti-spam rules. It aims
# to PASS stanzas that are definitely not spam, and DROP stanzas
# that are very likely spam.
#
# It does not do any form of content filtering,
# but this can be implemented by other scripts and
# modules as desired using the chains documented below.
#
#
# The following chains are available as extension
# points:
#
# ::user/spam_check_custom
# Apply additional rules to all stanzas before they are checked.
# Mainly useful to PASS stanzas that you do not want to be
# filtered.
#
# ::user/spam_check_message_custom
# Apply additional rules to messages from strangers, aiming to
# PASS stanzas that are not spam and jump to ::user/spam_reject
# for stanzas that are considered spam.
#
# ::user/spam_check_message_content_custom
# Apply additional rules to messages that may be spam, based on
# message content rules. These may contain more intensive rules,
# so are executed after all other checks. Rules should jump to
# ::user/spam_reject if a message is considered spam.
#
# ::user/spam_check_presence_custom
# Apply additional rules to presence that may be spam.
#
# ::user/spam_check_subscription_request_custom
# Apply additional rules to subscription requests.
#
# ::user/spam_handle_unknown_custom
# Override default handling of stanzas that weren't explicitly
# passed or rejected by the anti-spam checks.
#
# ::user/spam_reject_custom
# Override default handling of stanzas that have
# been recognised as spam (default is to bounce
# a policy-violation error).
#
##################################################################
#### Entry point for all incoming stanzas ########################
::deliver
# Override this if you want to prevent certain stanzas going through
# the normal spam_check chain
JUMP_CHAIN=user/spam_check_custom
# Run the default spam_check chain
JUMP_CHAIN=user/spam_check
##################################################################
#### General spam-checking rules (all stanzas) ###################
::user/spam_check
# Pass stanzas that a user sends to their own account
TO SELF?
PASS.
# Pass stanzas that are addressed to a valid full JID
TO FULL JID?
PASS.
# Pass stanzas from contacts
SUBSCRIBED?
PASS.
# Run extra rules that apply to messages only
KIND: message
JUMP CHAIN=user/spam_check_message
# Run extra rules that apply to presence stanzas only
KIND: presence
JUMP CHAIN=user/spam_check_presence
JUMP CHAIN=user/spam_handle_unknown
# Default is to allow, override this with
# the 'user/spam_handle_unknown' chain
PASS.
#### Rules for messages ##########################################
::user/spam_check_message
JUMP CHAIN=user/spam_check_message_custom
# Type 'groupchat' messages addressed to an offline full JID are harmless,
# and should be routed normally to handle MUC 'ghosts' correctly
TO: <*>@<*>/<*>
TYPE: groupchat
PASS.
# Mediated MUC invitations are naturally from 'strangers' and have special
# handling. We lean towards accepting them, unless overridden by custom rules.
NOT FROM FULL JID?
INSPECT: {http://jabber.org/protocol/muc#user}x/invite
JUMP CHAIN=user/spam_check_muc_invite
# Non-chat message types often generate pop-ups in clients,
# so we won't accept them from strangers
NOT TYPE: chat
JUMP CHAIN=user/spam_reject
JUMP CHAIN=user/spam_check_message_content
# This chain can be used by other scripts
# and modules that analyze message content
JUMP CHAIN=user/spam_check_message_content_custom
##################################################################
#### Rules for presence stanzas ##################################
::user/spam_check_presence
JUMP CHAIN=user/spam_check_presence_custom
# Presence to offline full JIDs is harmless, and should be routed
# normally to handle MUC 'ghosts' correctly
TO: <*>@<*>/<*>
PASS.
# These may be received if rosters get out of sync and are harmless
# because they will not be routed to the client unless necessary
TYPE: unsubscribe|unsubscribed
PASS.
# We don't want to receive presence from random strangers,
# but still allow subscription requests
NOT TYPE: subscribe|subscribed
DROP.
# This chain can be used by other scripts
# and modules to filter subscription requests
JUMP CHAIN=user/spam_check_subscription_request
JUMP CHAIN=user/spam_check_subscription_request_custom
##################################################################
#### Rules for MUC invitations ###################################
::user/spam_check_muc_invite
# This chain can be used to inspect the invitation and determine
# the appropriate action. Otherwise, we proceed with the default
# action below.
JUMP CHAIN=user/spam_check_muc_invite_custom
# Allow mediated MUC invitations by default
PASS.
#### Stanzas reaching this chain will be rejected ################
::user/spam_reject
# This chain can be used by other scripts
# and modules to override the default behaviour
# when rejecting spam stanzas
JUMP CHAIN=user/spam_reject_custom
LOG=Rejecting suspected spam: $(stanza:top_tag())
BOUNCE=policy-violation
##################################################################
#### Stanzas that may be spam, but we're not sure either way #####
::user/spam_handle_unknown
# This chain can be used by other scripts
# and modules to apply additional checks, or to
# override the default behaviour
JUMP CHAIN=user/spam_handle_unknown_custom
#LOG=[debug] Spam check allowing: $(stanza:top_tag())
##################################################################

@ -0,0 +1,20 @@
# This script depends on spam-blocking.pfw also being loaded
# Any traffic that is not explicitly blocked or allowed by other
# rules will be checked against the JabberSPAM server blocklist
%LIST blocklist: https://cdn.jsdelivr.net/gh/jabberspam/blacklist/blacklist.txt
::user/spam_handle_unknown_custom
CHECK LIST: blocklist contains $<@from|host>
BOUNCE=policy-violation (Your server is blocked due to spam)
::user/spam_check_muc_invite_custom
# Check the server we received the invitation from
CHECK LIST: blocklist contains $<@from|host>
BOUNCE=policy-violation (Your server is blocked due to spam)
# Check the inviter's JID against the blocklist, too
CHECK LIST: blocklist contains $<{http://jabber.org/protocol/muc#user}x/invite@from|host>
BOUNCE=policy-violation (Your server is blocked due to spam)

@ -0,0 +1,5 @@
# Strip XHTML-IM from messages received from strangers
::user/spam_check_message_custom
STRIP=html http://jabber.org/protocol/xhtml-im

@ -0,0 +1,75 @@
-- luacheck: globals load_unload_scripts
local set = require "util.set";
local ltn12 = require "ltn12";
local xmppstream = require "util.xmppstream";
local function stderr(...)
io.stderr:write("** ", table.concat({...}, "\t", 1, select("#", ...)), "\n");
end
return function (arg)
require "net.http".request = function (url, ex, cb)
stderr("Making HTTP request to "..url);
local body_table = {};
local ok, response_status, response_headers = require "ssl.https".request({
url = url;
headers = ex.headers;
method = ex.body and "POST" or "GET";
sink = ltn12.sink.table(body_table);
source = ex.body and ltn12.source.string(ex.body) or nil;
});
stderr("HTTP response "..response_status);
cb(table.concat(body_table), response_status, { headers = response_headers });
return true;
end;
local stats_dropped, stats_passed = 0, 0;
load_unload_scripts(set.new(arg));
local stream_callbacks = { default_ns = "jabber:client" };
function stream_callbacks.streamopened(session)
session.notopen = nil;
end
function stream_callbacks.streamclosed()
end
function stream_callbacks.error(session, error_name, error_message) -- luacheck: ignore 212/session
stderr("Fatal error parsing XML stream: "..error_name..": "..tostring(error_message))
assert(false);
end
function stream_callbacks.handlestanza(session, stanza)
if not module:fire_event("firewall/chains/deliver", { origin = session, stanza = stanza }) then
stats_passed = stats_passed + 1;
print(stanza);
print("");
else
stats_dropped = stats_dropped + 1;
end
end
local session = { notopen = true };
function session.send(stanza)
stderr("Reply:", "\n"..tostring(stanza).."\n");
end
local stream = xmppstream.new(session, stream_callbacks);
stream:feed("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'>");
local line_count = 0;
for line in io.lines() do
line_count = line_count + 1;
local ok, err = stream:feed(line.."\n");
if not ok then
stderr("Fatal XML parse error on line "..line_count..": "..err);
return 1;
end
end
stderr("Summary");
stderr("-------");
stderr("");
stderr(stats_dropped + stats_passed, "processed");
stderr(stats_passed, "passed");
stderr(stats_dropped, "dropped");
stderr(line_count, "input lines");
stderr("");
end

@ -0,0 +1,210 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { RegisterServerOptions } from '@peertube/peertube-types'
import type { AdminFirewallConfiguration } from '../../../shared/lib/types'
import * as path from 'path'
import * as fs from 'fs'
import {
firewallNameRegexp, maxFirewallFileSize, maxFirewallFiles, maxFirewallNameLength
} from '../../../shared/lib/admin-firewall'
/**
* Indicates if the firewall configuration can be changed in the Peertube web interface.
* Sys admins can disable this feature by creating a special file in the plugin folder.
* @param options Peertube server options
*/
export async function canEditFirewallConfig (options: RegisterServerOptions): Promise<boolean> {
const peertubeHelpers = options.peertubeHelpers
const logger = peertubeHelpers.logger
if (!peertubeHelpers.plugin) {
return false
}
const filepath = path.resolve(peertubeHelpers.plugin.getDataDirectoryPath(), 'disable_mod_firewall_editing')
try {
// Testing if file exist by reading it.
await fs.promises.readFile(filepath)
return false
} catch (err: any) {
if (('code' in err) && err.code === 'ENOENT') {
// File does not exist
return true
}
logger.error(err)
// Here it is safer to disable the editing...
return false
}
}
/**
* Returns the list of mod_firewall configuration files.
* @param options: Peertube server options.
* @param dir the path to the directory containing these configuration files.
* @param includeDisabled if true, disabled files are included in the results.
*/
export async function listModFirewallFiles (
options: RegisterServerOptions,
dir: string,
includeDisabled?: boolean
): Promise<string[]> {
try {
const files = (await fs.promises.readdir(dir, { withFileTypes: true })).filter(file => {
if (!file.isFile()) {
return false
}
if (
file.name.endsWith('.pfw') &&
// we only load valid names, to avoid having files that could not be edited from frontend
firewallNameRegexp.test(file.name.substring(0, file.name.length - 4))
) {
return true
}
if (
includeDisabled &&
file.name.endsWith('.pfw.disabled') &&
firewallNameRegexp.test(file.name.substring(0, file.name.length - 13))
) {
return true
}
return false
})
return files.map(f => path.join(dir, f.name)).sort()
} catch (err) {
// should be that the directory does not exists
return []
}
}
/**
* Returns the modFirewall configuration.
* @param options Peertube server options
* @param dir the path to the directory containing these configuration files.
* @throws will throw an error if it can't read any of the configuration file.
*/
export async function getModFirewallConfig (
options: RegisterServerOptions,
dir: string
): Promise<AdminFirewallConfiguration> {
const filePaths = await listModFirewallFiles(options, dir, true)
const files = []
for (const filePath of filePaths) {
const content = (await fs.promises.readFile(filePath)).toString()
const name = path.basename(filePath).replace(/\.pfw(\.disabled)?$/, '')
files.push({
name,
content,
enabled: !filePath.endsWith('.disabled')
})
}
const enabled = (await options.settingsManager.getSetting('prosody-firewall-enabled')) === true
return {
enabled,
files
}
}
/**
* Sanitize any data received from the frontend, to store in modFirewall configuration.
* Throws an exception if data is invalid.
* @param options Peertube server options
* @param data Incoming data
*/
export async function sanitizeModFirewallConfig (
options: RegisterServerOptions,
data: any
): Promise<AdminFirewallConfiguration> {
if (typeof data !== 'object') {
throw new Error('Invalid data type')
}
if (!Array.isArray(data.files)) {
throw new Error('Invalid data.files')
}
if (data.files.length > maxFirewallFiles) {
throw new Error('Too many files')
}
const files: AdminFirewallConfiguration['files'] = []
for (const entry of data.files) {
if (typeof entry !== 'object') {
throw new Error('Invalid data in data.files')
}
if (typeof entry.enabled !== 'boolean') {
throw new Error('Invalid data in data.files (enabled)')
}
if (typeof entry.name !== 'string') {
throw new Error('Invalid data in data.files (name)')
}
if (typeof entry.content !== 'string') {
throw new Error('Invalid data in data.files (content)')
}
if (entry.name.length > maxFirewallNameLength || !firewallNameRegexp.test(entry.name)) {
throw new Error('Invalid name in data.files')
}
if (entry.content.length > maxFirewallFileSize) {
throw new Error('File content too big in data.files')
}
files.push({
enabled: entry.enabled,
name: entry.name,
content: entry.content
})
}
const result = {
enabled: !!data.enabled, // this is not saved, so no need to check type.
files
}
return result
}
/**
* Saves the modFirewall configuration.
* FIXME: currently, if the save fails on one file, remaining files will not be saved. So there is a risk of data loss.
* @param options Peertube server options
* @param dir the path to the directory containing these configuration files.
* @param config the configuration to save
* @throws will throw an error if it can't read any of the configuration file.
*/
export async function saveModFirewallConfig (
options: RegisterServerOptions,
dir: string,
config: AdminFirewallConfiguration
): Promise<void> {
const logger = options.peertubeHelpers.logger
const previousFiles = await listModFirewallFiles(options, dir, true)
logger.debug('[mod-firewall-lib] Creating the ' + dir + ' directory.')
await fs.promises.mkdir(dir, { recursive: true })
const seen = new Map<string, true>()
for (const f of config.files) {
const filePath = path.join(
dir,
f.name + '.pfw' + (f.enabled ? '' : '.disabled')
)
logger.info('[mod-firewall-lib] Saving ' + filePath)
await fs.promises.writeFile(filePath, f.content)
seen.set(filePath, true)
}
// Removing deprecated files:
for (const p of previousFiles) {
if (seen.has(p)) { continue }
logger.info('[mod-firewall-lib] Deleting deprecated file ' + p)
await fs.promises.rm(p)
}
}

@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { RegisterServerOptions } from '@peertube/peertube-types'
import type { Request, Response, NextFunction } from 'express'
import type { RequestPromiseHandler } from './async'
import { isUserAdmin } from '../helpers'
/**
* Returns a middleware handler to check if advanced configuration is not disabled
* @param options Peertube server options
* @returns middleware function
*/
function checkUserIsAdminMiddleware (options: RegisterServerOptions): RequestPromiseHandler {
return async (req: Request, res: Response, next: NextFunction) => {
const logger = options.peertubeHelpers.logger
if (!await isUserAdmin(options, res)) {
logger.warn('Current user tries to access a page only allowed for admins, and has no right.')
res.sendStatus(403)
return
}
logger.debug('User is admin, can access the page..')
next()
}
}
export {
checkUserIsAdminMiddleware
}

@ -18,6 +18,7 @@ import { getRemoteServerInfosDir } from '../federation/storage'
import { BotConfiguration } from '../configuration/bot'
import { debugMucAdmins } from '../debug'
import { ExternalAuthOIDC } from '../external-auth/oidc'
import { listModFirewallFiles } from '../firewall/config'
async function getWorkingDir (options: RegisterServerOptions): Promise<string> {
const peertubeHelpers = options.peertubeHelpers
@ -139,7 +140,8 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise<Pro
execCtl,
execCtlArgs,
appImageToExtract,
appImageExtractPath
appImageExtractPath,
modFirewallFiles: path.resolve(dir, 'mod_firewall_config')
}
}
@ -185,7 +187,8 @@ async function getProsodyConfig (options: RegisterServerOptionsV5): Promise<Pros
'auto-ban-anonymous-ip',
'federation-dont-publish-remotely',
'disable-channel-configuration',
'chat-terms'
'chat-terms',
'prosody-firewall-enabled'
])
const valuesToHideInDiagnostic = new Map<string, string>()
@ -379,6 +382,13 @@ async function getProsodyConfig (options: RegisterServerOptionsV5): Promise<Pros
config.usePoll()
if (settings['prosody-firewall-enabled'] === true) {
const modFirewallFiles = await listModFirewallFiles(options, paths.modFirewallFiles)
// We load the module, even if there is no configuration file.
// So we will be sure that a Prosody reload is enought to take into account any change.
config.useModFirewall(modFirewallFiles)
}
config.useTestModule(apikey, testApiUrl)
const debugMucAdminJids = debugMucAdmins(options)

@ -553,6 +553,15 @@ class ProsodyConfigContent {
this.muc.set('poll_string_vote_instructions', loc('poll_vote_instructions_xmpp'))
}
/**
* Enable mod_firewall.
* @param files file paths to load (ordered)
*/
useModFirewall (files: string[]): void {
this.global.add('modules_enabled', 'firewall')
this.global.set('firewall_scripts', files)
}
addMucAdmins (jids: string[]): void {
for (const jid of jids) {
this.muc.add('admins', jid)

@ -22,6 +22,7 @@ interface ProsodyFilePaths {
execCtlArgs: string[]
appImageToExtract?: string
appImageExtractPath: string
modFirewallFiles: string
}
export {

@ -14,6 +14,7 @@ import { initFederationServerInfosApiRouter } from './api/federation-server-info
import { initConfigurationApiRouter } from './api/configuration'
import { initPromoteApiRouter } from './api/promote'
import { initEmojisRouter } from './emojis'
import { initAdminFirewallApiRouter } from './api/admin/firewall'
/**
* Initiate API routes
@ -45,6 +46,8 @@ async function initApiRouter (options: RegisterServerOptions): Promise<Router> {
await initPromoteApiRouter(options, router)
await initEmojisRouter(options, router)
await initAdminFirewallApiRouter(options, router)
if (isDebugMode(options)) {
// Only add this route if the debug mode is enabled at time of the server launch.
// Note: the isDebugMode will be tested again when the API is called.

@ -0,0 +1,81 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { RegisterServerOptions } from '@peertube/peertube-types'
import type { Router, Request, Response, NextFunction } from 'express'
import type { AdminFirewallConfiguration } from '../../../../../shared/lib/types'
import { asyncMiddleware, RequestPromiseHandler } from '../../../middlewares/async'
import { checkUserIsAdminMiddleware } from '../../../middlewares/is-admin'
import {
getModFirewallConfig, sanitizeModFirewallConfig, saveModFirewallConfig, canEditFirewallConfig
} from '../../../firewall/config'
import { getProsodyFilePaths, writeProsodyConfig } from '../../../prosody/config'
import { reloadProsody } from '../../../prosody/ctl'
function canEditFirewallConfigMiddleware (options: RegisterServerOptions): RequestPromiseHandler {
return async (req: Request, res: Response, next: NextFunction) => {
if (!await canEditFirewallConfig(options)) {
options.peertubeHelpers.logger.info('Firewall configuration editing is disabled')
res.sendStatus(403)
return
}
next()
}
}
async function initAdminFirewallApiRouter (options: RegisterServerOptions, router: Router): Promise<void> {
const logger = options.peertubeHelpers.logger
router.get('/admin/firewall', asyncMiddleware([
checkUserIsAdminMiddleware(options),
canEditFirewallConfigMiddleware(options),
async (req: Request, res: Response, _next: NextFunction): Promise<void> => {
try {
const prosodyPaths = await getProsodyFilePaths(options)
const result: AdminFirewallConfiguration = await getModFirewallConfig(options, prosodyPaths.modFirewallFiles)
res.status(200)
res.json(result)
} catch (err) {
options.peertubeHelpers.logger.error(err)
res.sendStatus(500)
}
}
]))
router.post('/admin/firewall', asyncMiddleware([
checkUserIsAdminMiddleware(options),
canEditFirewallConfigMiddleware(options),
async (req: Request, res: Response, _next: NextFunction): Promise<void> => {
try {
const prosodyPaths = await getProsodyFilePaths(options)
let data: AdminFirewallConfiguration
try {
data = await sanitizeModFirewallConfig(options, req.body)
} catch (err) {
logger.error(err)
res.sendStatus(400)
return
}
await saveModFirewallConfig(options, prosodyPaths.modFirewallFiles, data)
logger.info('Just saved a new mod_firewall const, must rewrite Prosody configuration file, and reload Prosody.')
await writeProsodyConfig(options)
await reloadProsody(options)
const result: AdminFirewallConfiguration = await getModFirewallConfig(options, prosodyPaths.modFirewallFiles)
res.status(200)
res.json(result)
} catch (err) {
options.peertubeHelpers.logger.error(err)
res.sendStatus(500)
}
}
]))
}
export {
initAdminFirewallApiRouter
}

@ -11,6 +11,7 @@ import { ExternalAuthOIDC, ExternalAuthOIDCType } from './external-auth/oidc'
import { Emojis } from './emojis'
import { LivechatProsodyAuth } from './prosody/auth'
import { loc } from './loc'
import { canEditFirewallConfig } from './firewall/config'
const escapeHTML = require('escape-html')
type AvatarSet = 'sepia' | 'cat' | 'bird' | 'fenec' | 'abstract' | 'legacy' | 'none'
@ -27,7 +28,7 @@ async function initSettings (options: RegisterServerOptions): Promise<void> {
initAdvancedChannelCustomizationSettings(options)
initChatBehaviourSettings(options)
initThemingSettings(options)
initChatServerAdvancedSettings(options)
await initChatServerAdvancedSettings(options)
await ExternalAuthOIDC.initSingletons(options)
const loadOidcs = (): void => {
@ -555,7 +556,9 @@ function initThemingSettings ({ registerSetting }: RegisterServerOptions): void
* Registers settings related to the "Chat server advanded settings" section.
* @param param0 server options
*/
function initChatServerAdvancedSettings ({ registerSetting }: RegisterServerOptions): void {
async function initChatServerAdvancedSettings (options: RegisterServerOptions): Promise<void> {
const { registerSetting } = options
registerSetting({
name: 'prosody-advanced',
type: 'html',
@ -723,6 +726,23 @@ function initChatServerAdvancedSettings ({ registerSetting }: RegisterServerOpti
private: true,
descriptionHTML: loc('prosody_components_list_description')
})
registerSetting({
name: 'prosody-firewall-enabled',
label: loc('prosody_firewall_label'),
type: 'input-checkbox',
default: false,
private: true,
descriptionHTML: loc('prosody_firewall_description')
})
if (await canEditFirewallConfig(options)) {
registerSetting({
type: 'html',
name: 'prosody-firewall-configure-button',
private: true,
descriptionHTML: loc('prosody_firewall_configure_button')
})
}
}
export {

@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
// Note: API request body size is limited to 100Kb (expressjs body-parser defaut limit, and Peertube nginx config).
// So we must be sure to never send more than 100Kb.
// All files are sent in one JSON object.
export const maxFirewallFileSize: number = 3 * 1024
export const maxFirewallFiles = 20
export const maxFirewallNameLength = 20
export const firewallNameRegexp = /^[a-zA-Z0-9_-]+$/

@ -192,6 +192,17 @@ interface LivechatToken {
date: number
}
interface AdminFirewallConfigurationFile {
name: string
content: string
enabled: boolean
}
interface AdminFirewallConfiguration {
enabled: boolean
files: AdminFirewallConfigurationFile[]
}
export type {
ConverseJSTheme,
InitConverseJSParams,
@ -212,5 +223,7 @@ export type {
ChannelEmojis,
ChannelEmojisConfiguration,
ProsodyAuthentInfos,
LivechatToken
LivechatToken,
AdminFirewallConfiguration,
AdminFirewallConfigurationFile
}

@ -1,7 +1,7 @@
---
title: "Advanced usage"
description: "Some advanced features"
weight: 20
weight: 40
chapter: false
---

@ -0,0 +1,53 @@
---
title: "Prosody mod_firewall"
description: "Advanced firewall rules for the Prosody server"
weight: 30
chapter: false
---
{{% notice info %}}
This feature comes with the livechat plugin version 11.0.0.
{{% /notice %}}
You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server.
Doing so, Peertube admins will be able to define advanced firewall rules.
{{% notice warning %}}
These rules could be used to run arbitrary code on the server.
If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`).
This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin.
You can still use mod_firewall by editing files directly on the server.
{{% /notice %}}
## Edit rules
First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings).
Just bellow the settings, you will find a "Configure mod_firewall" button.
This button will open a configuration page.
![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)
Here you can add several configuration files.
You can enable/disable each files.
Files will be loaded in the alphabetical order.
You can use a number as prefix to easily choose the order.
{{% notice info %}}
You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory.
File names must only contains alphanumerical characters, underscores and hyphens.
The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file.
Please be sure that the peertube system user has write access to these files, else the web editing interface will fail.
{{% /notice %}}
When you save the configuration, the server will automatically reload it, and your rules will apply immediatly.
You can check that there is no parsing error in the Prosody error log.
To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors.
## Examples
Don't hesitate to share your rules.
To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation).

@ -254,3 +254,9 @@ More informations on Prosody external components [here](https://prosody.im/doc/c
#### {{% livechat_label prosody_components_list_label %}}
{{% livechat_label prosody_components_list_description %}}
### {{% livechat_label prosody_firewall_label %}}
You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server.
For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/).

Binary file not shown.

After

(image error) Size: 101 KiB

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2024-01-17 11:38+0000\n"
"Last-Translator: ButterflyOfFire <butterflyoffire@protonmail.com>\n"
"Language-Team: Arabic <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/ar/>\n"
@ -1859,6 +1859,98 @@ msgstr ""
msgid "Admin documentation"
msgstr "المستندات"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2129,6 +2221,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, fuzzy, no-wrap
@ -3344,12 +3441,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Catalan <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/ca/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Czech <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/cs/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2024-08-07 07:41+0000\n"
"Last-Translator: Victor Hampel <v.hampel@users.noreply.weblate.framasoft.org>\n"
"Language-Team: German <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/de/>\n"
@ -1921,6 +1921,105 @@ msgstr "Plugin Peertube Livechat Administation"
msgid "Admin documentation"
msgstr "Admin Dokumentation"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr "Diese Funktion wird mit dem Livechatplugin Version 11.0.0 verfügbar sein."
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy, no-wrap
#| msgid "Edit tasks"
msgid "Edit rules"
msgstr "Aufgaben bearbeiten"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "Check the help for [this setting](/peertube-plugin-livechat/documentation/admin/settings/) for more information."
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr "Weitere Informationen finden Sie in der Hilfe für [diese Einstellung](/peertube-plugin-livechat/de/documentation/admin/settings/)."
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "![Timers configuration](/peertube-plugin-livechat/images/bot_quotes.png?classes=shadow,border&height=200px)"
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr "[Konfiguration der Timer](/peertube-plugin-livechat/images/bot_quotes.png?classes=shadow,border&height=200px)"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "Here you can configure:"
msgid "Here you can add several configuration files."
msgstr "Hier können Sie konfigurieren:"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2193,6 +2292,13 @@ msgstr "Diese Funktion könnte für die Verbindung von Brücken oder Bots genutz
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr "Weitere Informationen zu den externen Komponenten von Prosody finden Sie [hier](https://prosody.im/doc/components)."
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
#, fuzzy
#| msgid "For the user documentation, see [user documentation](/peertube-plugin-livechat/documentation/user/viewers/)"
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr "Für die Benutzerdokumentation, siehe [Benutzerdokumentation](/peertube-plugin-livechat/de/documentation/user/viewers/)"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3417,12 +3523,6 @@ msgstr "Es gibt verschiedene Rollen, die Benutzern in Chaträumen zugewiesen wer
msgid "You can promote users as moderators, if you need some help."
msgstr "Sie können Benutzer zu Moderatoren befördern, wenn Sie Hilfe benötigen."
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr "Diese Funktion wird mit dem Livechatplugin Version 11.0.0 verfügbar sein."
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#, fuzzy

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Greek <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/el/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -2089,6 +2089,111 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
#, markdown-text
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
#, markdown-text
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, markdown-text
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2399,6 +2504,12 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
#, markdown-text
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3765,13 +3876,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
#, markdown-text
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#, markdown-text

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Esperanto <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/eo/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2024-04-16 21:38+0000\n"
"Last-Translator: rnek0 <rnek0@users.noreply.weblate.framasoft.org>\n"
"Language-Team: Spanish <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/es/>\n"
@ -1889,6 +1889,98 @@ msgstr ""
msgid "Admin documentation"
msgstr "Redactar la documentación"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2159,6 +2251,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, fuzzy, no-wrap
@ -3375,12 +3472,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Basque <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/eu/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Persian <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/fa/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Finnish <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/fi/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -7,11 +7,10 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2024-08-12 11:25+0000\n"
"Last-Translator: John Livingston <git@john-livingston.fr>\n"
"Language-Team: French <https://weblate.framasoft.org/projects/"
"peertube-livechat/peertube-plugin-livechat-documentation/fr/>\n"
"Language-Team: French <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/fr/>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1940,6 +1939,105 @@ msgstr "Administration du Plugin Peertube Livechat"
msgid "Admin documentation"
msgstr "Documentation administrateur⋅rice"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr "Cette fonctionnalité arrive avec le plugin livechat version 11.0.0."
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy, no-wrap
#| msgid "Edit tasks"
msgid "Edit rules"
msgstr "Modifier les tâches"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "Check the help for [this setting](/peertube-plugin-livechat/documentation/admin/settings/) for more information."
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr "Veuillez vous référer à la page d'aide [pour ce paramètre](/peertube-plugin-livechat/fr/documentation/admin/settings)."
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "![Timers configuration](/peertube-plugin-livechat/images/bot_quotes.png?classes=shadow,border&height=200px)"
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr "![Configuration des messages pré-enregistrés](/peertube-plugin-livechat/images/bot_quotes.png?classes=shadow,border&height=200px)"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "Here you can configure:"
msgid "Here you can add several configuration files."
msgstr "Ici vous pouvez configurer :"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2212,6 +2310,13 @@ msgstr "Cette fonction pourrait être utilisée pour connecter des ponts ou des
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr "Plus d'informations sur les composants externes de Prosody [ici] (https://prosody.im/doc/components)."
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
#, fuzzy
#| msgid "For the user documentation, see [user documentation](/peertube-plugin-livechat/documentation/user/viewers/)"
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr "Pour la documentation utilisateur⋅rice, veuillez vous référer à la page [de documentation utilisateur⋅rice](/peertube-plugin-livechat/fr/documentation/user/viewers/)"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3436,28 +3541,15 @@ msgstr "Il y a différents rôles qui peuvent être assignés aux utilisateur⋅
msgid "You can promote users as moderators, if you need some help."
msgstr "Vous pouvez promouvoir des utilisateur⋅rices en tant que modérateur⋅rices, si vous avez besoin d'aide."
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr "Cette fonctionnalité arrive avec le plugin livechat version 11.0.0."
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."
msgstr ""
"Il est possible d'anonymiser les actions de modération, afin d'éviter de "
"divulguer qui bannit/expulse/... les participant⋅es."
msgstr "Il est possible d'anonymiser les actions de modération, afin d'éviter de divulguer qui bannit/expulse/... les participant⋅es."
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "To enable or disable this feature, use the [chat dropdown menu](/peertube-plugin-livechat/documentation/user/viewers), open the \"configure\" menu. In the form, you will find a \"{{% livechat_label livechat_configuration_channel_anonymize_moderation_label %}}\" checkbox."
msgstr ""
"Pour activer ou désactiver cette fonctionnalité, utilisez le [menu déroulant "
"du chat](/peertube-plugin-livechat/fr/documentation/user/viewers), puis "
"ouvrez le menu \"configurer\". Dans le formulaire, vous trouverez une case "
"à cocher \"{{% livechat_label "
"livechat_configuration_channel_anonymize_moderation_label %}}\"."
msgstr "Pour activer ou désactiver cette fonctionnalité, utilisez le [menu déroulant du chat](/peertube-plugin-livechat/fr/documentation/user/viewers), puis ouvrez le menu \"configurer\". Dans le formulaire, vous trouverez une case à cocher \"{{% livechat_label livechat_configuration_channel_anonymize_moderation_label %}}\"."
#. type: Title ##
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
@ -3468,9 +3560,7 @@ msgstr "Recherche dans l'historique des messages des participant⋅es"
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "As a room admin or owner, you can search all messages sent by a given participant."
msgstr ""
"En tant qu'administrateur⋅rice ou propriétaire d'un sallon, vous pouvez "
"rechercher tous les messages envoyés par un⋅e participant⋅e donné⋅e."
msgstr "En tant qu'administrateur⋅rice ou propriétaire d'un sallon, vous pouvez rechercher tous les messages envoyés par un⋅e participant⋅e donné⋅e."
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
@ -3480,23 +3570,17 @@ msgstr "Pour ce faire, plusieurs possibilités s'offrent à vous:"
#. type: Bullet: '* '
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "using the \"{{% livechat_label search_occupant_message %}}\" action in the dropdown menu besides participants in the sidebar"
msgstr ""
"utiliser l'action \"{{% livechat_label search_occupant_message %}}\" dans le "
"menu déroulant à côté des participant⋅es dans la barre latérale"
msgstr "utiliser l'action \"{{% livechat_label search_occupant_message %}}\" dans le menu déroulant à côté des participant⋅es dans la barre latérale"
#. type: Bullet: '* '
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "using the \"{{% livechat_label search_occupant_message %}}\" action in the dropdown menu besides chat messages"
msgstr ""
"utilisation de l'action \"{{% livechat_label search_occupant_message %}}\" "
"dans le menu déroulant à côté des messages de tchat"
msgstr "utilisation de l'action \"{{% livechat_label search_occupant_message %}}\" dans le menu déroulant à côté des messages de tchat"
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "![Message history search](/peertube-plugin-livechat/images/message_search.png?classes=shadow,border&height=200px)"
msgstr ""
"![Recherche dans l'historique des messages](/peertube-plugin-livechat/images/"
"message_search.png?classes=shadow,border&height=200px)"
msgstr "![Recherche dans l'historique des messages](/peertube-plugin-livechat/images/message_search.png?classes=shadow,border&height=200px)"
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
@ -3508,32 +3592,24 @@ msgstr "Pour avoir plus d'espace et une meilleure lisibilité, ouvrez le tchat e
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "In the search results, there are several informations that are shown at the right of the participant nickname:"
msgstr ""
"Dans les résultats de la recherche, plusieurs informations sont affichées à "
"droite du pseudo de la personne participante:"
msgstr "Dans les résultats de la recherche, plusieurs informations sont affichées à droite du pseudo de la personne participante:"
#. type: Bullet: '* '
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "if the current nickname is different than the nickname when the participant has sent the message, the original nickname will be shown"
msgstr ""
"si le pseudonyme actuel est différent du pseudonyme utilisé lorsque le⋅a "
"participant⋅e a envoyé le message, le pseudonyme original sera affiché"
msgstr "si le pseudonyme actuel est différent du pseudonyme utilisé lorsque le⋅a participant⋅e a envoyé le message, le pseudonyme original sera affiché"
#. type: Bullet: '* '
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "you will see the [JID (Jabber ID)](https://xmpp.org/extensions/xep-0029.html) of the participant"
msgstr ""
"vous verrez le [JID (Jabber ID)](https://xmpp.org/extensions/xep-0029.html) "
"de la personne participante"
msgstr "vous verrez le [JID (Jabber ID)](https://xmpp.org/extensions/xep-0029.html) de la personne participante"
#. type: Bullet: '* '
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "you will also see the [occupant-id](https://xmpp.org/extensions/xep-0421.html) of the participant"
msgstr ""
"vous verrez également l'[occupant](-id)[https://xmpp.org/extensions/xep-0421."
"html) de la personne participante"
msgstr "vous verrez également l'[occupant](-id)[https://xmpp.org/extensions/xep-0421.html) de la personne participante"
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Gaelic <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/gd/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Galician <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/gl/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2024-07-19 17:45+0000\n"
"Last-Translator: Milo Ivir <mail@milotype.de>\n"
"Language-Team: Croatian <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/hr/>\n"
@ -1858,6 +1858,104 @@ msgstr ""
msgid "Admin documentation"
msgstr "Dokumentacija za administratore"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
#, fuzzy
#| msgid "This feature comes with the livechat plugin version 10.0.0."
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr "Ova je funkcija dostupna s dodatkom za chat uživo verzije 10.0.0."
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "Check the help for [this setting](/peertube-plugin-livechat/documentation/admin/settings/) for more information."
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr "Za više informacija pogledaj stranicu pomoći za [ovu postavku](/peertube-plugin-livechat/hr/documentation/admin/settings/)."
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "![Moderation delay timer](/peertube-plugin-livechat/images/moderation_delay_timer.png?classes=shadow,border)"
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr "![Timer odgode moderiranja](/peertube-plugin-livechat/images/moderation_delay_timer.png?classes=shadow,border)"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2127,6 +2225,13 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
#, fuzzy
#| msgid "Check the help for [this setting](/peertube-plugin-livechat/documentation/admin/settings/) for more information."
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr "Za više informacija pogledaj stranicu pomoći za [ovu postavku](/peertube-plugin-livechat/hr/documentation/admin/settings/)."
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3340,14 +3445,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
#, fuzzy
#| msgid "This feature comes with the livechat plugin version 10.0.0."
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr "Ova je funkcija dostupna s dodatkom za chat uživo verzije 10.0.0."
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Hungarian <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/hu/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Icelandic <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/is/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 14:21+0000\n"
"Last-Translator: John Livingston <git@john-livingston.fr>\n"
"Language-Team: Italian <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/it/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2024-03-10 20:38+0000\n"
"Last-Translator: \"T.S\" <fusen@users.noreply.weblate.framasoft.org>\n"
"Language-Team: Japanese <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/ja/>\n"
@ -1875,6 +1875,101 @@ msgstr "クレジット"
msgid "Admin documentation"
msgstr "ドキュメンテーション"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr "PeerTube ライブチャットプラグイン"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, fuzzy
#| msgid "![Fullscreen chat screenshot](/peertube-plugin-livechat/images/fullscreen.png?classes=shadow,border&height=200px)"
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr "![チャット画面のスクリーンショット](/peertube-plugin-livechat/images/chat.png?classes=shadow,border&height=200px)"
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, fuzzy, no-wrap
@ -2158,6 +2253,12 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
#, fuzzy
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr "PeerTube ライブチャットプラグイン"
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, fuzzy, no-wrap
@ -3440,12 +3541,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Kabyle <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/kab/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Norwegian Bokmål <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/nb_NO/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Dutch <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/nl/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Norwegian Nynorsk <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/nn/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Occitan <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/oc/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Polish <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/pl/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Portuguese <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/pt/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Russian <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/ru/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Albanian <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/sq/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Swedish <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/sv/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:52+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Thai <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/th/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:53+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Toki Pona <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/tok/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -1837,6 +1837,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2106,6 +2198,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3317,12 +3414,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/ occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:53+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Ukrainian <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/uk/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:53+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Vietnamese <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/vi/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:53+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Chinese (Simplified) <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/zh_Hans/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: peertube-plugin-livechat-documentation VERSION\n"
"POT-Creation-Date: 2024-08-12 12:08+0200\n"
"POT-Creation-Date: 2024-08-13 10:29+0200\n"
"PO-Revision-Date: 2023-07-17 10:53+0000\n"
"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Chinese (Traditional) <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/zh_Hant/>\n"
@ -1856,6 +1856,98 @@ msgstr ""
msgid "Admin documentation"
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Advanced firewall rules for the Prosody server"
msgstr ""
#. type: Yaml Front Matter Hash Value: title
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Prosody mod_firewall"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "You can enable [mod_firewall](https://modules.prosody.im/mod_firewall) on your Prosody server."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Doing so, Peertube admins will be able to define advanced firewall rules."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "These rules could be used to run arbitrary code on the server. If you are a hosting provider, and you don't want to allow Peertube admins to write such rules, you can disable the online editing by creating a `disable_mod_firewall_editing` file in the plugin directory (`plugins/data/peertube-plugin-livechat/disable_mod_firewall_editing`). This is opt-out, as Peertube admins can already run arbitrary code just by installing any plugin. You can still use mod_firewall by editing files directly on the server."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Edit rules"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "First, you must enable the feature in the [plugin settings](/peertube-plugin-livechat/documentation/admin/settings)."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Just bellow the settings, you will find a \"Configure mod_firewall\" button. This button will open a configuration page."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "![Mod_firewall configuration](/peertube-plugin-livechat/images/mod_firewall.png?classes=shadow,border&height=400px)"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Here you can add several configuration files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can enable/disable each files."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Files will be loaded in the alphabetical order. You can use a number as prefix to easily choose the order."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "You can also edit these firewall rules directly on the server, in the `plugins/data/peertube-plugin-livechat/prosody/mod_firewall_config/` directory. File names must only contains alphanumerical characters, underscores and hyphens. The extension must be `.pfw`, or `.pfw.disabled` if you want to disable a file. Please be sure that the peertube system user has write access to these files, else the web editing interface will fail."
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "When you save the configuration, the server will automatically reload it, and your rules will apply immediatly. You can check that there is no parsing error in the Prosody error log. To do so, you can read the `plugins/data/peertube-plugin-livechat/prosody/prosody.err` file, or use the [diagnostic tool](/peertube-plugin-livechat/documentation/installation/troubleshooting/) that will show last Prosody errors."
msgstr ""
#. type: Title ##
#: support/documentation/content/en/documentation/admin/mod_firewall.md
#, no-wrap
msgid "Examples"
msgstr ""
#. type: Plain text
#: support/documentation/content/en/documentation/admin/mod_firewall.md
msgid "Don't hesitate to share your rules. To do so, you can for example edit this [page](/peertube-plugin-livechat/contributing/document/#write-documentation)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: build/documentation/pot_in/documentation/admin/settings.md
#, no-wrap
@ -2125,6 +2217,11 @@ msgstr ""
msgid "More informations on Prosody external components [here](https://prosody.im/doc/components)."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/admin/settings.md
msgid "For more information, please check [the documentation](/peertube-plugin-livechat/documentation/admin/mod_firewall/)."
msgstr ""
#. type: Yaml Front Matter Hash Value: description
#: support/documentation/content/en/documentation/_index.md
#, no-wrap
@ -3336,12 +3433,6 @@ msgstr ""
msgid "You can promote users as moderators, if you need some help."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
#: support/documentation/content/en/documentation/user/streamers/moderation_notes.md
msgid "This feature comes with the livechat plugin version 11.0.0."
msgstr ""
#. type: Plain text
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
msgid "It is possible to anonymize moderation actions, to avoid disclosing who is banning/kicking/… occupants."