APBoard v3.0.1-rc.2 released Read more

Changelog

Version history and release notes for APBoard v3.

View on GitLab

Changelog

All notable changes to APBoard are documented in this file.

Format based on Keep a Changelog, versioning follows Semantic Versioning.


[3.0.1-rc.2] - 2026-06-29

Added

  • apbcli: Full interactive setup wizard
  • apbcli: CLI tool for board administration (user/package/db/config/forum/system management)
  • Docker: APBOARD_FIRST_ADMIN_NAME env var to set admin display name on first start
  • Install ping to count active installations (weekly, anonymous, HMAC-signed)

Changed

  • Docker entrypoint: Admin user initialization now performed by php apbcli install:admin instead of the removed setup/docker-init.php

Fixed

  • Web installer: PHP version check corrected from 8.0 to 8.5
  • Web installer: added missing intl and zip extension checks
  • Docs: corrected Docker setup step 7 to reference apbcli install:admin

Removed

  • setup/docker-init.php: Admin init logic fully replaced by apbcli install:admin
  • Profile visibility privacy setting: Users can now restrict their profile page, pinboard, and activity feed to logged-in members only
  • APBoard Package System
  • Plugin unit tests: Options, Permissions, Language, Assets, Cron, Migrations
  • Developer documentation under docs/packages/

Changed

  • Profile area (all 5 stylesets): Removed left sidebar; replaced with a full-width card featuring a horizontal scrollable tab navigation.
  • Moderator area (all 5 stylesets): Removed left sidebar; replaced with a full-width card featuring a horizontal tab navigation
  • Admin area (all 5 stylesets): Replaced flat link list with a grouped, icon-based sticky sidebar .
  • Dark-mode overrides (sets 4 & 5): Removed stale sidebar gradient and link-colour rules for profile/admin/mod sidebars.
  • Admin sidebar reduced from 310 px to 220 px to give more room to the content area.

Fixed

  • Package language importer now skips language files whose DB table does not exist (language not installed on this instance)
  • Plugin JS assets now render correctly.

[3.0.1-rc.1] - 2026-06-27

Added

  • Browser and app push notifications
  • User ignore and follow controls
  • Moderator-only user notes on the moderation user detail page
  • Accepted-answer marking for solved support topics

Fixed

  • Push settings in all stylesets
  • Push migration with stale vendor files
  • Message inbox and trash count queries missing a bind parameter

[3.0.0] - 2026-06-26

Changed

  • Version bump from 3.0.0-rc.2 to 3.0.0

Fixed

  • Docker Hub CI login uses --password-stdin (non-TTY fix)
  • CI dind TLS/port mismatch; add QEMU for multi-platform builds
  • Missing navigation_link_* translations for online list (forgot, 2fa, banned etc.)

[3.0.0-rc.2] - 2026-06-26

Added

  • Password strength meter (real-time, client-side) on registration and profile password-change pages
  • Production Docker image for Docker Hub distribution
  • CI pipeline publishes multi-platform image on release tags
  • docker-compose.hub.yml for Docker Hub installations

Changed

  • Password policy enforced: 8–100 chars, upper+lower, digit, special character
  • Rewrote LAMP and Docker installation guides

Fixed

  • resources/klaro missing from release ZIP
  • Klaro symlink missing from web installer and LAMP docs

[3.0.0-rc.2] - 2026-06-25

Security

  • Fix SSRF in ActivityPub: central apb_AP_ValidateOutboundUrl() resolves DNS and blocks all private/reserved IP ranges (RFC1918, loopback, link-local, ULA, metadata) before every outbound cURL call
  • Fix APB-SEC-004: defederation policy now applies to inbox URI, shared-inbox URI, and avatar URL host - not just the actor domain
  • Fix APB-SEC-002: shared inbox /ap/inbox enforces 64 KB payload limit via Content-Length and actual body length before parsing JSON
  • Fix APB-SEC-005: setup wizard supports APB_SETUP_TOKEN env var to gate access
  • Fix APB-SEC-006: profile homepage validates scheme (http/https only); javascript:/data: URIs are rejected
  • Fix FINDING-01: remove htmlspecialchars() on password before password_verify() - raw input required for correct bcrypt verification
  • Fix FINDING-02: escape LIKE metacharacters (%, _) in search queries to prevent wildcard injection
  • Fix APB-SEC-007: rate-limit autocomplete endpoints (search_users, search_topics) - 60 req/60 s per IP; new apb_search_attempts table
  • Fix FINDING-06: data-href click handler enforces same-origin navigation in all three stylesets; external URLs are silently ignored
  • Add @deprecated annotations and security warnings to legacy raw-query methods in db_mysql.php
  • Document non-image upload MIME+extension-only protection and admin raw-HTML field security implications

