|
- #!/bin/sh
-
- if [ "$#" -gt 1 ]; then
- echo "To many arguments. You will be asked."
- exit
- fi
-
- if [[ -z $prefix ]]; then
- case "$(uname)" in
- Linux) prefix="/usr" ;;
- *) prefix="/usr/local" ;;
- esac
- fi
-
- command -V gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2"
- [ -z $PASSWORD_STORE_DIR ] && PASSWORD_STORE_DIR="$HOME/.password-store"
- [ -r "$PASSWORD_STORE_DIR/.gpg-id" ] &&
- "$GPG" --list-secret-keys $(cat "$PASSWORD_STORE_DIR/.gpg-id") >/dev/null 2>&1 || {
- printf "\`pass\` must be installed and initialized to encrypt passwords.\\nBe sure it is installed and run \`pass init <yourgpgemail>\`.\\nIf you don't have a GPG public private key pair, run \`$GPG --full-gen-key\` first.\\n"
- exit
- }
- ! command -v $prefix/bin/mbsync >/dev/null && printf "\`mbsync\` must be installed to run mutt-wizard.\\n" && exit
- ! command -v $prefix/bin/msmtp >/dev/null && printf "\`msmtp\` must be installed.\\n" && exit
- ! ( command -v mutt >/dev/null || command -v neomutt >/dev/null ) && printf "\`mutt\` must be installed.\\n" && exit
-
- mwconfigdir=${XDG_CONFIG_HOME:-$HOME/.config}
- # Main mutt config location
- mwmuttdir="$mwconfigdir/mutt"
- # Directory for account settings
- mwaccdir="$mwmuttdir/accounts"
- # Location of mail storage
- mwmaildir="${MAILDIR:-${XDG_DATA_HOME:-$HOME/.local/share}/mail}"
- # Regex to confirm valid email address
- mwemailre=".\+@.\+\\..\+"
- mwshare="$prefix/share/mutt-wizard"
- if [[ -n $XDG_CONFIG_HOME ]]; then
- mwmbsyncrc="$mwconfigdir/isync/mbsyncrc"
- else
- mwmbsyncrc="$HOME/.mbsyncrc"
- fi
- mwconfig="$mwshare/mutt-wizard.muttrc"
- mwcachedir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard"
- mwmuttrc="$mwmuttdir/muttrc"
- mwmsmtprc="$mwconfigdir/msmtp/config"
- mwssltype="IMAPS"
- mbsyncbin="$prefix/bin/mbsync -c $mwmbsyncrc"
- msmtpbin="$prefix/bin/msmtp"
-
- for x in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" "/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
- do
- [ -f "$x" ] && sslcert="$x" && break
- done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && exit 1 ;}
-
- getaccounts() { accounts="$(find "$mwaccdir" -type f | grep -o "[0-9]-.*.muttrc" | sed "s/-/: /;s/\..*//" | sort -n)" ;}
-
- mwlist() { getaccounts && [ -n "$accounts" ] && echo "$accounts" ;}
-
- mwadd() { asktype && askinfo && tryconnect && finalize || mwdelete ;}
-
- getprofiles() { \
- unset msmtp_header msmtp_profile mutt_profile mbsync_profile
- printf "Creating profiles for \`%s\`..." "$mwaccount"
- msmtp_header="defaults
- auth on
- tls on
- tls_trust_file $sslcert
- logfile ${XDG_LOG_HOME:-$HOME}/msmtp.log
- "
- msmtp_profile="account $mwaccount
- host $mwsmtp
- port $mwsport
- from $mwaddr
- user $mwlogin
- passwordeval \"pass $mwpass\"
- $starttlsoff
- "
- mbsync_profile="IMAPStore $mwaccount-remote
- Host $mwimap
- Port $mwiport
- User $mwlogin
- PassCmd \"pass $mwpass\"
- SSLType $mwssltype
- CertificateFile $sslcert
-
- MaildirStore $mwaccount-local
- Subfolders Verbatim
- Path $mwmaildir/$mwaccount/
- Inbox $mwmaildir/$mwaccount/INBOX
- Flatten .
-
- Channel $mwaccount
- Expunge Both
- Master :$mwaccount-remote:
- Slave :$mwaccount-local:
- Patterns * !\"[Gmail]/All Mail\"
- Create Both
- SyncState *
- MaxMessages 0
- # End profile
- "
-
- if [ "$mwtype" = "offline" ]; then
- mutt_profile="# vim: filetype=neomuttrc
- # muttrc file for account $mwaccount
- set realname = \"$mwname\"
- set from = \"$mwaddr\"
- set sendmail = \"$msmtpbin -a $mwaccount\"
- alias me $mwname <$mwaddr>
- set folder = \"$mwmaildir/$mwaccount\"
- set mbox_type = Maildir
-
- macro index gm \"<shell-escape>mailsync -V $mwaccount<enter>\" \"sync mail $mwaccount\"
-
- unmailboxes *
- "
- else
- mutt_profile="# vim: filetype=neomuttrc
- # muttrc file for account $mwaccount
- set realname = \"$mwname\"
- set from = \"$mwaddr\"
- set sendmail = \"$msmtpbin -a $mwaccount\"
- alias me $mwname <$mwaddr>
- set folder = \"imaps://$mwaddr@$mwimap:$mwiport\"
- set imap_user = \"$mwlogin\"
- set header_cache = $mwcachedir/$mwaccount/headers
- set message_cachedir = $mwcachedir/$mwaccount/bodies
- set imap_pass = \"\`pass $mwpass\`\"
-
- set mbox_type = Maildir
- set ssl_starttls = yes
- set ssl_force_tls = yes
-
- unmailboxes *
- "
- fi
- printf "DONE.\\n"
- }
-
- askinfo() { \
- if [ -z $mwaddr ]; then
- printf "Type the \033[31memail address\033[0m\\n\t\033[36m"
- read -r mwaddr
- printf "\033[0m"
- while ! echo "$mwaddr" | grep "$mwemailre" >/dev/null; do
- printf "That is not a valid \033[31memail address\033[0m, please retype\\n\t\033[36m"
- read -r mwaddr
- printf "\033[0m"
- done
- fi
- domain="$(echo "$mwaddr" | sed "s/.*@//")"
- printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$domain"
- mwserverinfo="$(grep "^$domain" "$mwshare/domains.csv" 2>/dev/null)"
- if [ -z "$mwserverinfo" ]; then
- printf "Your email domain is not known to mutt-wizard.\\nType in your settings.\\nUsually you find them by an internet search.\\n"
- printf "Type the IMAP server (excluding the port number)\\n\033[36m\t"
- read -r mwimap
- printf "\033[0mIMAP port number (usually 993)\\n\033[36m\t"
- read -r mwiport
- printf "\033[0mSMTP server (excluding the port number)\\n\033[36m\t"
- read -r mwsmtp
- printf "\033[0mSMTP port number (usually 587 or 465)\\n\033[36m\t"
- read -r mwsport
- printf "\033[0m\\nIf you want, you can copy the line below and add it to the \`domains.csv\` file on Github, for others.\\n\\n%s,%s,%s,%s,%s\\n\\nBut be sure the setting works, first! ;-)\\n" "$domain" "$mwimap" "$mwiport" "$mwsmtp" "$mwsport"
- else
- IFS=, read -r mwservice mwimap mwiport mwsmtp mwsport <<EOF
- $mwserverinfo
- EOF
- printf "\\n\033[3;33mCongrats!\033[0m Server info is known, so you don't need to look it up!\\n\t\033[1mIMAP server\033[0m: %s\\n\t\033[1mIMAP port\033[0m: %s\\n\t\033[1mSMTP server\033[0m: %s\\n\t\033[1mSMTP port\033[0m: %s\\n" "$imap" "$mwiport" "$mwsmtp" "$mwsport"
- case "$mwservice" in
- gmail.com) printf "\033[31mGmail: \"less secure\" must be enabled before you continue.\\nDo it now, if you have not done it already:\\nhttps://support.google.com/accounts/answer/6010255\\n\033[0m" ;;
- protonmail.ch|protonmail.com|pm.me) printf "\033[31mProtonmail: Users must install and configure Protonmail Bridge for the sync to work:\\nhttps://protonmail.com/bridge/\\n\033[0m" && ssltype="None" ;;
- esac
- [ "$mwsport" = 465 ] && starttlsoff="tls_starttls off"
- fi
- if [ -z "$mwname" ]; then
- printf "Name to associate to email.\\n\t"
- read -r mwname
- fi
- mwaccount=$mwaddr
- if [ -z $mwlogin ]; then
- printf "Type your account username if different from your email address.\\n\033[34mFor most accounts you can probably leave this blank.\033[0m\\n\tLogin(?): \033[36m"
- read -r mwlogin
- printf "\033[0m"
- [ -z "$mwlogin" ] && mwlogin="$mwaddr"
- fi
- if [ -z "$mwpass" ]; then
- mwpass=mutt-wizard-$mwaccount
- getpass
- fi
- getprofiles
- mkdir -p "$mwmuttdir" "$mwaccdir" "$mwcachedir/$mwaccount/bodies" "$mwconfigdir/msmtp"
- getaccounts
- for x in $(seq 1 9); do echo "$accounts" | grep "$x" >/dev/null 2>&1 || { export idnum="$x"; break ;}; done
- [ ! -f "$mwmsmtprc" ] && echo "$msmtp_header" > "$mwmsmtprc"
- echo "$msmtp_profile" >> "$mwmsmtprc"
- case "$mwservice" in
- protonmail.ch|protonmail.com|pm.me) protonfinger || return 1 ;;
- esac
- echo "$mutt_profile" > "$mwaccdir/$idnum-$mwaccount.muttrc"
- mkdir -p ${mwmbsyncrc%/*}
- echo "$mbsync_profile" >> "$mwmbsyncrc"
- [ ! -f "$mwmuttrc" ] && echo "# vim: filetype=neomuttrc" > "$mwmuttrc" && echo "muttrc created."
- ! grep "^source.*mutt-wizard.muttrc" "$mwmuttrc" >/dev/null && echo "source $mwconfig # mw-autogenerated" >> "$mwmuttrc"
- ! grep "^source.*.muttrc" "$mwmuttrc" | grep -v "$mwconfig" >/dev/null && echo "source $mwaccdir/$idnum-$mwaccount.muttrc # mw-autogenerated" >> "$mwmuttrc"
- echo "macro index,pager i$idnum '<sync-mailbox><enter-command>source $mwaccdir/$idnum-$mwaccount.muttrc<enter><change-folder>!<enter>;<check-stats>' \"switch to $mwaddr\" # mw-autogenerated" >> "$mwmuttrc"
- [ "$mwtype" = "offline" ] && echo "macro index gM '<shell-escape>mailsync -Va<enter>' \"sync all mail\" # mw-autogenerated" >> "$mwmuttrc"
- return 0
- }
-
- protonfinger() { printf "Getting Protonmail bridge fingerprint...\\n"
- fingerprint="$($msmtpbin --serverinfo --host=127.0.0.1 --port=1025 --tls --tls-certcheck=off)" || return 1
- sed -i "s/account $mwaccount/&\ntls_trust_file\ntls_fingerprint $fingerprint/" "$mwmsmtprc"
- }
-
- getpass() { while : ; do pass rm -f "$mwpass" >/dev/null 2>&1
- pass insert "$mwpass" && break; done ;}
-
- formatShortcut() { \
- while read -r data; do { echo "macro index,pager g$1 \"<change-folder>$data<enter>\" \"go to $2\" # mw-autogenerated"
- echo "macro index,pager M$1 \"<save-message>$data<enter>\" \"move mail to $2\" # mw-autogenerated"
- echo "macro index,pager C$1 \"<copy-message>$data<enter>\" \"copy mail to $2\" # mw-autogenerated"; } >> "$mwaccdir/$idnum-$mwaccount.muttrc"
- done ;}
-
- tryconnect() { \
- if [ -z "$mailboxes" ]; then
- mkdir -p $mwmaildir/$mwaccount
- mailboxes="$($mbsyncbin -l $mwaccount | sed 's/\//./')" >/dev/null 2>&1
- fi
- if [ -n "$mailboxes" ]; then
- [ "$mwtype" = "online" ] && sed -i "/IMAPStore $mwaccount-remote$/,/# End profile/d" "$mwmbsyncrc"
- [ "$mwtype" = "offline" ] && notmuchauto
- printf "\033[32mMailboxes detected.\033[0m\\n"
- echo "$mailboxes" | xargs -I {} mkdir -p "$mwmaildir/$mwaccount/{}"
- return 0
- else
- printf "\033[31m\033[31mLog-on not successful.\033[0m\\nIt seems that either you inputted the wrong password or server settings, or there are other requirements for your account out of the control of mutt-wizard.\\n"
- return 1
- fi ;}
-
- finalize() { \
- boxes="$(find "$mwmaildir/$mwaccount/" -mindepth 1 -maxdepth 1 | sed "s/\ /\\\ /g;s/^.*\//=/")"
- [ -z "$boxes" ] && printf "\033[31mNo local mailboxes have been detected for %s.\033[0m\\nThis means that mbsync has not been successfully run.\\nRun mbsync, and if it has an error, be sure to check your password and server settings manually if needbe.\\n" "$mwaccount" && return
- printf "Setting default mailboxes for your Inbox, Sent, Drafts and Trash in mutt...\\n"
- spoolfile=$(echo "$boxes" | grep -i -m 1 inbox | sed 's/=/+/g')
- record=$(echo "$boxes" | grep -i -m 1 sent | sed 's/=/+/g')
- postponed=$(echo "$boxes" | grep -i -m 1 draft | sed 's/=/+/g')
- trash=$(echo "$boxes" | grep -i -m 1 trash | sed 's/=/+/g')
- sed -i "/^mailboxes\|^set record\|^set postponed\|^set trash\|^set spoolfile/d" "$mwaccdir/$idnum-$mwaccount.muttrc"
- { echo "set spoolfile = \"$spoolfile\""; echo "set record = \"$record\""; echo "set postponed = \"$postponed\""; echo "set trash = \"$trash\""; } >> "$mwaccdir/$idnum-$mwaccount.muttrc"
- echo "mailboxes =$mwaccount ===================== $(echo "$boxes" | sed -e "s/^\|$/\"/g" | tr "\n" " ")" >> "$mwaccdir/$idnum-$mwaccount.muttrc"
- printf "Setting up your keyboard shortcuts for jumping between mailboxes...\\n"
- sed -i "/# mw-autogenerated/d" "$mwaccdir/$idnum-$mwaccount.muttrc"
- echo "$boxes" | grep -i inbox | head -n 1 | formatShortcut i inbox
- echo "$boxes" | grep -i sent | head -n 1 | formatShortcut s sent
- echo "$boxes" | grep -i draft | head -n 1 | formatShortcut d drafts
- echo "$boxes" | grep -i trash | head -n 1 | formatShortcut t trash
- echo "$boxes" | grep -i spam | head -n 1 | formatShortcut S spam
- echo "$boxes" | grep -i junk | head -n 1 | formatShortcut j junk
- echo "$boxes" | grep -i archive | head -n 1 | formatShortcut a archive
- [ "$mwtype" = "offline" ] && printf "All done.\\n\033[33mYou can now run \`\033[32mmailsync [%s]\033[33m\` to sync your mail.\033[0m\\n" "$mwaccount"
- command -V urlview >/dev/null 2>&1 && [ ! -f "$HOME/.urlview" ] && echo "COMMAND \$BROWSER" > "$HOME/.urlview"
- return 0
- }
-
- confirm() { printf "[y/N]: Do you want to %s?\\n\t" "$@" && read -r input && ! echo "$input" | grep -i "^y$\|^yes$" >/dev/null && printf "That doesn't seem like a yes to me.\\n\\n" && return 1
- return 0 ;}
-
- mwpick() { printf "Select an accounts to %s:\\n" "$1"
- mwlist
- read -r input
- [ -z "$input" ] && return 1
- mwaccount="$(echo "$accounts" | grep "$input" | awk '{print $2}')"
- [ -z "$mwaccount" ] && printf "Invalid response." && return 1
- return 0 ;}
-
- mwdelete() { sed -i "/IMAPStore $mwaccount-remote$/,/# End profile/d" "$mwmbsyncrc"
- rm -rf "${mwcachedir:?}/${mwaccount:?}" "$mwaccdir/"[1-9]"-$mwaccount.muttrc"
- sed -i "/[0-9]-$mwaccount.muttrc/d" "$mwmuttrc"
- sed -i "/account $mwaccount/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
- }
-
- mwcron() { ! pgrep cron >/dev/null && echo "No cron manager running. Install/enable one and then select this option again." && return 1
- if crontab -l | grep mailsync >/dev/null; then
- echo "Active mail sync cronjob detected. Do you want to remove it?"
- printf "\033[36m\t"
- read -r rmyn
- printf "\033[0m"
- echo "$rmyn" | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null && echo "Mail sync turned off."
- else
- echo "How many minutes between each mail sync?"
- printf "\033[36m\t"
- read -r minnum
- printf "\033[0m"
- while ! echo "$minnum" | grep "^[0-9]\+$" >/dev/null; do
- printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t"
- read -r minnum
- printf "\033[0m"
- done
- (crontab -l; echo "*/$minnum * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mailsync | cut -d' ' -f3)") | crontab - &&
- echo "Cronjob added. Mail will sync every $minnum minutes. Be sure you have your cron manager running."
- fi ;}
-
- asktype() { \
- if [ -z "$mwtype" ]; then
- while : ; do
- printf "[yes/no]: Local mail via mbsync? No: Mutt remotes (slower)\\n\t"
- read -r offnot
- case "$offnot" in
- [Yy][Ee][Ss]) mwtype="offline" && break ;;
- [Nn][Oo]) mwtype="online" && break ;;
- *) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;;
- esac
- done
- fi
- }
-
- mwpurge() {
- confirm "delete all account data" || exit
- rm -rf "$mwmbsyncrc" "$mwaccdir" "$mwconfigdir/msmtp" "$mwcachedir"
- pgrep cron >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null
- sed -i "/\# mw-autogenerated/d" "$mwmuttrc"
- echo "All configs and account settings have been purged."
- }
-
- notmuchauto() { \
- [ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config"
- [ -f "$NOTMUCH_CONFIG" ] && return 0
- nmbasic="[database]
- path=$mwmaildir
- [user]
- name=$mwname
- primary_email=$mwaddr
- [new]
- tags=unread;inbox;
- ignore=
- [search]
- exclude_tags=deleted;spam;
- [maildir]
- synchronize_flags=true
- [crypto]
- gpg_path=$GPG"
- mkdir -p ${NOTMUCH_CONFIG%/*}
- echo "$nmbasic" > "$NOTMUCH_CONFIG" ;}
-
- trap 'echo -e "\033[0m\n"; exit' STOP INT ABRT KILL
-
- if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
- case "$1" in
- ls) mwlist ;;
- add) mwadd ;;
- pass) mwpick "change the password of" && getpass ;;
- delete) mwpick delete && confirm "delete the \`$mwaccount\` profile" && mwdelete ;;
- purge) mwpurge ;;
- cron) mwcron ;;
- *) cat << EOF
- mw: mutt-wizard, auto-configure email accounts for mutt
- including downloadable mail with \`isync\`.
-
- Allowed options:
- add Add and autoconfigure an email address (9 max.)
- ls List configured accounts
- delete Pick an account to delete
- purge Delete all accounts and settings
- cron Enable or disable an autosync via cronjob
- all else Print this message
-
- NOTE: Once at least one account is added, you can run
- \`mailsync -a\` to begin downloading mail.
- EOF
- esac
- fi
|