fix: update deployment scripts and resolve backend API communication issue

This commit is contained in:
dido committed 2026-09-14 15:52:11 +03:00
1 parent ae023525ec
commit 441560a910
14 files changed
+61 -66

No files matched your search

+6 -6
View File
@@ -1,4 +1,4 @@
# StrixWebSSH - Browser-based SSH Client # WebSSH - Browser-based SSH Client
Multi-connection SSH client that runs in your browser with JWT authentication. Multi-connection SSH client that runs in your browser with JWT authentication.
@@ -40,7 +40,7 @@ Default credentials:
Set users via environment variable in `deployment/docker-compose.yml`: Set users via environment variable in `deployment/docker-compose.yml`:
```yaml ```yaml
environment: environment:
- STRIXWEBSSH_USERS=user1:pass1,user2:pass2 - WEBSSH_USERS=user1:pass1,user2:pass2
``` ```
### JWT Secret ### JWT Secret
@@ -184,10 +184,10 @@ your-domain.com {
:8080 { :8080 {
handle_path /ws* { handle_path /ws* {
reverse_proxy strixwebssh:8081 reverse_proxy webssh:8081
} }
handle_path /api/* { handle_path /api/* {
reverse_proxy strixwebssh:8082 reverse_proxy webssh:8082
} }
route { route {
root * /srv root * /srv
@@ -202,8 +202,8 @@ your-domain.com {
Pre-built multi-arch images available: Pre-built multi-arch images available:
```bash ```bash
docker pull danaildr/strixwebssh:latest docker pull danaildr/webssh:latest
docker pull danaildr/strixwebssh:0.3.1 docker pull danaildr/webssh:0.4.0
``` ```
Supported architectures: `linux/amd64`, `linux/arm64` Supported architectures: `linux/amd64`, `linux/arm64`
+3 -8
View File
@@ -44,8 +44,7 @@ RUN set -eux; \
find /opt/venv -path '*/site-packages/pip*' -print0 | xargs -0 -r rm -rf || true; \ find /opt/venv -path '*/site-packages/pip*' -print0 | xargs -0 -r rm -rf || true; \
find /opt/venv -path '*/site-packages/setuptools*' -print0 | xargs -0 -r rm -rf || true; \ find /opt/venv -path '*/site-packages/setuptools*' -print0 | xargs -0 -r rm -rf || true; \
find /opt/venv -path '*/site-packages/wheel*' -print0 | xargs -0 -r rm -rf || true; \ find /opt/venv -path '*/site-packages/wheel*' -print0 | xargs -0 -r rm -rf || true; \
# Remove static metadata not required for runtime (careful: keep runtime metadata intact) true
find /opt/venv -type d -name '*.dist-info' -prune -print0 | xargs -0 -r rm -rf || true || true
# Download Caddy binary for the build target (multi-arch aware) # Download Caddy binary for the build target (multi-arch aware)
ARG TARGETARCH ARG TARGETARCH
@@ -108,12 +107,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY --from=builder /opt/venv /opt/venv COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH" ENV PATH="/opt/venv/bin:$PATH"
# Reinstall runtime dependencies explicitly in the final image to avoid missing package metadata
COPY requirements.txt /tmp/requirements.txt
RUN /opt/venv/bin/python -m ensurepip --upgrade && /opt/venv/bin/python -m pip install --no-cache-dir --prefer-binary -r /tmp/requirements.txt && rm -f /tmp/requirements.txt
# Security: Run as non-root user # Security: Run as non-root user
RUN groupadd -r strixwebssh && useradd -r -g strixwebssh strixwebssh RUN groupadd -r webssh && useradd -r -g webssh webssh
WORKDIR /app/src WORKDIR /app/src
@@ -122,7 +117,7 @@ COPY src/ /app/src/
COPY deployment/docker-entrypoint.sh /usr/local/bin/ COPY deployment/docker-entrypoint.sh /usr/local/bin/
# Create .ssh directory for host keys # Create .ssh directory for host keys
RUN mkdir -p /app/src/.ssh && chown -R strixwebssh:strixwebssh /app/src RUN mkdir -p /app/src/.ssh && chown -R webssh:webssh /app/src
# Copy entrypoint # Copy entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint.sh RUN chmod +x /usr/local/bin/docker-entrypoint.sh
+7 -7
View File
@@ -1,11 +1,11 @@
services: services:
strixwebssh: webssh:
build: build:
context: .. context: ..
dockerfile: deployment/Dockerfile dockerfile: deployment/Dockerfile
container_name: strixwebssh-backend container_name: webssh-backend
restart: unless-stopped restart: unless-stopped
# StrixWebSSH runs internal services; integrated Caddy will expose port 8080 to the host # WebSSH runs internal services; integrated Caddy will expose port 8080 to the host
ports: ports:
- "8080:8080" - "8080:8080"
environment: environment:
@@ -13,7 +13,7 @@ services:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
- LOG_LEVEL=INFO - LOG_LEVEL=INFO
# Configure users: format is username:password,username2:password2 # Configure users: format is username:password,username2:password2
- STRIXWEBSSH_USERS=admin:admin - WEBSSH_USERS=admin:admin
# Max upload size (supports format like "100M" for 100MB or "50M" for 50MB) # Max upload size (supports format like "100M" for 100MB or "50M" for 50MB)
- MAX_UPLOAD_SIZE=30M - MAX_UPLOAD_SIZE=30M
# Session Recording Configuration # Session Recording Configuration
@@ -34,9 +34,9 @@ services:
cpus: '0.25' cpus: '0.25'
memory: 128M memory: 128M
volumes: volumes:
- strixwebssh_data:/data - webssh_data:/data
# Optionally expose code to other services (read-only) # Optionally expose code to other services (read-only)
# - ./:/srv/strixwebssh:ro # - ./:/srv/webssh:ro
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/"] test: ["CMD", "curl", "-f", "http://localhost:8080/"]
interval: 30s interval: 30s
@@ -46,4 +46,4 @@ services:
volumes: volumes:
strixwebssh_data: webssh_data:
+7 -7
View File
@@ -7,7 +7,7 @@ if [ "$(id -u)" != "0" ]; then
exec python /app/src/run.py exec python /app/src/run.py
fi fi
# Create data directory with correct permissions for the StrixWebSSH user # Create data directory with correct permissions for the WebSSH user
if [ ! -d "/data" ]; then if [ ! -d "/data" ]; then
echo "Creating /data directory..." echo "Creating /data directory..."
mkdir -p /data mkdir -p /data
@@ -17,14 +17,14 @@ echo "Current /data permissions:"
ls -la /data || true ls -la /data || true
ls -la / | grep data || true ls -la / | grep data || true
# Ensure /data is writable and owned by the StrixWebSSH user (UID 999) # Ensure /data is writable and owned by the WebSSH user (UID 999)
echo "Setting permissions on /data..." echo "Setting permissions on /data..."
chmod 755 /data chmod 755 /data
chown strixwebssh:strixwebssh /data chown webssh:webssh /data
# Check if chown worked # Check if chown worked
if [ "$(stat -c %U /data)" != "strixwebssh" ]; then if [ "$(stat -c %U /data)" != "webssh" ]; then
echo "WARNING: Could not change ownership of /data to strixwebssh" echo "WARNING: Could not change ownership of /data to webssh"
echo "Current owner: $(stat -c %U /data)" echo "Current owner: $(stat -c %U /data)"
echo "This may happen with bind mounts. Ensure host directory is writable." echo "This may happen with bind mounts. Ensure host directory is writable."
fi fi
@@ -43,5 +43,5 @@ else
echo "Caddy binary not found; continuing without reverse proxy" echo "Caddy binary not found; continuing without reverse proxy"
fi fi
# Start the application (run as the StrixWebSSH user) # Start the application (run as the WebSSH user)
exec gosu strixwebssh python /app/src/run.py exec gosu webssh python /app/src/run.py
+1 -1
View File
@@ -7,7 +7,7 @@ set -e
# Configuration # Configuration
IMAGE_NAME="danaildr/webssh" IMAGE_NAME="danaildr/webssh"
VERSION="0.3.1" VERSION="0.4.0"
PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7" PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
# Colors # Colors
+1 -1
View File
@@ -129,7 +129,7 @@ https://github.com/danaildr/web-ssh
## Tags ## Tags
- `latest` - Most recent stable build - `latest` - Most recent stable build
- `0.3.1` - Version-specific tag (Grouped recordings + Bulk operations + Multi-arch support) - `0.4.0` - Version-specific tag (Grouped recordings + Bulk operations + Multi-arch support)
- `0.1.9` - Previous version - `0.1.9` - Previous version
Multi-arch: All tags support both `linux/amd64` and `linux/arm64`. Multi-arch: All tags support both `linux/amd64` and `linux/arm64`.
+2 -2
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
StrixWebSSH Backend - Modular SSH and SFTP server. WebSSH Backend - Modular SSH and SFTP server.
This file is a compatibility wrapper around the StrixWebSSH backend package. This file is a compatibility wrapper around the WebSSH backend package.
The actual implementation has been split into modular components in webssh_backend/: The actual implementation has been split into modular components in webssh_backend/:
- config.py: Configuration and constants - config.py: Configuration and constants
+6 -6
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>StrixWebSSH - Help</title> <title>WebSSH - Help</title>
<style> <style>
body { body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
@@ -193,7 +193,7 @@
</head> </head>
<body> <body>
<div class="header"> <div class="header">
<h1>🔐 StrixWebSSH</h1> <h1>🔐 WebSSH</h1>
<p>Secure SSH client that runs entirely in your browser</p> <p>Secure SSH client that runs entirely in your browser</p>
</div> </div>
@@ -330,7 +330,7 @@
<li><code>"500K"</code> - 500 kilobytes</li> <li><code>"500K"</code> - 500 kilobytes</li>
</ul> </ul>
<p><strong>STRIXWEBSSH_USERS:</strong> Users in format <code>username:password,username2:password2</code></p> <p><strong>WEBSSH_USERS:</strong> Users in format <code>username:password,username2:password2</code></p>
<p><strong>JWT_SECRET:</strong> Secret key for JWT tokens (auto-generated if not set)</p> <p><strong>JWT_SECRET:</strong> Secret key for JWT tokens (auto-generated if not set)</p>
@@ -339,12 +339,12 @@
<p><strong>RECORDING_RETENTION_DAYS:</strong> Number of days to keep recordings (default: 30)</p> <p><strong>RECORDING_RETENTION_DAYS:</strong> Number of days to keep recordings (default: 30)</p>
<h3>🔒 Auto-Lock & Auto-Disconnect</h3> <h3>🔒 Auto-Lock & Auto-Disconnect</h3>
<p>StrixWebSSH can automatically lock sessions after a period of inactivity and require your StrixWebSSH password to unlock. Sessions can also be automatically disconnected after a longer period.</p> <p>WebSSH can automatically lock sessions after a period of inactivity and require your WebSSH password to unlock. Sessions can also be automatically disconnected after a longer period.</p>
<ul> <ul>
<li><strong>Lock after:</strong> Period of inactivity before locking (5, 15, 30, 60 minutes)</li> <li><strong>Lock after:</strong> Period of inactivity before locking (5, 15, 30, 60 minutes)</li>
<li><strong>Disconnect after:</strong> Period of inactivity before disconnecting (30, 60 minutes, or never)</li> <li><strong>Disconnect after:</strong> Period of inactivity before disconnecting (30, 60 minutes, or never)</li>
<li><strong>Configuration:</strong> Set per connection in the connection settings</li> <li><strong>Configuration:</strong> Set per connection in the connection settings</li>
<li><strong>Security:</strong> Lock requires StrixWebSSH password only (not SSH password)</li> <li><strong>Security:</strong> Lock requires WebSSH password only (not SSH password)</li>
</ul> </ul>
</div> </div>
</div> </div>
@@ -381,7 +381,7 @@
<div class="footer"> <div class="footer">
<p>📧 <strong>Support:</strong> For more information and help, check the project documentation.</p> <p>📧 <strong>Support:</strong> For more information and help, check the project documentation.</p>
<p>🔄 <strong>Version:</strong> StrixWebSSH Multi-Connection Terminal v0.3.1</p> <p>🔄 <strong>Version:</strong> WebSSH Multi-Connection Terminal v0.4.0</p>
<p>⚡ <strong>Technologies:</strong> Python, Paramiko, WebSockets, HTML5, CSS3, JavaScript</p> <p>⚡ <strong>Technologies:</strong> Python, Paramiko, WebSockets, HTML5, CSS3, JavaScript</p>
</div> </div>
</body> </body>
+7 -7
View File
@@ -2,7 +2,7 @@
<html lang="bg"> <html lang="bg">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>StrixWebSSH - Multi-Connection Terminal</title> <title>WebSSH - Multi-Connection Terminal</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm/css/xterm.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm/css/xterm.css" />
<script src="https://cdn.jsdelivr.net/npm/xterm/lib/xterm.js"></script> <script src="https://cdn.jsdelivr.net/npm/xterm/lib/xterm.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit/lib/xterm-addon-fit.js"></script> <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit/lib/xterm-addon-fit.js"></script>
@@ -18,7 +18,7 @@
<!-- Login Modal --> <!-- Login Modal -->
<div class="modal-overlay active" id="loginModal"> <div class="modal-overlay active" id="loginModal">
<div class="modal"> <div class="modal">
<h3>StrixWebSSH Login</h3> <h3>WebSSH Login</h3>
<form onsubmit="event.preventDefault(); login()"> <form onsubmit="event.preventDefault(); login()">
<div class="form-group"> <div class="form-group">
<label>Username</label> <label>Username</label>
@@ -271,8 +271,8 @@
<h3>Session Locked</h3> <h3>Session Locked</h3>
<p class="text-muted">Your session has been locked due to inactivity.</p> <p class="text-muted">Your session has been locked due to inactivity.</p>
<div class="form-group" style="margin-top: 20px;"> <div class="form-group" style="margin-top: 20px;">
<label>Enter your StrixWebSSH password to unlock</label> <label>Enter your WebSSH password to unlock</label>
<input type="password" id="unlockPassword" placeholder="StrixWebSSH password" onkeydown="if(event.key==='Enter')unlockSession()"> <input type="password" id="unlockPassword" placeholder="WebSSH password" onkeydown="if(event.key==='Enter')unlockSession()">
</div> </div>
<div id="unlockError" style="color: #ef4444; margin-top: 10px; display: none;">Incorrect password</div> <div id="unlockError" style="color: #ef4444; margin-top: 10px; display: none;">Incorrect password</div>
<div class="modal-actions" style="margin-top: 20px;"> <div class="modal-actions" style="margin-top: 20px;">
@@ -319,8 +319,8 @@
<h3>Session Locked</h3> <h3>Session Locked</h3>
<p class="text-muted">Your session has been locked due to inactivity.</p> <p class="text-muted">Your session has been locked due to inactivity.</p>
<div class="form-group" style="margin-top: 20px;"> <div class="form-group" style="margin-top: 20px;">
<label>Enter your StrixWebSSH password to unlock</label> <label>Enter your WebSSH password to unlock</label>
<input type="password" id="unlockPassword" placeholder="StrixWebSSH password" onkeydown="if(event.key==='Enter')unlockSession()"> <input type="password" id="unlockPassword" placeholder="WebSSH password" onkeydown="if(event.key==='Enter')unlockSession()">
</div> </div>
<div id="unlockError" style="color: #ef4444; margin-top: 10px; display: none;">Incorrect password</div> <div id="unlockError" style="color: #ef4444; margin-top: 10px; display: none;">Incorrect password</div>
<div class="modal-actions" style="margin-top: 20px;"> <div class="modal-actions" style="margin-top: 20px;">
@@ -333,7 +333,7 @@
<div class="modal-overlay" id="helpModal"> <div class="modal-overlay" id="helpModal">
<div class="modal" style="max-width: 90%; max-height: 90%; overflow-y: auto;"> <div class="modal" style="max-width: 90%; max-height: 90%; overflow-y: auto;">
<div class="modal-header"> <div class="modal-header">
<h3>📚 StrixWebSSH Help</h3> <h3>📚 WebSSH Help</h3>
<button class="modal-close" onclick="hideHelp()">&times;</button> <button class="modal-close" onclick="hideHelp()">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
+1 -1
View File
@@ -1,4 +1,4 @@
/* StrixWebSSH Client Styles */ /* WebSSH Client Styles */
* { box-sizing: border-box; } * { box-sizing: border-box; }
body { body {
+12 -12
View File
@@ -1,9 +1,9 @@
// StrixWebSSH Client JavaScript // WebSSH Client JavaScript
let connections = []; let connections = [];
let currentConnectionId = null; let currentConnectionId = null;
let authToken = localStorage.getItem('strixwebssh_token'); let authToken = localStorage.getItem('webssh_token');
let currentUser = localStorage.getItem('strixwebssh_user'); let currentUser = localStorage.getItem('webssh_user');
let storedUsers = {}; // Will be loaded from /api/config let storedUsers = {}; // Will be loaded from /api/config
let maxUploadSize = localStorage.getItem('maxUploadSize') ? parseInt(localStorage.getItem('maxUploadSize')) : 100 * 1024 * 1024; let maxUploadSize = localStorage.getItem('maxUploadSize') ? parseInt(localStorage.getItem('maxUploadSize')) : 100 * 1024 * 1024;
// Dynamically determine API URL based on current host (same origin since everything is in container) // Dynamically determine API URL based on current host (same origin since everything is in container)
@@ -17,7 +17,7 @@ function getWsUrl() {
return `${protocol}//${window.location.host}/ws`; return `${protocol}//${window.location.host}/ws`;
} }
const CONNECTIONS_KEY = 'strixwebssh_connections'; const CONNECTIONS_KEY = 'webssh_connections';
// Load connections from server (with encrypted credentials) // Load connections from server (with encrypted credentials)
async function loadSavedConnections() { async function loadSavedConnections() {
@@ -256,7 +256,7 @@ async function login() {
if (response.ok && data.token) { if (response.ok && data.token) {
authToken = data.token; authToken = data.token;
localStorage.setItem('strixwebssh_token', authToken); localStorage.setItem('webssh_token', authToken);
document.getElementById('loginModal').classList.remove('active'); document.getElementById('loginModal').classList.remove('active');
document.getElementById('loggedInUser').textContent = data.username; document.getElementById('loggedInUser').textContent = data.username;
term.writeln(`[Authenticated as ${data.username}]`); term.writeln(`[Authenticated as ${data.username}]`);
@@ -287,18 +287,18 @@ async function verifyToken() {
loadSavedConnections(); // Load encrypted credentials from server loadSavedConnections(); // Load encrypted credentials from server
setTimeout(loadConfig, 500); // Load configuration after successful token verification with delay setTimeout(loadConfig, 500); // Load configuration after successful token verification with delay
} else { } else {
localStorage.removeItem('strixwebssh_token'); localStorage.removeItem('webssh_token');
authToken = null; authToken = null;
} }
} catch (e) { } catch (e) {
localStorage.removeItem('strixwebssh_token'); localStorage.removeItem('webssh_token');
authToken = null; authToken = null;
} }
} }
function logout() { function logout() {
localStorage.removeItem('strixwebssh_token'); localStorage.removeItem('webssh_token');
localStorage.removeItem('strixwebssh_api_url'); localStorage.removeItem('webssh_api_url');
authToken = null; authToken = null;
location.reload(); location.reload();
} }
@@ -773,7 +773,7 @@ function sendResizeForConnection(conn) {
// Initialize // Initialize
toggleAuthFields(); toggleAuthFields();
term.writeln('StrixWebSSH Multi-Connection Client'); term.writeln('WebSSH Multi-Connection Client');
term.writeln('Click "+ New Connection" to get started'); term.writeln('Click "+ New Connection" to get started');
// ============================================ // ============================================
@@ -787,13 +787,13 @@ let sftpUploadQueue = [];
let currentSftpConnection = null; let currentSftpConnection = null;
// Load configuration from API // Load configuration from API
function loadConfig() { function loadConfig() {
console.log('loadConfig() called, token exists:', !!localStorage.getItem('strixwebssh_token')); console.log('loadConfig() called, token exists:', !!localStorage.getItem('webssh_token'));
console.log('apiBaseUrl:', apiBaseUrl); console.log('apiBaseUrl:', apiBaseUrl);
fetch(`${apiBaseUrl}/api/config`, { fetch(`${apiBaseUrl}/api/config`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Authorization': `Bearer ${localStorage.getItem('strixwebssh_token')}` 'Authorization': `Bearer ${localStorage.getItem('webssh_token')}`
} }
}) })
.then(response => { .then(response => {
+2 -2
View File
@@ -1,5 +1,5 @@
""" """
StrixWebSSH Backend Package - Modular SSH and SFTP server. WebSSH Backend Package - Modular SSH and SFTP server.
This package provides a modular SSH and SFTP server with the following components: This package provides a modular SSH and SFTP server with the following components:
@@ -18,7 +18,7 @@ Usage:
from webssh_backend.main import main from webssh_backend.main import main
asyncio.run(main()) asyncio.run(main())
""" """
__version__ = "0.3.1" __version__ = "0.4.0"
# Note: Specific imports are intentionally NOT done at package level # Note: Specific imports are intentionally NOT done at package level
# to avoid loading all dependencies when only specific modules are needed. # to avoid loading all dependencies when only specific modules are needed.
+5 -5
View File
@@ -169,9 +169,9 @@ def ensure_storage_dir():
ensure_storage_dir() ensure_storage_dir()
# Resolve backend ports, falling back to the next free port when defaults are busy. # Resolve backend ports, falling back to the next free port when defaults are busy.
WS_PORT = _resolve_port(("STRIXWEBSSH_WS_PORT", "WEBSSH_WS_PORT"), 8081) WS_PORT = _resolve_port(("WEBSSH_WS_PORT",), 8081)
HTTP_PORT = _resolve_port(("STRIXWEBSSH_HTTP_PORT", "WEBSSH_HTTP_PORT"), 8082, reserved_ports={WS_PORT}) HTTP_PORT = _resolve_port(("WEBSSH_HTTP_PORT",), 8082, reserved_ports={WS_PORT})
SFTP_WS_PORT = _resolve_port(("STRIXWEBSSH_SFTP_PORT", "WEBSSH_SFTP_PORT"), 8083, reserved_ports={WS_PORT, HTTP_PORT}) SFTP_WS_PORT = _resolve_port(("WEBSSH_SFTP_PORT",), 8083, reserved_ports={WS_PORT, HTTP_PORT})
try: try:
with open(PORT_STATE_FILE, "w") as handle: with open(PORT_STATE_FILE, "w") as handle:
@@ -186,9 +186,9 @@ except Exception as exc:
logger.info(f"Resolved backend ports: ws={WS_PORT}, http={HTTP_PORT}, sftp={SFTP_WS_PORT}") logger.info(f"Resolved backend ports: ws={WS_PORT}, http={HTTP_PORT}, sftp={SFTP_WS_PORT}")
# User Configuration (username: password_hash) # User Configuration (username: password_hash)
# Set via environment variable: STRIXWEBSSH_USERS=user1:pass1,user2:pass2 # Set via environment variable: WEBSSH_USERS=user1:pass1,user2:pass2
USERS = {} USERS = {}
users_env = os.environ.get("STRIXWEBSSH_USERS", os.environ.get("WEBSSH_USERS", "admin:admin")) users_env = os.environ.get("WEBSSH_USERS", "admin:admin")
for user_cred in users_env.split(","): for user_cred in users_env.split(","):
if ":" in user_cred: if ":" in user_cred:
u, p = user_cred.split(":", 1) u, p = user_cred.split(":", 1)
+1 -1
View File
@@ -25,7 +25,7 @@ async def periodic_cleanup():
async def main(): async def main():
logger.info(f"StrixWebSSH server starting on ws://{HOST}:{WS_PORT}") logger.info(f"WebSSH server starting on ws://{HOST}:{WS_PORT}")
logger.info(f"SFTP server starting on ws://{HOST}:{SFTP_WS_PORT}") logger.info(f"SFTP server starting on ws://{HOST}:{SFTP_WS_PORT}")
logger.info(f"Login API available on http://{HOST}:{HTTP_PORT}") logger.info(f"Login API available on http://{HOST}:{HTTP_PORT}")