Fixed

  • Avatar-cache migration: add missing apb_AP_Config.php include for fresh installs

[3.0.0-rc.1] - 2026-06-25

Security

  • Nonce-basierte Content Security Policy - kein unsafe-inline mehr für Scripts
  • Alle Inline-Event-Handler durch CSP-sichere data-Attribute ersetzt

[3.0.0-beta.6] - 2026-06-25

Fixed

  • GDPR export: all ZIP content now fully translated, no hardcoded German
  • GDPR export: ZIP filename changed to apboard-gdpr-*.zip
  • GDPR export: ZIP files renamed to English (access-notice.md, profile.md, etc.)
  • GDPR export: stat labels in template now use translation system
  • GDPR export: revoked warning check uses correct revoked flag

[3.0.0-beta.5] - 2026-06-25

Added

  • User Ranks: 13 Stufen basierend auf Post-Anzahl
  • Rank-Badge + Post-Count in Reply-Sidebar und Nutzerprofil
  • Admin: User-Ranks CRUD unter /admin/ranks/
  • Admin Settings: Ränge global aktivierbar/deaktivierbar
  • Honeypot-Feld bei Registrierung gegen Bots
  • Disposable-E-Mail-Blockliste (~400 bekannte Wegwerfanbieter)
  • DSGVO-Datenexport: ZIP mit Profil, Beiträgen, PMs, Pinboard (Art. 15 & 20)

[3.0.0-beta.4] - 2026-06-25 (continued)

Changed

  • Mobile: Boardinfos und letzter Beitrag jetzt sichtbar
  • Mobile: Topic-Titel wird abgekürzt
  • Mobile: Schriftgröße in „Last Topics" angepasst
  • Mobile: Topic-Stats und letzter Reply jetzt sichtbar
  • Mobile: Abstand und Icon-Ausrichtung in Topics verbessert
  • Mobile: Reaction-Picker Position korrigiert
  • Profil-Infos in Replies kompakter und moderner gestaltet
  • Mobile: Profil-Header als Flexbox mit Meta-Chips
  • Homepage-URL jetzt sichtbar (nicht nur Icon)
  • Back-to-top Button modernisiert: rund, FA-Icon, Hover-Animation

Added

  • Cookie-Banner via Klaro (lokal, keine externen Requests)
  • ToS-Seite: neue Legal-Page, im Admin konfigurierbar
  • Inline-Bulk-Moderation: Checkbox-Mehrfachauswahl im Mod-Panel
  • Topics: Bulk-Delete, Bulk-Pin/Unpin, Bulk-Lock/Unlock
  • Posts: Bulk-Delete (erste Posts und einzige Posts werden übersprungen)
  • Bulk-Toolbar erscheint dynamisch beim ersten Tick, verschwindet wieder
  • Select-All-Checkbox mit Indeterminate-State im Tabellenkopf

[3.0.0-beta.4] - 2026-06-24

Added

  • Emoji reactions: the single "Like" feature has been completely replaced by a full six-emoji reaction system
  • Warning system: a structured moderation tool
  • Two-Factor Authentication (TOTP/RFC 6238)
  • Thread Move: moderators can move a topic and all its replies to any other board
  • Thread Merge: moderators can merge a secondary topic into a primary topic
  • Thread Split: moderators can extract selected replies from a topic into a new topic

Fixed

  • Reaction notifications
  • the "Back to user" link was rendered unconditionally
  • the submit-button confirm dialog
  • warnings overview query
  • 2FA challenge page
  • Warning system
  • Ban enforcement: banned users were not stopped at login
  • Mute enforcement: muted users could still send private messages, edit their profile bio/infotext/signature, and post to their pinboard

Build

  • PHPStan memory limit in CI raised from 256 M to 512 M

[3.0.0-beta.3] - 2026-06-24

Added

  • Word filter system
  • @Mention system
  • New topic form layout unified with all other content pages
  • Poll system
  • Logout link added to the bottom of the profile sidebar
  • Logout icon added to the right of the welcome string in the subheader bar
  • New public statistics page
  • The username in the subheader welcome string ("Welcome Christin!") is now a link to the user's own public profile
  • Moderators and admins now see a red badge with the count of unresolved reports on the "Moderator" top-navigation link and on the "Reports" entry in the mod-area sidebar;

