Skip to content

Commit 92a4391

Browse files
committed
Release v3.2.1 — rTorrent HTTPS, self-hosted assets & script debugging
- Add HTTPS/SSL support for rTorrent XML-RPC connections - Bundle country flag SVGs locally (remove external CDN dependency) - Bundle Chart.js locally and remove cdn.jsdelivr.net from CSP - Add CRLF detection warning for event scripts - Improve event script error logging (always log stderr) - Fix mobile auto-scroll in settings when content stretches page
1 parent 9281e38 commit 92a4391

287 files changed

Lines changed: 393 additions & 26 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ PORT=4000
5555
# RTORRENT_PATH=/RPC2
5656
# RTORRENT_USERNAME=
5757
# RTORRENT_PASSWORD=
58+
# RTORRENT_USE_SSL=false
5859

5960
# qBittorrent Configuration (Optional)
6061
# Connect to qBittorrent for BitTorrent downloads via WebUI API

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pids/
3131
# Build outputs
3232
static/output.css
3333
static/dist/
34+
!static/dist/chart.umd.min.js
3435
dist/
3536
build/
3637

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.2.1] - rTorrent HTTPS, Self-Hosted Flags & Script Debugging
9+
10+
### ✨ Added
11+
12+
- **rTorrent HTTPS Support** - Connect to rTorrent XML-RPC endpoints over HTTPS/SSL, matching qBittorrent, Deluge, and Transmission. Configurable via Settings UI, `RTORRENT_USE_SSL` env var, or config.json
13+
- **Self-Hosted Country Flags** - Country flag SVGs are now bundled locally instead of loading from an external CDN, eliminating Content Security Policy issues and external dependencies
14+
- **Self-Hosted Chart.js** - Chart.js is now bundled locally instead of loading from jsdelivr CDN, removing the last external script dependency
15+
- **Event Script CRLF Detection** - Scripts with Windows line endings (CRLF) are detected before execution with a clear warning and fix command in logs
16+
17+
### 🐛 Fixed
18+
19+
- **Event Script Error Logging** - stderr output is now always logged regardless of exit code, and stdout is included on failures for easier debugging
20+
- **Settings Auto-Scroll on Mobile** - Fixed section auto-scroll not working on mobile when expanding sections that stretch the page content
21+
22+
### 🔒 Security
23+
24+
- **Tighter CSP** - Removed `cdn.jsdelivr.net` from `script-src` Content Security Policy directive — all assets are now self-hosted
25+
26+
---
27+
828
## [3.2.0] - Five-Client Support, Multi-Instance & User Management
929

1030
### 🎉 Major Release - Five Download Clients & Multi-User

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ COPY server/modules ./server/modules
3535
COPY static/index.html ./static/
3636
COPY static/*.png static/*.ico static/*.svg static/site.webmanifest ./static/
3737
COPY static/service-icons ./static/service-icons
38+
COPY static/flags ./static/flags
3839

3940
# Copy built assets from builder stage (CSS + JS bundle)
4041
COPY --from=builder /build/static/output.css ./static/output.css

docs/CONFIGURATION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ services:
167167
- RTORRENT_PATH=/RPC2
168168
- RTORRENT_USERNAME=user
169169
- RTORRENT_PASSWORD=pass # Locks UI editing
170+
- RTORRENT_USE_SSL=false
170171

171172
# qBittorrent Connection (optional)
172173
- QBITTORRENT_ENABLED=true
@@ -258,6 +259,7 @@ services:
258259
| `RTORRENT_PATH` | `/RPC2` | XML-RPC endpoint path |
259260
| `RTORRENT_USERNAME` | - | HTTP auth username (if required) |
260261
| `RTORRENT_PASSWORD` | - | HTTP auth password (locks UI editing) |
262+
| `RTORRENT_USE_SSL` | `false` | Use HTTPS for XML-RPC connection |
261263

262264
#### qBittorrent Connection
263265

docs/RTORRENT.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# rTorrent Integration
22

3-
aMuTorrent connects to rTorrent via XML-RPC over HTTP, allowing you to manage BitTorrent downloads.
3+
aMuTorrent connects to rTorrent via XML-RPC over HTTP/HTTPS, allowing you to manage BitTorrent downloads.
44

55
> **Alternative:** aMuTorrent also supports [qBittorrent](./QBITTORRENT.md), [Deluge](./DELUGE.md), and [Transmission](./TRANSMISSION.md). You can use multiple BitTorrent clients simultaneously.
66
77
## Requirements
88

9-
- rTorrent with XML-RPC enabled over HTTP
9+
- rTorrent with XML-RPC enabled over HTTP or HTTPS
1010
- Typically requires a web server (nginx, lighttpd) to expose XML-RPC
1111

1212
## Configuration
@@ -21,6 +21,7 @@ aMuTorrent connects to rTorrent via XML-RPC over HTTP, allowing you to manage Bi
2121
- **Port**: XML-RPC port (default: `8000`)
2222
- **Path**: XML-RPC endpoint path (default: `/RPC2`)
2323
- **Username/Password**: If HTTP authentication is required
24+
- **Use SSL (HTTPS)**: Enable if your rTorrent XML-RPC endpoint uses HTTPS
2425

2526
### Via Environment Variables
2627

@@ -31,6 +32,7 @@ RTORRENT_PORT=8000
3132
RTORRENT_PATH=/RPC2
3233
RTORRENT_USERNAME=user
3334
RTORRENT_PASSWORD=pass
35+
RTORRENT_USE_SSL=false
3436
```
3537

3638
### Via config.json
@@ -43,7 +45,8 @@ RTORRENT_PASSWORD=pass
4345
"port": 8000,
4446
"path": "/RPC2",
4547
"username": "",
46-
"password": ""
48+
"password": "",
49+
"useSsl": false
4750
}
4851
}
4952
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "amutorrent-webapp-frontend",
3-
"version": "3.2.0",
3+
"version": "3.2.1",
44
"description": "aMuTorrent Frontend Build",
55
"scripts": {
66
"build:css": "tailwindcss -i ./src/input.css -o ./static/output.css --minify",

server/lib/EventScriptingManager.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ class EventScriptingManager extends BaseModule {
9898
return;
9999
}
100100

101+
// Warn about Windows line endings (CRLF) which cause "command not found" errors
102+
try {
103+
const head = Buffer.alloc(256);
104+
const fd = await fs.promises.open(scriptPath, 'r');
105+
await fd.read(head, 0, 256);
106+
await fd.close();
107+
if (head.includes(0x0d)) {
108+
this.log(`[EventScript] WARNING: Script has Windows line endings (CRLF): ${scriptPath} — this will cause "command not found" errors. Convert with: sed -i 's/\\r$//' ${scriptPath}`);
109+
}
110+
} catch { /* non-critical check */ }
111+
101112
const jsonData = JSON.stringify(eventData);
102113

