secubox-openwrt/package/secubox/luci-app-saas-relay/root/usr/libexec/rpcd/luci.saas-relay
CyberMind-FR 58220065b5 feat(v0.23.0): Matrix homeserver, SaaS Relay CDN caching, Media Hub dashboard
Matrix Homeserver (Conduit):
- E2EE mesh messaging using Conduit v0.10.12 in LXC container
- matrixctl CLI: install/uninstall, user/room management, federation
- luci-app-matrix: status cards, user form, emancipate, mesh publish
- RPCD backend with 17 methods
- Identity (DID) integration and P2P mesh publication

SaaS Relay CDN Caching & Session Replay:
- CDN cache profiles: minimal, gandalf (default), aggressive
- Session replay modes: shared, per_user, master
- saasctl cache/session commands for management
- Enhanced mitmproxy addon (415 lines) with response caching

Media Services Hub Dashboard:
- Unified dashboard at /admin/services/media-hub
- Category-organized cards (streaming, conferencing, apps, etc.)
- Service status indicators with start/stop/restart controls
- RPCD backend querying 8 media services

Also includes:
- HexoJS static upload workflow and multi-user auth
- Jitsi config.js Promise handling fix
- Feed package updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-20 11:44:26 +01:00

462 lines
10 KiB
Bash
Executable File

