Open
Conversation
- Pass resolved locale to buildBbsMenuItems() and use translator for 'Polls' and 'Shoutbox' labels instead of hardcoded English strings - Remove dead elseif block in the Twig t() function where array_unshift was immediately overridden by the subsequent $namespaces = $args[1] assignment, making the branch unreachable in effect Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The charset detection wizard now tests CP437 box-drawing support when UTF-8 is not available, falling back to ASCII if CP437 also fails. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The file detail modal's Rename button is replaced with an Edit button that opens a unified dialog for changing filename, short description, and long description in one request. Admins additionally see a Move to Area dropdown that physically relocates the file to another area's storage directory and updates the database record. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace loose owner_id truthiness check with explicit null guards on both sides, preventing the edit and delete buttons from appearing on TIC-imported files (owner_id = NULL) or any file the current user does not own. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix isAdmin always being true: |default('false') replaced PHP false
with the string 'false' which is truthy in Twig's ternary. Now uses
window.currentUserIsAdmin set correctly by base.twig.
- Fix currentUserId always null: used current_user.id but auth session
key is user_id. Now uses window.currentUserId from base.twig.
- File details 'From' field now falls back to owner username when
uploaded_from_address is empty (e.g. files predating that column).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Prev/Next chevron buttons in modal header matching echomail/netmail style - Position indicator in title (e.g. "filename.zip (3 / 12)") - Navigation tracks displayed list (filtered or full area) - Left/Right arrow keyboard shortcuts when modal is open - Buttons disable at list boundaries - COALESCE display_from in getFileById() to prefer uploaded_from_address over owner_username server-side - i18n keys added to en/es/fr Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Press H in echomail or netmail reader to view message headers (kludge lines) - Scrollable full-screen viewer with Up/Down/PgUp/PgDn/Home/End navigation - Kludge keyword colorized in yellow for readability - Shows "(No message headers)" if none present - H added to status bar in both echomail and netmail readers - Sources kludge lines from kludge_lines + bottom_kludges API fields (not message_text) - i18n keys added to en/es/fr terminalserver catalogs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…racters Adds sanitizeToUtf8() helper to TicFileProcessor that converts CP437/ISO-8859-1 encoded text to valid UTF-8 before database insertion. Applied to DIZ content, short/long descriptions, and From address fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BinkdProcessor: move non-pkt files extracted from bundles back to inbound/ so TIC processing can find them (e.g. NIXLIST.Z65 inside a .FR0 day bundle) - process_packets: move leftover inbound files to unprocessed/ after all processing completes; TIC files are left in place - process_packets: add flock-based mutex so only one instance runs at a time Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- processExtractedPackets: use RecursiveIteratorIterator to find pkt and non-pkt files in subdirectories (e.g. RETROPCK/ inside temp dir) - cleanupTempDir: recursively delete subdirectories so temp dirs are not left stranded when archives extract into subdirectories - Add pathIsUnder() guard to prevent both functions from operating on paths outside the inbound directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…OW_INFECTED option
- docs/AntiVirus.md: new document covering ClamAV installation, configuration,
permissions, .env options, and troubleshooting; linked from README
- Admin file details modal: add Virus Scan button (admin only) that triggers
an on-demand scan via admin daemon and refreshes the scan status display
- AdminDaemonServer/Client: add scan_file command that scans a file by ID
and updates the database with the result
- POST /api/files/{id}/scan: new admin-only API endpoint
- CLAMAV_ALLOW_INFECTED=true: when set, infected files are kept and approved
rather than deleted and rejected; scan result is still recorded in the DB
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Upload route now returns a specific 422 error when virus is detected instead of falling through to the generic 'Failed to upload file' message - Virus rejection is logged to server log via admin daemon with username, filename, and file area - Unknown upload errors now log to PHP error log before returning generic message - Add errors.files.upload.virus_detected i18n key to en/es/fr Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…style Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of Changes
Localization (i18n) Support
en), Spanish (es), and French (fr). Seedocs/Localization.mdfor a full technical reference and translation contributor workflow.es) and French (fr) translations were generated by AI and have not been independently reviewed for accuracy. They may contain errors, awkward phrasing, or incorrect terminology. Community corrections are welcome via pull request.error_code/message_code(with optional params), so clients can localize consistently per user locale./api/i18n/catalog). Pages that render text dynamically must initialize after user settings + i18n catalogs are loaded to avoid English fallback text.BbsSessionclass) now support localization. All user-facing strings in the telnet server, shell menus, message editor, echomail/netmail browsers, polls, shoutbox, and door launcher are translated via theterminalservercatalog namespace (config/i18n/<locale>/terminalserver.php). The daemon defaults to the system locale (I18N_DEFAULT_LOCALE) pre-login and switches to the user's saved locale immediately after a successful login.scripts/create_translation_catalog.phpnow supports Anthropic Claude in addition to OpenAI for automated locale generation. Provider is auto-detected from the presence ofANTHROPIC_API_KEYorOPENAI_API_KEYin.env, or set explicitly with--provider=claude|openai. Default Claude model isclaude-sonnet-4-6; default OpenAI model isgpt-4o-mini. Seedocs/Localization.mdfor full usage.php scripts/check_i18n_error_keys.phpvalidates error key coverage.php scripts/check_i18n_hardcoded_strings.phpblocks new hardcoded UI strings not in the allowlist.BinktermPHP Terminal Server
The BinktermPHP Terminal Server provides a BBS-style interactive terminal accessible over two protocols:
telnet_daemon.php) — default port2323; TLS available on port8023ssh/ssh_daemon.php) — pure-PHP SSH-2 daemon; default port8022Both access methods share the same session logic (
BbsSession) and deliver identical BBS features: menus, messaging, file areas, doors, polls, shoutbox, and more.SSH Access
ssh/ssh_daemon.php) — pure-PHP SSH daemon using onlyext-opensslandext-gmp, no new Composer dependencies. Default port8022(configurable viaSSH_PORTin.env). Correct SSH credentials skip the BBS login screen; failed auth drops to the login/register screen instead of disconnecting. Host key is auto-generated on first run atdata/ssh/ssh_host_rsa_key. Seedocs/SSHServer.mdfor full documentation.Telnet Access
data/telnet/. SetTELNET_TLS=falsein.envto disable, or provide your own certificate viaTELNET_TLS_CERTandTELNET_TLS_KEY. Use--no-tlson the command line to disable for a single run.Terminal Features
Ffrom the main menu)Zin the message viewer when attachments exist).users_metausingterminal_*keys. Netmail restores the last page + selected message. Echomail restores the echoarea list page and per-area message position (page + selected message).GET /api/user/terminal-mail-statePOST /api/user/terminal-mail-stateTELNET_ZMODEM_DEBUG_UNIQUE_NAMES=true>) are always rendered as plain dim text regardless of the declared markup format.~~text~~) now renders as dim-text-in the terminal and<del>text</del>in the web message reader.File Areas
.envoption:CLAMAV_ALLOW_INFECTED=true— accept infected files rather than rejecting them; scan result is still recordedFILE_ID.DIZcontents containing CP437 or ISO-8859-1 characters no longer cause a PostgreSQL encoding error. Text is converted to UTF-8 before database insertion..FR0) are now correctly extracted and made available for TIC processing instead of being silently discarded.process_packets.phpnow uses a file lock to prevent multiple concurrent instances.data/inbound/are moved todata/inbound/unprocessed/for manual review instead of accumulating indefinitely.Native Doors
allow_anonymous: trueandguest_max_sessions: Ninconfig/nativedoors.json. Requires migration v1.10.17.2 (run viasetup.php).PUBTERM_HOSTandPUBTERM_PORTin.env(defaults to127.0.0.1:2323). Linux usestelnet -E -K; Windows uses PuTTYplink(install viawinget install PuTTY.PuTTY, or setPUBTERM_PLINK_BINin.env). When enabled, a "Connect via Telnet" button appears on the login page./guest-doors) listing all anonymous-accessible native doors. Enable via Admin → BBS Settings → Enable Guest Doors Page. When enabled, a Guest Doors link appears in the navigation for logged-out users.platformfield inrequirements(e.g.["linux", "windows"]). The admin UI shows a warning badge if a door's platform requirements don't match the server OS.launch_command_windowsfor platform-specific launch commands on Windows.docs/Doors.mdentry point covers all door types and shared multiplexing bridge setup (including--daemonmode);docs/DOSDoors.mdanddocs/NativeDoors.mdupdated to reference it.DOS Door Multiplexing Server
kill -HUP $(cat data/run/multiplexing-server.pid)to reload.envvalues without restarting. The following settings reload live:DOSDOOR_DISCONNECT_TIMEOUT,DOSDOOR_DEBUG_KEEP_FILES,DOSDOOR_CARRIER_LOSS_TIMEOUT. Settings that require a full restart:DOSDOOR_WS_PORT,DOSDOOR_WS_BIND_HOST,DOSDOOR_TRUSTED_PROXIES,DB_*.X-Forwarded-Forheader when the connection originates from a trusted proxy. SetDOSDOOR_TRUSTED_PROXIESin.envto a comma-separated list of proxy IPs (default:127.0.0.1). Connections from unlisted addresses always use the raw socket IP.[sessionId|username|ip]for every session-scoped event, including emulator adapter output (DOSBox, DOSEMU, Native), DB updates, and drop file writes. This makes it straightforward to correlate all activity for a specific user or connection in the log.TIC / File Areas (FidoNet)
Character not in repertoire) that occurred when processing TIC files whoseFILE_ID.DIZorDesc/LDescfields contained CP437 or ISO-8859-1 characters. Descriptions are now converted to valid UTF-8 before database insertion, matching the encoding handling already applied to message packets.Echomail / Netmail
RW>> text), the bumped quote now consistently carries a leading space (RW>>> text) matching the FSC-0032 quoting style used for first-level quotes.>quoting instead of FSC-0032 initials style. Netmail replies now quote identically to echomail replies.AREA:/SEEN-BY/PATHkludges) being incorrectly delivered to the sysop's netmail inbox. The sysop catch-all fallback in address routing has been removed. Undeliverable messages are now dropped with a detailed log entry (from, to, subject, date, MSGID) and the original.pktpacket file is preserved todata/undeliverable/for manual inspection.Admin / Sysop Tools
config/i18n/overrides/<locale>/<namespace>.jsonand are applied transparently on top of the base catalog at runtime./games) and Files (/files).Web / PWA
sw.jsscript now has a dedicatedCache-Control: no-cacheheader in.htaccessper the Service Worker spec recommendation.>) not rendering in the UPGRADING doc viewer. Blockquotes now display with a left border accent at normal body font size.