firefox_as ssh's to localhost, which can start a new session; the old mkdir -p then ran before mount-user-cifs-shares linked ~/network_drives/home, created a local tmpfs dir there (the mount script's ln -sf then put its link inside it), and Firefox got a fresh empty profile - and gopass broke for that session too. Now: refuse if home is a plain directory (with repair hint), otherwise wait up to 20s for the link (starting the mount service), and fail with a message instead of creating a local profile. Also drop the blank line before the shebang.
172 lines
6.4 KiB
Plaintext
Executable File
172 lines
6.4 KiB
Plaintext
Executable File
|
|
#!/usr/bin/env bash
|
|
|
|
# --- CONFIGURATION ---
|
|
# 1. Give your profile a distinct, single-word name (NO spaces)
|
|
PROFILE_NAME="SharedProfile"
|
|
|
|
# 2. Define exactly where the folder should live
|
|
PROFILE_DIR="$HOME/network_drives/home/.mozilla/shared_profile"
|
|
|
|
# Detect OS to set the correct Firefox binary path
|
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
FIREFOX_BIN="/Applications/Firefox.app/Contents/MacOS/firefox"
|
|
LOCK_FILE="$PROFILE_DIR/.parentlock"
|
|
else
|
|
FIREFOX_BIN="firefox" # Assumes 'firefox' is in your system PATH on Linux
|
|
LOCK_FILE="$PROFILE_DIR/lock"
|
|
fi
|
|
|
|
# ---------------------
|
|
|
|
# --- MAKE SURE THE SHARED HOME IS REALLY MOUNTED ---
|
|
# ~/network_drives/home is a symlink that mount-user-cifs-shares.service
|
|
# (/opt/pli/bin/create-network-drive-links) creates asynchronously at the
|
|
# start of a session. firefox_as ssh's to localhost, which often IS the
|
|
# start of a new session, so we can get here before that link exists.
|
|
# Never mkdir under it in that case: a plain directory there makes the
|
|
# mount script's "ln -sf" put its link INSIDE it, leaving the whole
|
|
# session with a local, empty "home" (new firefox profile, broken gopass).
|
|
fail() {
|
|
echo "[ERROR] $1" >&2
|
|
zenity --error --title="Firefox shared profile" --width=480 --text="$1" 2>/dev/null
|
|
exit 1
|
|
}
|
|
|
|
if [[ "$OSTYPE" != "darwin"* ]]; then
|
|
NET_HOME="$HOME/network_drives/home"
|
|
if [ -e "$NET_HOME" ] && [ ! -L "$NET_HOME" ]; then
|
|
fail "$NET_HOME is a local directory, not the link to your network home.\n\nSomething created it before the network drives were mounted, so this session cannot see the shared profile (or gopass).\n\nFix: close everything that uses it, then run:\n mv $NET_HOME ${NET_HOME}.broken\n setup-network-drives"
|
|
fi
|
|
for i in $(seq 1 20); do
|
|
[ -L "$NET_HOME" ] && [ -d "$NET_HOME/" ] && break
|
|
if [ "$i" -eq 3 ]; then
|
|
echo "[INFO] Waiting for network drives to be mounted..."
|
|
systemctl --user start mount-user-cifs-shares.service 2>/dev/null
|
|
fi
|
|
sleep 1
|
|
done
|
|
if ! [ -L "$NET_HOME" ] || ! [ -d "$NET_HOME/" ]; then
|
|
fail "Network home $NET_HOME is not available (no Kerberos ticket?).\n\nRun 'setup-network-drives' in a terminal as $USER, then try again."
|
|
fi
|
|
fi
|
|
|
|
# Ensure the parent directory folder physically exists first
|
|
mkdir -p "$PROFILE_DIR"
|
|
|
|
# Check if the folder is empty/doesn't exist
|
|
if [ ! -d "$PROFILE_DIR" ] || [ -z "$(ls -A "$PROFILE_DIR")" ]; then
|
|
echo "[INFO] Profile not found or empty. Forcing registration via Firefox CLI..."
|
|
|
|
# Modern Firefox fix: We use -CreateProfile paired with a dummy screenshot
|
|
# to force Firefox to write the directory structure and exit cleanly.
|
|
$FIREFOX_BIN -CreateProfile "$PROFILE_NAME $PROFILE_DIR" --headless --screenshot /dev/null > /dev/null 2>&1
|
|
|
|
echo "[SUCCESS] Profile '$PROFILE_NAME' registered at: $PROFILE_DIR"
|
|
else
|
|
echo "[INFO] Profile folder already exists. Skipping creation step."
|
|
fi
|
|
|
|
|
|
SIGNAL_FILE="$PROFILE_DIR/remote_shutdown.signal"
|
|
|
|
|
|
|
|
|
|
# --- NEW NETWORK-SAFE LOCK DETECTION LOGIC ---
|
|
echo "[INFO] Scanning for active network locks..."
|
|
|
|
# Force network share to drop local metadata cache
|
|
ls -la "$PROFILE_DIR" > /dev/null 2>&1
|
|
|
|
ACTIVE_LOCK_FOUND=false
|
|
|
|
# Check all 3 potential lock names
|
|
for POSSIBLE_LOCK in "lock" ".parentlock" "parent.lock"; do
|
|
TARGET_LOCK_PATH="$PROFILE_DIR/$POSSIBLE_LOCK"
|
|
|
|
if [ -e "$TARGET_LOCK_PATH" ] || [ -L "$TARGET_LOCK_PATH" ]; then
|
|
|
|
# FIXED: We use -newermt to see if the lock was touched within the last 25 seconds.
|
|
# This operates natively across Linux/Mac and accepts precise time strings safely.
|
|
IS_ACTIVE=$(find "$TARGET_LOCK_PATH" -newermt '25 seconds ago' 2>/dev/null)
|
|
|
|
if [ -n "$IS_ACTIVE" ]; then
|
|
echo "[WARN] Active remote lock verified: $POSSIBLE_LOCK (Modified within last 25s)"
|
|
ACTIVE_LOCK_FOUND=true
|
|
break
|
|
else
|
|
echo "[INFO] Stale lock ignored: $POSSIBLE_LOCK (Not modified recently)"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Act on our findings
|
|
if [ "$ACTIVE_LOCK_FOUND" = true ]; then
|
|
zenity --question \
|
|
--title="Firefox Profile Warning" \
|
|
--text="This profile is actively running on another computer.\n\nDo you want to send a SHUTDOWN SIGNAL to close the other session remotely?" \
|
|
--ok-label="Close Other & Open Here" \
|
|
--cancel-label="Cancel Launch" \
|
|
--width=420 2>/dev/null
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "[INFO] Creating shutdown signal file..."
|
|
touch "$SIGNAL_FILE"
|
|
|
|
(
|
|
for i in {1..12}; do
|
|
ls -la "$PROFILE_DIR" > /dev/null 2>&1
|
|
|
|
# Update the progress tracker loop to use the same -newermt logic
|
|
STILL_ACTIVE=$(find "$PROFILE_DIR" \( -name "lock" -o -name ".parentlock" -o -name "parent.lock" \) -newermt '25 seconds ago' 2>/dev/null)
|
|
if [ -z "$STILL_ACTIVE" ]; then
|
|
echo 100; break
|
|
fi
|
|
echo $((i * 8))
|
|
sleep 1
|
|
done
|
|
) | zenity --progress --title="Waiting" --text="Signaling remote session to close cleanly..." --auto-close --width=300 2>/dev/null
|
|
|
|
rm -f "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" "$PROFILE_DIR/parent.lock" "$SIGNAL_FILE"
|
|
else
|
|
echo "[INFO] Aborted by user."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
echo "[INFO] Launching Firefox instance..."
|
|
|
|
# FIX: Added the '&' back to the end of the line so the script can continue
|
|
# executing the background heartbeat loop while Firefox runs.
|
|
$FIREFOX_BIN --profile "$PROFILE_DIR" -no-remote > /dev/null 2>&1 &
|
|
|
|
FF_PID=$! # This will now successfully capture Firefox's background PID
|
|
|
|
echo "[INFO] Monitoring session (PID: $FF_PID). Close the window to exit."
|
|
|
|
# --- STEP 3: BACKGROUND MONITORING LOOP WITH HEARTBEAT ---
|
|
while kill -0 $FF_PID 2>/dev/null; do
|
|
# 1. Update our local lock file timestamp so other machines know we are alive
|
|
touch "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" 2>/dev/null
|
|
|
|
# 2. Check for the remote shutdown signal
|
|
if [ -f "$SIGNAL_FILE" ]; then
|
|
echo "[SIGNAL] Remote shutdown request received! Closing Firefox..."
|
|
kill -15 $FF_PID
|
|
rm -f "$SIGNAL_FILE"
|
|
wait $FF_PID 2>/dev/null
|
|
break
|
|
fi
|
|
sleep 3 # Heartbeat/check interval every 3 seconds
|
|
done
|
|
|
|
# Safety wait to ensure the process is fully reaped if closed manually
|
|
wait $FF_PID 2>/dev/null
|
|
|
|
# Final local cleanup
|
|
rm -f "$PROFILE_DIR/lock" "$PROFILE_DIR/.parentlock" "$PROFILE_DIR/parent.lock"
|
|
echo "[INFO] Session closed cleanly."
|
|
exit 0
|
|
|