#!/bin/sh # iris-browser — the Chrome-family launcher iris is pointed at (`iris --chrome ~/.local/bin/iris-browser`). # # Two jobs, both invisible to iris: # # 1. Pick the browser. Brave first — it is Chromium underneath, so CDP and the profile format are the # same — then Chromium, then Chrome. Iris only knows it asked for "a chrome". # # 2. Carry the user's sessions into the capture, read-only. The persistent profile is the one the # desktop's browser signs into (~/.config/officer/browser-profile); captures ride COPIES of its # cookies in a throwaway profile, so a capture can never corrupt or lock the profile that holds the # sessions, and the desktop browser being open never collides with a capture. # # Per-user isolation is $HOME: whoever runs iris gets their own profile, their own sessions, and nothing # of anyone else's. That is the kernel's answer, not this script's. # # The launcher (chromiumoxide) may pass its own --user-data-dir. If it does, we seed the sessions INTO # that directory and change nothing else — overriding it could break how the launcher finds the DevTools # socket. If it does not, we provide an ephemeral directory ourselves and clean it up. set -u PROFILE="${OFFICER_BROWSER_PROFILE:-$HOME/.config/officer/browser-profile}" BROWSER="" for candidate in brave-browser brave chromium chromium-browser google-chrome google-chrome-stable; do if BROWSER="$(command -v "$candidate" 2>/dev/null)" && [ -n "$BROWSER" ]; then break fi done if [ -z "$BROWSER" ]; then echo "iris-browser: no Chrome-family browser found (looked for brave, chromium, chrome)" >&2 echo "iris-browser: install the desktop plugin, or any of the above" >&2 exit 127 fi # Cookies plus the key that decrypts them. Login Data rides along so "remembered" form logins survive. # Everything else in a profile is cache and preference noise a capture does not need. seed_sessions() { dest="$1" [ -d "$PROFILE/Default" ] || return 0 mkdir -p "$dest/Default" cp "$PROFILE/Local State" "$dest/Local State" 2>/dev/null || true cp "$PROFILE/Default/Cookies" "$dest/Default/Cookies" 2>/dev/null || true cp "$PROFILE/Default/Login Data" "$dest/Default/Login Data" 2>/dev/null || true } # Did the launcher already choose a profile directory? CALLER_DIR="" for arg in "$@"; do case "$arg" in --user-data-dir=*) CALLER_DIR="${arg#--user-data-dir=}" ;; esac done if [ -n "$CALLER_DIR" ]; then seed_sessions "$CALLER_DIR" exec "$BROWSER" "$@" fi EPHEMERAL="$(mktemp -d "${TMPDIR:-/tmp}/iris-profile.XXXXXX")" trap 'rm -rf "$EPHEMERAL"' EXIT INT TERM seed_sessions "$EPHEMERAL" # --password-store=basic keeps cookie encryption portable between the profile and the copy — without it a # keyring-backed browser writes cookies the copy cannot decrypt. Appended AFTER the launcher's args, and # so is our --user-data-dir, because for a repeated switch Chrome honours the last occurrence. "$BROWSER" "$@" --user-data-dir="$EPHEMERAL" --password-store=basic exit $?