blob: 3e119f659f894074f0ec7f644d70399e949c0d9b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#!/usr/bin/env bash
# cmail-setup-finish.sh — finish Proton Mail Bridge + cmail-action setup after
# Bridge first-run. Idempotent; safe to re-run after a Bridge cert rotation or
# a claude-templates re-clone.
#
# Pre-reqs (the script aborts if any are missing):
# - protonmail-bridge installed (archsetup handles it)
# - You have run 'protonmail-bridge --cli', logged in, and quit at least once
# (the script looks for state at ~/.config/protonmail/bridge-v3/)
# - claude-templates cloned at ~/projects/claude-templates
# - dotfiles stowed (~/.config/.cmailpass.gpg present)
#
# What it does:
# 1. Decrypts ~/.config/.cmailpass.gpg → ~/.config/.cmailpass (mode 0600)
# 2. Copies Bridge's self-signed cert → ~/.config/protonbridge.pem
# 3. Symlinks ~/projects/claude-templates/.ai/scripts/cmail-action.py
# → ~/.local/bin/cmail-action
# 4. Removes the leftover ~/.config/autostart/Proton Mail Bridge.desktop
# stub (it double-launches Bridge alongside the systemd user service
# and throws an "orphan instance" dialog every login)
# 5. Installs a wait-for-dns drop-in so Bridge doesn't spam
# name-resolution errors during the early-boot DNS race
# 6. Enables + starts the protonmail-bridge user service
# 7. Verifies Bridge is listening on 127.0.0.1:1143 / :1025
set -euo pipefail
err() { printf 'error: %s\n' "$*" >&2; exit 1; }
info() { printf '==> %s\n' "$*"; }
ok() { printf ' %s\n' "$*"; }
# 1. Pre-reqs
command -v protonmail-bridge >/dev/null 2>&1 \
|| err "protonmail-bridge not found in PATH — install via archsetup first"
bridge_state="$HOME/.config/protonmail/bridge-v3"
[ -d "$bridge_state" ] \
|| err "Bridge has no state at $bridge_state — run 'protonmail-bridge --cli' and log in first"
cmail_action_src="$HOME/projects/claude-templates/.ai/scripts/cmail-action.py"
[ -f "$cmail_action_src" ] \
|| err "cmail-action.py not found at $cmail_action_src — clone claude-templates first"
cmailpass_enc="$HOME/.config/.cmailpass.gpg"
[ -f "$cmailpass_enc" ] \
|| err "$cmailpass_enc not found — ensure dotfiles are stowed"
# 2. Decrypt cmailpass
info "decrypting $cmailpass_enc"
cmailpass_plain="$HOME/.config/.cmailpass"
gpg --quiet --yes --decrypt --output "$cmailpass_plain" "$cmailpass_enc"
chmod 600 "$cmailpass_plain"
ok "wrote $cmailpass_plain (mode 0600)"
# 3. Bridge cert
info "exporting Bridge cert"
cert_src="$(find "$bridge_state" -name 'cert.pem' -print -quit 2>/dev/null)"
[ -n "$cert_src" ] || err "no cert.pem found under $bridge_state — Bridge state is incomplete"
cert_dst="$HOME/.config/protonbridge.pem"
cp "$cert_src" "$cert_dst"
ok "copied $cert_src → $cert_dst"
# 4. Symlink cmail-action
info "symlinking cmail-action"
mkdir -p "$HOME/.local/bin"
ln -sf "$cmail_action_src" "$HOME/.local/bin/cmail-action"
ok "linked $HOME/.local/bin/cmail-action → $cmail_action_src"
# 5. Remove leftover XDG autostart stub
# The systemd --user service is the canonical launcher. The autostart .desktop
# starts a second Bridge instance that can't get the lock and pops up an
# "orphan instance" dialog every login.
info "removing orphan autostart launcher (if present)"
autostart_stub="$HOME/.config/autostart/Proton Mail Bridge.desktop"
if [ -f "$autostart_stub" ]; then
rm "$autostart_stub"
ok "removed $autostart_stub"
else
ok "no autostart stub present"
fi
# 6. Install wait-for-dns drop-in
# User-instance systemd doesn't carry network-online.target / nss-lookup.target,
# so the packaged unit's After=network.target doesn't imply DNS readiness.
# Bridge starts before the resolver is up and its first API calls all fail
# until DNS comes online a few seconds later. The drop-in waits (bounded 30s)
# for resolution before ExecStart. The leading '-' on ExecStartPre makes it
# non-fatal, so an offline boot still starts the unit.
info "installing wait-for-dns drop-in"
dropin_dir="$HOME/.config/systemd/user/protonmail-bridge.service.d"
dropin_file="$dropin_dir/wait-for-dns.conf"
mkdir -p "$dropin_dir"
cat > "$dropin_file" <<'EOF'
[Service]
ExecStartPre=-/bin/sh -c 'for i in $(seq 1 30); do getent hosts mail-api.proton.me >/dev/null 2>&1 && exit 0; sleep 1; done'
EOF
ok "wrote $dropin_file"
systemctl --user daemon-reload
ok "reloaded systemd user units"
# 7. Enable + start systemd user service
info "enabling protonmail-bridge user service"
was_active=0
systemctl --user is-active --quiet protonmail-bridge.service && was_active=1
systemctl --user enable --now protonmail-bridge
if [ "$was_active" = "1" ]; then
systemctl --user restart protonmail-bridge
ok "service active (restarted to pick up drop-in)"
else
ok "service active"
fi
# 8. Verify
info "verifying Bridge is listening"
if ss -ltn 2>/dev/null | grep -qE '127\.0\.0\.1:(1143|1025)'; then
ok "127.0.0.1:1143 + :1025 LISTEN"
else
err "Bridge isn't listening on the expected ports — check 'systemctl --user status protonmail-bridge'"
fi
echo
echo "cmail setup complete."
echo "Next: 'mbsync cmail && mu index' for the first sync."
|