chore(demo): update manual sync script and lock TOTP for demo account
- Update scripts/manual-sync.sh to pull v2.0.2, backup extra demo/Pro dirs, and safely rsync core code without touching data, bundles, or site overrides - After sync, automatically flip FR_DEMO_MODE to true in config/config.php so the droplet always runs in demo mode - Block TOTP enable/disable/setup and recovery code generation for the demo account when FR_DEMO_MODE is enabled, returning 403 with clear JSON errors
This commit is contained in:
@@ -1,19 +1,24 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# === Update FileRise to v1.9.1 (safe rsync) ===
|
# === Update FileRise to v2.0.2 (safe rsync) ===
|
||||||
# shellcheck disable=SC2155 # we intentionally assign 'stamp' with command substitution
|
|
||||||
|
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
VER="v1.9.1"
|
VER="v2.0.2"
|
||||||
ASSET="FileRise-${VER}.zip" # If the asset name is different, set it exactly (e.g. FileRise-v1.9.0.zip)
|
ASSET="FileRise-${VER}.zip" # matches GitHub release asset name
|
||||||
WEBROOT="/var/www"
|
WEBROOT="/var/www"
|
||||||
TMP="/tmp/filerise-update"
|
TMP="/tmp/filerise-update"
|
||||||
|
|
||||||
# 0) (optional) quick backup of critical bits
|
# 0) quick backup of critical bits (include Pro/demo stuff too)
|
||||||
stamp="$(date +%F-%H%M)"
|
stamp="$(date +%F-%H%M)"
|
||||||
mkdir -p /root/backups
|
mkdir -p /root/backups
|
||||||
tar -C "$WEBROOT" -czf "/root/backups/filerise-$stamp.tgz" \
|
tar -C "$WEBROOT" -czf "/root/backups/filerise-$stamp.tgz" \
|
||||||
public/.htaccess config users uploads metadata || true
|
public/.htaccess \
|
||||||
|
config \
|
||||||
|
users \
|
||||||
|
uploads \
|
||||||
|
metadata \
|
||||||
|
filerise-bundles \
|
||||||
|
filerise-config \
|
||||||
|
filerise-site || true
|
||||||
echo "Backup saved to /root/backups/filerise-$stamp.tgz"
|
echo "Backup saved to /root/backups/filerise-$stamp.tgz"
|
||||||
|
|
||||||
# 1) Fetch the release zip
|
# 1) Fetch the release zip
|
||||||
@@ -29,12 +34,15 @@ STAGE_DIR="$(find "$TMP" -maxdepth 1 -type d -name 'FileRise*' ! -path "$TMP" |
|
|||||||
# 3) Sync code into /var/www
|
# 3) Sync code into /var/www
|
||||||
# - keep public/.htaccess
|
# - keep public/.htaccess
|
||||||
# - keep data dirs and current config.php
|
# - keep data dirs and current config.php
|
||||||
|
# - DO NOT touch filerise-site / bundles / demo config
|
||||||
rsync -a --delete \
|
rsync -a --delete \
|
||||||
--exclude='public/.htaccess' \
|
--exclude='public/.htaccess' \
|
||||||
--exclude='uploads/***' \
|
--exclude='uploads/***' \
|
||||||
--exclude='users/***' \
|
--exclude='users/***' \
|
||||||
--exclude='metadata/***' \
|
--exclude='metadata/***' \
|
||||||
--exclude='config/config.php' \
|
--exclude='filerise-bundles/***' \
|
||||||
|
--exclude='filerise-config/***' \
|
||||||
|
--exclude='filerise-site/***' \
|
||||||
--exclude='.github/***' \
|
--exclude='.github/***' \
|
||||||
--exclude='docker-compose.yml' \
|
--exclude='docker-compose.yml' \
|
||||||
"$STAGE_DIR"/ "$WEBROOT"/
|
"$STAGE_DIR"/ "$WEBROOT"/
|
||||||
@@ -42,13 +50,23 @@ rsync -a --delete \
|
|||||||
# 4) Ownership (Ubuntu/Debian w/ Apache)
|
# 4) Ownership (Ubuntu/Debian w/ Apache)
|
||||||
chown -R www-data:www-data "$WEBROOT"
|
chown -R www-data:www-data "$WEBROOT"
|
||||||
|
|
||||||
# 5) (optional) Composer autoload optimization if composer is available
|
# 5) Composer autoload optimization if composer is available
|
||||||
if command -v composer >/dev/null 2>&1; then
|
if command -v composer >/dev/null 2>&1; then
|
||||||
cd "$WEBROOT" || { echo "cd to $WEBROOT failed" >&2; exit 1; }
|
cd "$WEBROOT" || { echo "cd to $WEBROOT failed" >&2; exit 1; }
|
||||||
composer install --no-dev --optimize-autoloader
|
composer install --no-dev --optimize-autoloader
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 6) Reload Apache (don’t fail the whole script if reload isn’t available)
|
# 6) Force demo mode ON in config/config.php
|
||||||
|
CFG_FILE="$WEBROOT/config/config.php"
|
||||||
|
if [[ -f "$CFG_FILE" ]]; then
|
||||||
|
# Make a one-time backup of config.php before editing
|
||||||
|
cp "$CFG_FILE" "${CFG_FILE}.bak.$stamp" || true
|
||||||
|
|
||||||
|
# Flip FR_DEMO_MODE to true if it exists as false
|
||||||
|
sed -i "s/define('FR_DEMO_MODE',[[:space:]]*false);/define('FR_DEMO_MODE', true);/" "$CFG_FILE" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 7) Reload Apache (don’t fail the whole script if reload isn’t available)
|
||||||
systemctl reload apache2 2>/dev/null || true
|
systemctl reload apache2 2>/dev/null || true
|
||||||
|
|
||||||
echo "✅ FileRise updated to ${VER} (code). Data and public/.htaccess preserved."
|
echo "FileRise updated to ${VER} (code). Demo mode forced ON. Data, Pro bundles, and demo site preserved."
|
||||||
@@ -327,6 +327,14 @@ class UserController
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defined('FR_DEMO_MODE') && FR_DEMO_MODE && $username === 'demo') {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => 'TOTP settings are disabled for the demo account.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$totp_enabled = isset($data['totp_enabled']) ? filter_var($data['totp_enabled'], FILTER_VALIDATE_BOOLEAN) : false;
|
$totp_enabled = isset($data['totp_enabled']) ? filter_var($data['totp_enabled'], FILTER_VALIDATE_BOOLEAN) : false;
|
||||||
$result = UserModel::updateUserPanel($username, $totp_enabled);
|
$result = UserModel::updateUserPanel($username, $totp_enabled);
|
||||||
echo json_encode($result);
|
echo json_encode($result);
|
||||||
@@ -348,6 +356,14 @@ class UserController
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defined('FR_DEMO_MODE') && FR_DEMO_MODE && $username === 'demo') {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode([
|
||||||
|
'error' => 'TOTP settings are disabled for the demo account.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$result = UserModel::disableTOTPSecret($username);
|
$result = UserModel::disableTOTPSecret($username);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
echo json_encode(["success" => true, "message" => "TOTP disabled successfully."]);
|
echo json_encode(["success" => true, "message" => "TOTP disabled successfully."]);
|
||||||
@@ -412,6 +428,16 @@ class UserController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$userId = $_SESSION['username'];
|
$userId = $_SESSION['username'];
|
||||||
|
|
||||||
|
if (defined('FR_DEMO_MODE') && FR_DEMO_MODE && $userId === 'demo') {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'TOTP settings are disabled for the demo account.',
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (!preg_match(REGEX_USER, $userId)) {
|
if (!preg_match(REGEX_USER, $userId)) {
|
||||||
http_response_code(400);
|
http_response_code(400);
|
||||||
echo json_encode(['status' => 'error', 'message' => 'Invalid user identifier']);
|
echo json_encode(['status' => 'error', 'message' => 'Invalid user identifier']);
|
||||||
@@ -438,6 +464,14 @@ class UserController
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$username = $_SESSION['username'] ?? ($_SESSION['pending_login_user'] ?? '');
|
||||||
|
if (defined('FR_DEMO_MODE') && FR_DEMO_MODE && $username === 'demo') {
|
||||||
|
http_response_code(403);
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode(['error' => 'TOTP setup is disabled for the demo account.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
self::requireCsrf();
|
self::requireCsrf();
|
||||||
|
|
||||||
// Fix: if username not present (pending flow), fall back to pending_login_user
|
// Fix: if username not present (pending flow), fall back to pending_login_user
|
||||||
|
|||||||
Reference in New Issue
Block a user