diff --git a/install.sh b/install.sh index 2c7aea6..53e5448 100755 --- a/install.sh +++ b/install.sh @@ -20,6 +20,18 @@ info() { echo -e "${BLUE}$1${NC}"; } warn() { echo -e "${YELLOW}$1${NC}"; } header() { echo -e "\n${BOLD}${CYAN}$1${NC}"; } +# ============================================================ +# USER & SUDO +# ============================================================ +SYS_USER="${SUDO_USER:-$USER}" +SYS_HOME=$(eval echo "~$SYS_USER") +[ "$EUID" -eq 0 ] && SUDO="" || SUDO="sudo" + +if [ -z "$SUDO" ] && [ "$EUID" -ne 0 ]; then + error "This script needs root for /opt/ and systemd. Use: sudo bash install.sh" + exit 1 +fi + # ============================================================ # PATHS # ============================================================ @@ -29,7 +41,7 @@ BIN_DIR="${INSTALL_DIR}/bin" DATA_DIR="${INSTALL_DIR}/data" STATIC_DIR="${INSTALL_DIR}/static" CONFIG_FILE="${INSTALL_DIR}/config.yaml" -ENV_FILE="${REPO_DIR}/.env" +ENV_FILE="${SYS_HOME}/.nextwks-env" AUTHELIA_DIR="/opt/authelia" AUTHELIA_CONFIG="${AUTHELIA_DIR}/configuration.yml" SERVICE_FILE="/etc/systemd/system/nextwks.service" @@ -69,9 +81,10 @@ if [ ! -f "$REPO_DIR/src/main.go" ]; then error "git is required. Install it first: apt install git" exit 1 fi - CLONE_DIR="/tmp/nextwks-install" + CLONE_DIR="${SYS_HOME}/nextwks" rm -rf "$CLONE_DIR" 2>/dev/null git clone --depth 1 "$REPO_URL" "$CLONE_DIR" + chown -R "$SYS_USER:$SYS_USER" "$CLONE_DIR" 2>/dev/null || true REPO_DIR="$CLONE_DIR" success "Cloned to $REPO_DIR" fi @@ -98,11 +111,11 @@ done # ============================================================ if [ "$MODE" = "uninstall" ]; then info "Uninstalling Next Workspace..." - systemctl stop nextwks 2>/dev/null || true - systemctl disable nextwks 2>/dev/null || true - rm -f "$SERVICE_FILE" - systemctl daemon-reload - [ -d "$INSTALL_DIR" ] && { rm -rf "$INSTALL_DIR"; success "Removed $INSTALL_DIR"; } + $SUDO systemctl stop nextwks 2>/dev/null || true + $SUDO systemctl disable nextwks 2>/dev/null || true + $SUDO rm -f "$SERVICE_FILE" + $SUDO systemctl daemon-reload + [ -d "$INSTALL_DIR" ] && { $SUDO rm -rf "$INSTALL_DIR"; success "Removed $INSTALL_DIR"; } success "Uninstall complete" exit 0 fi @@ -114,8 +127,8 @@ if [ "$MODE" = "status" ]; then echo ""; header "Next Workspace Status" [ -f "${BIN_DIR}/core" ] && success "✓ Binary: ${BIN_DIR}/core" || warn "✗ Binary: not found" [ -f "$CONFIG_FILE" ] && success "✓ Config: $CONFIG_FILE" || warn "✗ Config: not found" - systemctl is-active --quiet nextwks 2>/dev/null && success "✓ Service: running" || info " Service: stopped" - systemctl is-active --quiet authelia 2>/dev/null && success "✓ Authelia: running" || info " Authelia: stopped" + $SUDO systemctl is-active --quiet nextwks 2>/dev/null && success "✓ Service: running" || info " Service: stopped" + $SUDO systemctl is-active --quiet authelia 2>/dev/null && success "✓ Authelia: running" || info " Authelia: stopped" command -v curl &>/dev/null && [ "$(curl -s --max-time 2 http://localhost:8080/api/health 2>/dev/null)" = '{"status":"ok"}' ] && success "✓ API: OK" || info " API: not responding" echo ""; exit 0 fi @@ -241,9 +254,11 @@ success "Binary built: app/core (${VERSION})" # INSTALL # ============================================================ header "── Installing ──" -mkdir -p "$BIN_DIR" "$DATA_DIR" "$STATIC_DIR" -cp "$REPO_DIR/app/core" "$BIN_DIR/core" && chmod 755 "$BIN_DIR/core" -[ -d "$REPO_DIR/app/static" ] && cp -r "$REPO_DIR/app/static"/* "$STATIC_DIR/" +$SUDO mkdir -p "$BIN_DIR" "$DATA_DIR" "$STATIC_DIR" +$SUDO cp "$REPO_DIR/app/core" "$BIN_DIR/core" +$SUDO chmod 755 "$BIN_DIR/core" +$SUDO chown -R "$SYS_USER:$SYS_USER" "$DATA_DIR" 2>/dev/null || true +[ -d "$REPO_DIR/app/static" ] && $SUDO cp -r "$REPO_DIR/app/static"/* "$STATIC_DIR/" success "Copied files to $INSTALL_DIR/" # ============================================================ @@ -253,7 +268,7 @@ header "── Configuration ──" ADMIN_TOKEN=$(openssl rand -hex 32 2>/dev/null || head -c32 /dev/urandom | xxd -p -c32) SESSION_KEY=$(openssl rand -hex 32 2>/dev/null || head -c32 /dev/urandom | xxd -p -c32) -cat > "$CONFIG_FILE" << CONFIGEOF +$SUDO tee "$CONFIG_FILE" > /dev/null << CONFIGEOF # Next Workspace — $(date +%Y-%m-%d) server: host: "0.0.0.0" @@ -283,14 +298,14 @@ session: secret: "${SESSION_KEY}" expiry_minutes: 60 CONFIGEOF -chmod 600 "$CONFIG_FILE" +$SUDO chmod 600 "$CONFIG_FILE" success "Config: $CONFIG_FILE" # ============================================================ # SYSTEMD # ============================================================ header "── Systemd ──" -cat > "$SERVICE_FILE" << SERVICEEOF +$SUDO tee "$SERVICE_FILE" > /dev/null << SERVICEEOF [Unit] Description=Next Workspace (NextWks) Core After=network.target authelia.service @@ -298,7 +313,7 @@ Wants=authelia.service [Service] Type=simple -User=root +User=${SYS_USER} WorkingDirectory=${INSTALL_DIR} ExecStart=${BIN_DIR}/core -config ${CONFIG_FILE} Restart=always @@ -316,7 +331,7 @@ ReadOnlyPaths=${INSTALL_DIR}/config.yaml ${INSTALL_DIR}/static [Install] WantedBy=multi-user.target SERVICEEOF -systemctl daemon-reload +$SUDO systemctl daemon-reload success "Service: $SERVICE_FILE" # ============================================================ @@ -337,7 +352,7 @@ if [ -f "${AUTHELIA_DIR}/authelia" ]; then # Hash current admin password (if users exist) or generate one ADMIN_HASH=$("${AUTHELIA_DIR}/authelia" crypto hash generate --password "$(openssl rand -base64 12)" 2>/dev/null | awk '{print $NF}' || echo "\$argon2id\$v=19\$m=65536,t=3,p=4\$placeholder\$placeholder") - cat > "$AUTHELIA_CONFIG" << AUTHEOF + $SUDO tee "$AUTHELIA_CONFIG" > /dev/null << AUTHEOF theme: light server: host: 0.0.0.0 @@ -405,7 +420,7 @@ $(echo "$OIDC_KEY" | sed 's/^/ /') pre_configured_consent_duration: "1 year" userinfo_signed_response_alg: "none" AUTHEOF - chmod 600 "$AUTHELIA_CONFIG" + $SUDO chmod 600 "$AUTHELIA_CONFIG" success "Authelia config written" # Create initial users_database.yml (needed for Authelia to start) @@ -422,11 +437,11 @@ users: email: "${ADMIN_EMAIL:-admin@local}" groups: [admins] USERSDB - chmod 600 "${AUTHELIA_DIR}/users_database.yml" + $SUDO chmod 600 "${AUTHELIA_DIR}/users_database.yml" success "Users database created" fi - systemctl restart authelia 2>/dev/null && info "Authelia restarted" || info "Authelia not running (will start later)" + $SUDO systemctl restart authelia 2>/dev/null && info "Authelia restarted" || info "Authelia not running (will start later)" fi # ============================================================ @@ -477,8 +492,8 @@ info " Workspace: ${NEXTWKS_URL}" info " Auth: ${AUTH_URL}" info " Admin UI: ${NEXTWKS_URL}/admin" echo "" -info " Start: systemctl enable --now nextwks" -info " Logs: journalctl -u nextwks -f" +info " Start: sudo systemctl enable --now nextwks" +info " Logs: sudo journalctl -u nextwks -f" info " Status: ./install.sh --status" echo "" if [ -n "${ADMIN_PASS:-}" ]; then