Fixed

  • Reporting a post showed a JavaScript error popup
  • Mod area post edit no longer silently discards edit-tracking metadata
  • Broadcast detail page now renders with the same styled card layout as the About/Legal pages
  • Admin and moderator post/topic listings now show the Fediverse handle (@user@domain) for ActivityPub-sourced content
  • Broadcast detail page now shows author name and publication date below the title
  • Collation mismatch caused 500 errors on mod dashboard, mod/admin posts and mod/admin topics
  • Public user profile now displays the username in white with a subtle text-shadow
  • "Last activity here:" on user profiles and the Profile Preview was always empty
  • Profile sidebar navigation now highlights the currently active page
  • Statistics page showed incorrect post count

Build

  • minified Chart.js build was causing CI to fail with a "file appears to be minified" warning (exit code 1)

[3.0.0-beta.3] - 2026-06-23

Added

  • Profile Preview page shows the logged-in user's own profile exactly as other members see it, including all privacy filters applied
  • "Profile Preview" link added at the top of the profile sidebar navigation across all three stylesets

Changed

  • Navigation: "Usermenu" renamed to "Profile" - links directly to /profile/preview/, no dropdown submenu
  • Navigation: "Admin" links directly to /admin/dashboard, no dropdown submenu
  • Navigation: "Moderator" links directly to /mod/dashboard, no dropdown submenu
  • Only the "Info" nav entry retains its dropdown submenu

[3.0.0-beta.2] - 2026-06-22 (continued)

Added

  • Forgot-password feature at /forgot/: users enter their email address and receive a time-limited reset link (30 minutes); the response is always identical regardless of whether the address is registered, preventing account enumeration
  • Rate limiting for the /forgot/ endpoint: max 3 requests per IP per 15 minutes
  • HTML email templates for account activation and password reset; both use inline-styled table-based layouts compatible with all common email clients
  • email_template_forgot_password_body and email_template_forgot_password_subject translation keys