103114
// Build environment variables
@@ -162,10 +173,13 @@ class EventScriptingManager extends BaseModule {
162173
if (timeoutId) clearTimeout(timeoutId);
163174

164175
if (!killed) {
176+
if (stderr) {
177+
this.log(`[EventScript] stderr for ${eventType}: ${stderr.trim().substring(0, 500)}`);
178+
}
165179
if (code === 0) {
166180
this.log(`[EventScript] Script completed for ${eventType}${stdout ? ': ' + stdout.trim().substring(0, 100) : ''}`);
167181
} else {
168-
this.log(`[EventScript] Script exited with code ${code} for ${eventType}${stderr ? ': ' + stderr.trim().substring(0, 200) : ''}`);
182+
this.log(`[EventScript] Script exited with code ${code} for ${eventType}${stdout ? ' | stdout: ' + stdout.trim().substring(0, 200) : ''}`);
169183
}
170184
}
171185
resolve();

server/lib/configTester.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,10 @@ async function testAmuleConnection(host, port, password) {
169169
* @param {string} rpcPath - XML-RPC path (e.g., /RPC2)
170170
* @param {string} username - Optional username for basic auth
171171
* @param {string} password - Optional password for basic auth
172+
* @param {boolean} useSsl - Whether to use HTTPS
172173
* @returns {Promise<{success: boolean, connected: boolean, version: string|null, error: string|null}>}
173174
*/
174-
async function testRtorrentConnection(host, port, rpcPath, username, password) {
175+
async function testRtorrentConnection(host, port, rpcPath, username, password, useSsl) {
175176
const result = {
176177
success: false,
177178
connected: false,
@@ -193,7 +194,8 @@ async function testRtorrentConnection(host, port, rpcPath, username, password) {
193194
port: port || 8000,
194195
path: rpcPath || '/RPC2',
195196
username: username || null,
196-
password: password || null
197+
password: password || null,
198+
useSsl: useSsl || false
197199
});
198200

199201
client.connect();

server/lib/rtorrent/RtorrentHandler.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class RtorrentHandler {
1515
this.path = options.path || '/RPC2';
1616
this.username = options.username || null;
1717
this.password = options.password || null;
18+
this.useSsl = options.useSsl || false;
1819

1920
this.client = null;
2021
this.connected = false;
@@ -38,7 +39,14 @@ class RtorrentHandler {
3839
};
3940
}
4041

41-
this.client = xmlrpc.createClient(clientOptions);
42+
// Allow self-signed certificates when using SSL
43+
if (this.useSsl) {
44+
clientOptions.rejectUnauthorized = false;
45+
}
46+
47+
this.client = this.useSsl
48+
? xmlrpc.createSecureClient(clientOptions)
49+
: xmlrpc.createClient(clientOptions);
4250
return this;
4351
}
4452

0 commit comments

Comments
 (0)