aboutsummaryrefslogtreecommitdiff
path: root/scripts/cmail-setup-finish.sh
blob: 7f9d3fc40542a51c3c501545b17fbb2ed283cd65 (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
124
125
126
127
128
129
130
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-or-later
# 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"
listening="$(ss -ltn 2>/dev/null || true)"
missing=""
echo "$listening" | grep -q '127\.0\.0\.1:1143' || missing="$missing 1143 (IMAP)"
echo "$listening" | grep -q '127\.0\.0\.1:1025' || missing="$missing 1025 (SMTP)"
if [ -z "$missing" ]; then
    ok "127.0.0.1:1143 + :1025 LISTEN"
else
    error_status="$(systemctl --user status protonmail-bridge --no-pager --lines=10 2>&1 || true)"
    printf '%s\n' "$error_status" >&2
    err "Bridge isn't listening on:${missing}"
fi

echo
echo "cmail setup complete."
echo "Next: 'mbsync cmail && mu index' for the first sync."