Changed

  • Login, registration, and password-reset forms redesigned: dark header band with logo (using the styleset's --apb-dark color), merged input group styling, accent-colored submit button, and cross-navigation links (forgot password, register, back to sign in)
  • Message/confirmation box redesigned: accent-colored header for success, red header for error, SVG status icon, outlined back button; removed inline <style> hack and <p>&nbsp;</p> spacers
  • "Forgot your password?" link on the login form now points to /forgot/ instead of /password/
  • All outbound emails are now sent as HTML with a plain-text fallback; registration confirmation email updated to match the new styled layout
  • apb_password_resets tokens now carry a type field (registration vs reset) so the activation endpoint can apply the correct account-update logic for each flow

Fixed

  • Cross-navigation links on login form: "Forgot your password?" and "No account yet? Register"
  • Cross-navigation links on register form: "Already have an account? Sign in"
  • Back-to-login link on password-reset form

[3.0.0-beta.2] - 2026-06-22

Added

  • Broadcast-Nachrichten: Admins können Board-weite Hinweisbanner erstellen, aktivieren und verwalten; Besucher sehen eine Broadcast-Bar mit Link zur Detailseite
  • X-Robots-Tag: index, follow, archive wird gesendet wenn Suchmaschinen-Indexierung aktiv ist

Changed

  • robots.txt wird dynamisch generiert und funktioniert auf jedem Webserver ohne zusätzliche Konfiguration
  • Sitemap-Generator komplett neu gebaut: datenbankbasiert, kein HTTP-Crawling mehr, skaliert ohne Limits, alle öffentlichen Seiten korrekt abgedeckt
  • Sitemap ist an die Suchmaschinen-Indexierungs-Einstellung gekoppelt: wird beim Deaktivieren sofort gelöscht, beim Aktivieren neu generiert

Fixed

  • <h1>-Überschrift auf Broadcast-Detailseite (war fälschlicherweise <h2>)

3.0.0-alpha.3 - 2026-06-07 (continued fixes)

Added

User-editable posts

  • Regular users can edit their own posts within a 30-minute window; admins and moderators can edit any post at any time
  • Edit opens a TinyMCE modal (lazy-initialized on first use)
  • Subject is editable when editing the first post of a topic
  • Edit history shown in reply footer: editor name, edit count, and timestamp of last edit
  • New AJAX handlers: get_post_for_edit, save_edit_post
  • New database columns on apb_replies: edit_count, last_edited_at, last_edited_by

Forum statistics box

  • Full-width stats bar displayed below the category grid on the homepage
  • Shows: registered user count, users online (last 30 min), topic count, reply count, board count, newest member
  • Configurable via Admin → General Settings (apb_show_stats)

Subheader welcome message

  • Breadcrumb bar is now two-column: breadcrumbs on the left, "Welcome [username]!" on the right (logged-in users only)
  • Multilingual via apb_welcome_string translation key

Changed

  • Reply footer redesigned: renamed .reply-meta.reply-footer; likes and action buttons are now right-aligned (justify-content: flex-end); minimum height 33 px
  • .reply-content uses flex-direction: column so the footer is always pinned to the bottom of the card regardless of content length
  • #content background removed; individual board, topic, and reply list items now carry explicit white backgrounds, letting the page background show through between cards
  • Topic header redesigned: white card with border and box-shadow, flexbox layout with mod buttons and subscribe button aligned in a single row
  • Footer info text replaced with a short, factual description of APBoard

Fixed

  • TinyMCE edit modal was visible on page load due to missing display:none on the modal container
  • Edit info showed the post author instead of the actual editor
  • Edit info rendered raw <strong>Today</strong> HTML instead of plain text; fixed with strip_tags()
  • TinyMCE sub-dialogs (emoji picker, link dialog) rendered behind the edit modal overlay; fixed with .tox-tinymce-aux { z-index: 9500 !important }

Data consistency

  • Admin dashboard stat_replies (Replies card) incorrectly used COUNT(*) FROM replies, counting first posts as replies; now uses COALESCE(SUM(replies), 0) FROM topics - consistent with homepage stats box and boards.num_replies
  • topics.lastreply / lastreplyid / lastreplyuserid were never updated after a reply deletion; stale values broke board sort order (ORDER BY lastreply DESC) and read/unread tracking (last_read_at < lastreply); both delete_post handlers now call apb_RecalcTopicLastReply() after the delete
  • total_replies in the homepage forum stats box incorrectly counted first posts (topic text) as replies; now derived from SUM(topics.replies) which already excludes first posts by design
  • Admin delete_topic did not update board or category num_threads / num_replies counters; now mirrors the moderator path (fetch → clean up → delete → decrement)
  • Admin and moderator delete_post did not update the category num_replies counter; catid now included in the JOIN query and the missing UPDATE added
  • Admin and moderator delete_post and delete_topic did not recalculate lastpost / lastaction / lastuser on boards and categories after deletion; the board listing could reference a now-deleted reply indefinitely
  • Deleting a reply via delete_post did not remove its apb_statustable (like) entries; deleting a topic did not remove like entries for any of its replies - fixed in all four deletion paths
  • Deleting a topic did not remove apb_user_read_topics entries, leaving orphaned read-tracking rows; fixed in both delete_topic handlers
  • The delete_post guard only rejected requests when the reply was the sole post in the topic; a second reply still allowed deleting the first post (topic text) independently, which would orphan the topic; the guard now also blocks deletion of the first post by MIN(id) comparison

Topic deletion UX

  • The delete button on the first reply (topic text) in the topic view previously showed an error message; it now routes directly to delete_topic with a strongly worded multi-line confirmation warning (via a dedicated form action, not delete_post)

Topic view

  • is_first_post was determined by loop counter ($bcounter === 0), which misidentified the first visible reply on page 2+ as the topic opener; the correct first reply ID is now fetched once before the loop and compared by ID

Admin UI

  • AP federation handle input fields in the admin board-edit form stacked vertically instead of appearing inline; root cause was Bootstrap 5's flex-wrap: wrap on .input-group combined with a too-narrow max-width: 360px; fixed with flex-nowrap class and max-width: 480px on the outer wrapper
  • Topic link in the admin topics list used /topic/{id} which routed to a 404; corrected to /topic/view/{id}/ (both set_1 and set_2)
  • Reply link in the admin posts list used /topic/{id}#post{id} which routed to a 404; corrected to /topic/view/{id}/#apb-reply-{id}
  • Admin and moderator posts lists included first posts (topic openers) alongside actual replies, and attempting to delete them produced a confusing error; first posts are now excluded from both listings - they are managed exclusively via the Topics section

Added (post-release fixes)

  • apb_RecalcTopicLastReply(topicid) helper in libs/functions.php - queries the surviving reply with the highest createdat/id and writes lastreply, lastreplyid, lastreplyuserid on the topic; called by both delete_post handlers
  • apb_RecalcBoardLastPost(boardid, catid) helper in libs/functions.php - queries the most-recent surviving reply after any deletion and writes lastpost, lastaction, lastuser on the board and its parent category; resets all three to 0 when the board is empty
  • mod_confirm_delete_first_post translation key - strongly worded confirmation text shown when a mod/admin uses the delete button on the first post of a topic (which triggers full topic deletion)
  • admin_confirm_delete_topic translation key - proper warning dialog for the topic delete action in the admin panel, replacing the previous generic "Delete #N?" prompt

Changed (post-release fixes)

  • Newest Member stat box now uses a two-line layout (username above label) consistent with all other stat items (icon → value → label)

Chore

  • .phpunit.cache/ added to .gitignore and removed from version control

3.0.0-alpha.3 - 2026-06-07 (logging, bot detection, search engine indexing)

Added

Search Engine Indexing setting

  • New admin toggle in General Settings: "Search Engine Indexing"
  • When set to Disabled, every response carries X-Robots-Tag: noindex, nofollow, noarchive
  • New config key apb_robots_noindex (default 0 = indexing allowed)
  • New function apb_SendConfigHeaders() - config-dependent headers sent after apb_LoadConfig() instead of in apb_SendSecurityHeaders() (which runs before config is available)

Online-page summary line

  • Persistent summary above the user list: "N member(s), N guest(s), N bot(s) in the last 30 minutes"
  • Always visible - does not depend on any count being non-zero
  • engine/online.php now passes member_count, guest_count, and bot_count to templates

Bot detection

  • apb_UserOnlineHandler(): extended bot detection from curl/ only to ~35 patterns
  • Covered: Googlebot, Bingbot, YandexBot, Baiduspider, ClaudeBot, GPT-Bot, ChatGPT-User, CCBot, ByteSpider, PetalBot, AppleBot, AhrefsBot, SemrushBot, DotBot, MJ12Bot, BLEXBot, Screaming Frog and others
  • Monitoring bots: UptimeRobot, Pingdom, Site24x7, StatusCake
  • Social/messaging bots: LinkedInBot, TwitterBot, WhatsApp, Telegram, Discord, Slack, Pinterest
  • Fediverse crawlers / media cachers: Wafrn, Mastodon, Pleroma, Misskey, Pixelfed, Lemmy, Friendica, Akkoma, Calckey, Firefish, IceShrimp
  • Empty User-Agent treated as bot - no real browser omits the UA header
  • Detected bots are stored with isbot = 1; the online page filters them out of the user list and counts them separately

set_2 templates

  • online.html and online_user_entry.html added to set_2 (were missing entirely)

Fixed

  • Bot dedup was broken for sessionless crawlers: every request generated a new Guest#XXXXXX (new PHP session = new publicname), causing N rows per crawl; bots are now deduplicated by ipaddress only (isbot = 1 guard), so any number of pages crawled from the same IP produces exactly one online-table row
  • Guest dedup query tightened: AND isbot = 0 added so a human guest and a bot from the same IP are never merged into the same row

Chore

Access logging

  • Apache log format changed from combined (%h = Traefik internal IP) to proxy_combined (%{X-Forwarded-For}i %h …) - real client IPs now visible in the log
  • Persistent access log written to /var/log/apboard/access.log (second CustomLog directive alongside the existing stdout log); available on the host at deploy/logs/access.log
  • deploy/docker-compose.yml: added ./logs:/var/log/apboard volume
  • deploy/docker/entrypoint.sh: creates /var/log/apboard with www-data ownership on startup
  • deploy/.gitignore: logs/ excluded from version control

3.0.0-alpha.2 - 2026-06-06

Added

ActivityPub / Fediverse federation

  • Each board can be activated as an ActivityPub Group actor (/ap/board/{id})
  • WebFinger endpoint (/.well-known/webfinger) for handle-based actor discovery (@board@domain)
  • NodeInfo 2.0 endpoints (/.well-known/nodeinfo, /nodeinfo/2.0) for Fediverse directory listings
  • Outbound federation: new topics and replies are delivered as Create(Note) activities to all board followers via signed HTTP POST (parallel cURL fan-out with shared_inbox deduplication)
  • Inbound federation: Follow, Undo(Follow), Create(Note), Update(Note), Delete activities accepted and processed via /ap/board/{id}/inbox and shared inbox /ap/inbox
  • Remote actors cached locally (apb_ap_remote_actors); avatars downloaded, GD-re-encoded, and served from the local domain (no external image requests during browsing)
  • Per-board AP configuration: enable/disable federation, custom handle, manual follower approval, allow/deny inbound topics and replies
  • Emergency kill-switch (ap_force_disabled) disables all federation instantly without touching per-board settings
  • Admin UI: AP settings integrated into board edit form; follower list with domain, URI, accepted date, and kick action
  • Fediverse handle and follow link displayed in board header when AP is active
  • Dedicated AP endpoint router (public/ap.php) separate from the main request stack - no session, no Twig overhead for AP requests
  • Person actors for local users (/ap/user/{id}) with WebFinger support; required by Mastodon to resolve attributedTo on delivered notes
  • RSA-4096 key pairs generated per board actor and per user actor, stored in apb_ap_board_keys / apb_ap_user_keys
  • Delivery log (apb_ap_delivery_log) and outbox (apb_ap_outbox) for auditing sent activities
  • Instance blocklist (apb_ap_instance_blocks) with admin UI for defederation

Security

  • HTTP Signatures (Draft-Cavage-12) enforced on all inbound POST requests; unsigned requests rejected with HTTP 401
  • apb_AP_verifyRequest() returns the verified actor URI (derived from keyId), not just a boolean; callers must cross-validate against activity['actor'] - prevents impersonation and defederation bypass via spoofed actor field
  • Actor cross-validation in inbox: verified signing actor must equal activity['actor']; mismatch → HTTP 401
  • Activity id required on all inbound activities (AP spec §5.1); id-less activities rejected with HTTP 400 (replay protection requires a deduplication key)
  • Instance block check runs twice: preliminary on unverified body actor (fast path), definitive on cryptographically verified domain (closes spoofed-actor bypass)
  • SSRF protection on all outbound cURL: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS restricted to CURLPROTO_HTTPS, preventing redirect-based bypass of the HTTPS-only guard
  • Remote actor ID validation: fetched actor['id'] must match the requested URI; prevents cache poisoning via malicious actor documents
  • apb_SanitizeApHtml() - dedicated HTMLPurifier profile for inbound AP content; stricter than local-post allowlist (no img, no div, no tracking pixels)
  • attributedTo in inbound Create(Note) validated against the verified signing actor
  • Date header directional check (replaces abs()): future-dated requests beyond 60 s clock skew tolerance rejected, closing pre-signed replay window
  • Payload size hard limit: 64 KB; oversized inbox POST rejected with HTTP 413 before any processing
  • Rate limiting: 100 activities per 60-second window per verified remote domain
  • Custom board handles re-validated against [a-z0-9-] at read time; non-conforming DB values fall back to auto-generation

3.0.0-alpha.1 - 2023-06-12 - 2026-06-05

Complete rewrite of APBoard from scratch. Development started 12 June 2023. PHP 8.3, MariaDB, Twig templating, Composer. Licensed under GPL v3.

Added

Core forum

  • Category and board hierarchy with sort order and active/hidden flags
  • Board listing with topic count, reply count, last activity info
  • Topic view with paginated replies and breadcrumb navigation
  • New topic creation with rich text editor (TinyMCE)
  • Fast reply form inline in topic view
  • Topic subscriptions (subscribe/unsubscribe per topic)
  • Reply likes with per-user tracking and batch loading
  • Quote reply with automatic attribution
  • Pin and lock topics (admins/mods)
  • Board locking (prevents new topics from non-admins)
  • Read/unread tracking per user per topic (via apb_user_read_topics)
  • Unread indicators on boards and topics (bold + colored icon)
  • AJAX mark-as-read for individual topics and entire boards
  • Hot topics widget on homepage
  • Latest replies widget on homepage

Search

  • Full-text search across forum posts, pinboard, and user profiles
  • Filter by category: All / Posts / Pinboard / Users
  • Highlighted query terms in result excerpts
  • Clickable result rows with permalink icon

User accounts

  • Email-based registration with verification link
  • Login with generic error messages (no user enumeration)
  • Password reset via email with one-time token
  • Session management stored in database
  • Rate limiting on login, registration, and password reset

User profiles

  • Avatar upload and cover image upload (GD re-encoded, EXIF stripped)
  • Profile fields: birthday, city, country, zipcode, gender, bio, quote/signature
  • Social links: Homepage, Matrix, Mastodon, Friendica, Facebook, YouTube, Instagram
  • Per-field privacy settings (18+ toggles, three-state: hidden / members-only / public)
  • Post display preferences (show/hide group badge, reg date, gender, city, social icons)
  • Notification preferences (12 individual toggles)
  • Account settings: display name, email, language, theme, timezone, date/time format
  • Password change with current-password verification

Pinboard

  • Blog-style posts per user with title, subtitle, teaser, and rich text content
  • Teaser image upload with GD re-encoding
  • Draft/publish toggle
  • Edit and delete own posts

Private messaging

  • Folders: Inbox, Sent, Drafts, Trash
  • TinyMCE editor in compose view
  • Recipient autocomplete via AJAX
  • Reply with automatic quoting, Forward with original-message header
  • Save as draft, edit and send draft later
  • Auto-mark-as-read on open
  • Bulk actions: mark read/unread, move to trash, restore, permanently delete
  • Empty trash action
  • Unread count badge in navigation
  • Privacy setting: allow/deny incoming messages per user
  • Rate limiting: max 30 messages per 60 minutes

Members & community

  • Member directory with username search
  • Sort by name, registration date, last login, last post date, post count
  • Admin-configurable guest visibility for member list and online list
  • Who's online list (last 30 minutes, with last-seen location)

Moderation

  • Moderator panel: user list with ban/mute status badges
  • Ban user (moves to group 4, stores previous group, invalidates all sessions)
  • Unban user (restores previous group)
  • Mute user (time-limited: 1h/12h/24h/7d/30d, or permanent)
  • Unmute user
  • Mods cannot ban/mute other mods or admins
  • Topic management: pin, lock, edit subject, delete
  • Post management: edit content (TinyMCE), delete single post
  • Inline mod buttons in topic view (header and per-reply)
  • Report system: users can report posts with optional reason
  • Mod panel reports queue: resolve or dismiss reports

Administration

  • Admin dashboard with total stats (users, boards, topics, replies)
  • User management: list, search, edit, delete (anonymizes posts)
  • User group management: custom groups with permission flags
  • Category management: create, edit, delete
  • Board management: create, edit, delete, lock/unlock
  • Topic and post management with delete and toggle actions
  • Legal page editor: About, Contact, Privacy Policy, Imprint (multi-language, rich text)
  • Site settings: title, description, limits, pagination, guest visibility
  • System info page: PHP version, DB version, loaded extensions, memory limits

Legal & static pages

  • About, Contact, Privacy Policy, Imprint as admin-editable pages
  • Multi-language support for all legal pages

Installation & deployment

  • Browser-based setup wizard
  • Docker Compose deployment stack (deploy/)
  • LAMP installation guide (EN + DE)
  • GitLab CI pipeline with deploy jobs for develop→dev and master→main
  • PHP lint and Composer audit jobs on every branch push
  • Health check endpoint (/health.php)

UI & frontend

  • Two themes included (set_1, set_2) built with Twig templates
  • Prism.js syntax highlighting for code blocks in posts
  • TinyMCE image upload endpoint (/upload/) for inline images in rich text
  • 404 and 403 error pages (multilingual)
  • Banned-user page

Internationalization

  • Database-driven translation system
  • language_en as canonical source; other languages inherit English as fallback
  • User-selectable language and timezone

Security

  • CSRF token validation on every POST handler without exception
  • Prepared statements for all database queries (no string concatenation with user input)
  • HTMLPurifier (apb_SanitizeHtml()) for all rich text input
  • Plain-text sanitization (apb_SanitizePlainText()) for names, subjects, etc.
  • File uploads: MIME/extension whitelist, mismatch rejection, GD re-encoding, EXIF strip
  • Admin hard gate (apb_IsAdmin()) at the top of every admin engine file
  • Role-based access control: Guest, User, Moderator, Admin
  • Ban enforcement: session invalidation on ban (immediate effect)
  • Mute enforcement: checked in apb_DoTheReply() and apb_DoTheNewTopic()
  • Redirect validation: open redirect prevention on all redirect_to parameters
  • Rate limiting on login (brute force), registration (spam), messaging (abuse)
  • GPL copyright integrity check with public violation warning