#!/bin/sh
# SaaS Relay RPCD backend
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
CONFIG="saas-relay"
SAASCTL="/usr/sbin/saasctl"
DATA_PATH="/srv/saas-relay"
COOKIES_PATH="$DATA_PATH/cookies"
LOG_PATH="$DATA_PATH/logs"
uci_get() { uci -q get ${CONFIG}.$1; }
# ===========================================
# Status Methods
# ===========================================
get_status() {
json_init
local enabled=$(uci_get main.enabled) || enabled="0"
local status=$(uci_get main.status) || status="stopped"
local proxy_port=$(uci_get main.proxy_port) || proxy_port="8890"
json_add_boolean "enabled" "$enabled"
json_add_string "status" "$status"
json_add_int "proxy_port" "$proxy_port"
json_add_string "data_path" "$DATA_PATH"
# Count services and cookies
local service_count=0
local cookie_count=0
local enabled_services=0
config_load "$CONFIG"
_count_service() {
local section="$1"
local svc_enabled domain
config_get domain "$section" domain
[ -z "$domain" ] && return
service_count=$((service_count + 1))
config_get svc_enabled "$section" enabled "0"
[ "$svc_enabled" = "1" ] && enabled_services=$((enabled_services + 1))
}
config_foreach _count_service service
for f in "$COOKIES_PATH"/*.json; do
[ -f "$f" ] || continue
local count=$(grep -c '"' "$f" 2>/dev/null | awk '{print int($1/2)}')
cookie_count=$((cookie_count + count))
done
json_add_int "service_count" "$service_count"
json_add_int "enabled_services" "$enabled_services"
json_add_int "total_cookies" "$cookie_count"
json_dump
}
# ===========================================
# Service Methods
# ===========================================
list_services() {
json_init
json_add_array "services"
config_load "$CONFIG"
_add_service() {
local section="$1"
local enabled name emoji domain status cookie_domains auth_required last_check
config_get domain "$section" domain
[ -z "$domain" ] && return
config_get enabled "$section" enabled "0"
config_get name "$section" name "$section"
config_get emoji "$section" emoji "🔗"
config_get status "$section" status "disconnected"
config_get cookie_domains "$section" cookie_domains "$domain"
config_get auth_required "$section" auth_required "1"
config_get last_check "$section" last_check "0"
# Count cookies for this service
local cookie_file="$COOKIES_PATH/${section}.json"
local cookie_count=0
[ -f "$cookie_file" ] && cookie_count=$(grep -c '"' "$cookie_file" 2>/dev/null | awk '{print int($1/2)}')
json_add_object
json_add_string "id" "$section"
json_add_string "name" "$name"
json_add_string "emoji" "$emoji"
json_add_string "domain" "$domain"
json_add_boolean "enabled" "$enabled"
json_add_string "status" "$status"
json_add_int "cookie_count" "$cookie_count"
json_add_string "cookie_domains" "$cookie_domains"
json_add_boolean "auth_required" "$auth_required"
json_add_int "last_check" "$last_check"
json_close_object
}
config_foreach _add_service service
json_close_array
json_dump
}
service_enable() {
read input
json_load "$input"
json_get_var id id
json_init
if [ -z "$id" ]; then
json_add_boolean "success" 0
json_add_string "error" "Service ID required"
json_dump
return
fi
uci set ${CONFIG}.${id}.enabled='1'
uci commit ${CONFIG}
json_add_boolean "success" 1
json_add_string "message" "Service enabled"
json_add_string "emoji" "🔓"
json_dump
}
service_disable() {
read input
json_load "$input"
json_get_var id id
json_init
if [ -z "$id" ]; then
json_add_boolean "success" 0
json_add_string "error" "Service ID required"
json_dump
return
fi
uci set ${CONFIG}.${id}.enabled='0'
uci commit ${CONFIG}
json_add_boolean "success" 1
json_add_string "message" "Service disabled"
json_add_string "emoji" "🔐"
json_dump
}
service_add() {
read input
json_load "$input"
json_get_var id id
json_get_var name name
json_get_var domain domain
json_get_var emoji emoji
json_init
if [ -z "$id" ] || [ -z "$name" ] || [ -z "$domain" ]; then
json_add_boolean "success" 0
json_add_string "error" "ID, name, and domain required"
json_dump
return
fi
[ -z "$emoji" ] && emoji="🔗"
uci set ${CONFIG}.${id}=service
uci set ${CONFIG}.${id}.enabled='1'
uci set ${CONFIG}.${id}.name="$name"
uci set ${CONFIG}.${id}.emoji="$emoji"
uci set ${CONFIG}.${id}.domain="$domain"
uci set ${CONFIG}.${id}.cookie_domains="$domain,.$domain"
uci set ${CONFIG}.${id}.auth_required='1'
uci set ${CONFIG}.${id}.status='disconnected'
uci commit ${CONFIG}
json_add_boolean "success" 1
json_add_string "message" "Service added: $name"
json_add_string "emoji" "$emoji"
json_dump
}
service_delete() {
read input
json_load "$input"
json_get_var id id
json_init
if [ -z "$id" ]; then
json_add_boolean "success" 0
json_add_string "error" "Service ID required"
json_dump
return
fi
uci delete ${CONFIG}.${id} 2>/dev/null
uci commit ${CONFIG}
# Remove cookies
rm -f "$COOKIES_PATH/${id}.json"
json_add_boolean "success" 1
json_add_string "message" "Service deleted"
json_add_string "emoji" "🗑️"
json_dump
}
# ===========================================
# Cookie Methods
# ===========================================
list_cookies() {
read input
json_load "$input"
json_get_var service service
json_init
json_add_boolean "success" 1
if [ -n "$service" ]; then
local cookie_file="$COOKIES_PATH/${service}.json"
json_add_string "service" "$service"
if [ -f "$cookie_file" ]; then
local content=$(cat "$cookie_file")
json_add_string "cookies" "$content"
local count=$(grep -c '"' "$cookie_file" 2>/dev/null | awk '{print int($1/2)}')
json_add_int "count" "$count"
else
json_add_string "cookies" "{}"
json_add_int "count" 0
fi
else
json_add_array "services"
for f in "$COOKIES_PATH"/*.json; do
[ -f "$f" ] || continue
local svc=$(basename "$f" .json)
local count=$(grep -c '"' "$f" 2>/dev/null | awk '{print int($1/2)}')
local size=$(stat -c%s "$f" 2>/dev/null || echo 0)
local modified=$(stat -c%Y "$f" 2>/dev/null || echo 0)
json_add_object
json_add_string "service" "$svc"
json_add_int "count" "$count"
json_add_int "size" "$size"
json_add_int "modified" "$modified"
json_close_object
done
json_close_array
fi
json_dump
}
import_cookies() {
read input
json_load "$input"
json_get_var service service
json_get_var cookies cookies
json_init
if [ -z "$service" ] || [ -z "$cookies" ]; then
json_add_boolean "success" 0
json_add_string "error" "Service and cookies required"
json_dump
return
fi
mkdir -p "$COOKIES_PATH"
echo "$cookies" > "$COOKIES_PATH/${service}.json"
chmod 600 "$COOKIES_PATH/${service}.json"
local count=$(grep -c '"' "$COOKIES_PATH/${service}.json" 2>/dev/null | awk '{print int($1/2)}')
json_add_boolean "success" 1
json_add_string "message" "Imported $count cookies"
json_add_string "emoji" "🍪"
json_add_int "count" "$count"
json_dump
}
clear_cookies() {
read input
json_load "$input"
json_get_var service service
json_init
if [ -n "$service" ]; then
rm -f "$COOKIES_PATH/${service}.json"
json_add_string "message" "Cleared cookies for $service"
else
rm -f "$COOKIES_PATH"/*.json
json_add_string "message" "Cleared all cookies"
fi
json_add_boolean "success" 1
json_add_string "emoji" "🗑️"
json_dump
}
# ===========================================
# Control Methods
# ===========================================
start_relay() {
json_init
local output=$("$SAASCTL" start 2>&1)
local result=$?
if [ "$result" -eq 0 ]; then
json_add_boolean "success" 1
json_add_string "message" "SaaS Relay started"
json_add_string "emoji" "🔄"
else
json_add_boolean "success" 0
json_add_string "error" "$output"
fi
json_dump
}
stop_relay() {
json_init
local output=$("$SAASCTL" stop 2>&1)
local result=$?
if [ "$result" -eq 0 ]; then
json_add_boolean "success" 1
json_add_string "message" "SaaS Relay stopped"
json_add_string "emoji" "🔌"
else
json_add_boolean "success" 0
json_add_string "error" "$output"
fi
json_dump
}
setup_relay() {
json_init
local output=$("$SAASCTL" setup 2>&1)
local result=$?
if [ "$result" -eq 0 ]; then
json_add_boolean "success" 1
json_add_string "message" "Setup complete"
json_add_string "emoji" "✅"
else
json_add_boolean "success" 0
json_add_string "error" "$output"
fi
json_dump
}
# ===========================================
# Activity Log
# ===========================================
get_log() {
read input
json_load "$input"
json_get_var lines lines
[ -z "$lines" ] && lines=50
json_init
json_add_boolean "success" 1
json_add_array "entries"
if [ -f "$LOG_PATH/activity.log" ]; then
tail -n "$lines" "$LOG_PATH/activity.log" | while read line; do
json_add_string "" "$line"
done
fi
json_close_array
json_dump
}
clear_log() {
json_init
> "$LOG_PATH/activity.log" 2>/dev/null
json_add_boolean "success" 1
json_add_string "message" "Log cleared"
json_add_string "emoji" "📋"
json_dump
}
# ===========================================
# Main Dispatcher
# ===========================================
case "$1" in
list)
cat << 'EOF'
{
"status": {},
"list_services": {},
"service_enable": {"id": "str"},
"service_disable": {"id": "str"},
"service_add": {"id": "str", "name": "str", "domain": "str", "emoji": "str"},
"service_delete": {"id": "str"},
"list_cookies": {"service": "str"},
"import_cookies": {"service": "str", "cookies": "str"},
"clear_cookies": {"service": "str"},
"start": {},
"stop": {},
"setup": {},
"get_log": {"lines": "int"},
"clear_log": {}
}
EOF
;;
call)
case "$2" in
status) get_status ;;
list_services) list_services ;;
service_enable) service_enable ;;
service_disable) service_disable ;;
service_add) service_add ;;
service_delete) service_delete ;;
list_cookies) list_cookies ;;
import_cookies) import_cookies ;;
clear_cookies) clear_cookies ;;
start) start_relay ;;
stop) stop_relay ;;
setup) setup_relay ;;
get_log) get_log ;;
clear_log) clear_log ;;
*) echo '{"error": "Unknown method"}' ;;
esac
;;
esac