|
- #!/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
- mwaccrcdir="$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
- mwsharerc="$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"
- takemwaddr(){
- mwacc="$mwaddr" # let the user always just deal with his email
- mwaccmutt="${mwaddr//[.@]/_}" # but mutt would not show it with an @ or .
- mwacccachedir=$mwcachedir/${mwaddr//[.@]/_} # @ cannot stay because of mutt, . could
- mwaccmaildir="$mwmaildir/$mwaccmutt" # folder name as shown by mutt and opens with gf in vim
- }
-
- 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 "$mwaccrcdir" -type f | grep -o "[0-9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc//" | 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\`..." "$mwaddr"
- msmtp_header="defaults
- auth on
- tls on
- tls_trust_file $sslcert
- logfile ${XDG_LOG_HOME:-$HOME}/msmtp.log
- "
- msmtp_profile="account $mwacc
- host $mwsmtp
- port $mwsport
- from $mwaddr
- user $mwlogin
- passwordeval \"pass $mwpass\"
- $starttlsoff
- "
- mbsync_profile="IMAPStore $mwacc-remote
- Host $mwimap
- Port $mwiport
- User $mwlogin
- PassCmd \"pass $mwpass\"
- SSLType $mwssltype
- CertificateFile $sslcert
-
- MaildirStore $mwacc-local
- Subfolders Verbatim
- Path $mwaccmaildir/
- Inbox $mwaccmaildir/INBOX
- Flatten .
-
- Channel $mwacc
- Expunge Both
- Master :$mwacc-remote:
- Slave :$mwacc-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 $mwaddr
- set realname = \"$mwname\"
- set from = \"$mwaddr\"
- set sendmail = \"$msmtpbin -a $mwacc\"
- alias me $mwname <$mwaddr>
- set folder = \"$mwaccmaildir\"
- set mbox_type = Maildir
-
- macro index gm \"<shell-escape>mailsync $mwacc<enter>\" \"sync mail $mwaddr\"
-
- unmailboxes *
- "
- else
- mutt_profile="# vim: filetype=neomuttrc
- # muttrc file for account $mwaddr
- set realname = \"$mwname\"
- set from = \"$mwaddr\"
- set sendmail = \"$msmtpbin -a $mwacc\"
- alias me $mwname <$mwaddr>
- set folder = \"imaps://$mwaddr@$mwimap:$mwiport\"
- set header_cache = \"$mwacccachedir\"
- set message_cachedir = \$header_cache
- set imap_user = \"$mwlogin\"
- set imap_pass = \"\`pass $mwpass\`\"
- account-hook \$folder 'set imap_user=\"$mwlogin\" 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
- mwdomain="$(echo "$mwaddr" | sed "s/.*@//")"
- printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$mwdomain"
- mwserverinfo="$(grep "^$mwdomain" "$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" "$mwdomain" "$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" "$mwimap" "$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
- takemwaddr
- 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 the user has a pass entry he could provide it via mwpass
- if [ -z "$mwpass" ]; then
- mwpass=mutt-wizard-$mwaddr
- getpass
- fi
- getprofiles
- mkdir -p "$mwmuttdir" "$mwaccrcdir" "$mwconfigdir/msmtp" "${mwmbsyncrc%/*}"
- [ ! -f "$mwmsmtprc" ] && echo "$msmtp_header" > "$mwmsmtprc"
- echo "$msmtp_profile" >> "$mwmsmtprc"
- case "$mwservice" in
- protonmail.ch|protonmail.com|pm.me) protonfinger || return 1 ;;
- esac
- echo "$mbsync_profile" >> "$mwmbsyncrc"
- # new idnum = first one missing
- getaccounts
- for x in $(seq 1 9); do echo "$accounts" | grep "$x": >/dev/null 2>&1 || { export idnum="$x"; break ;}; done
- mwaccrc="$mwaccrcdir/$idnum-$mwacc.muttrc"
- echo "$mutt_profile" > "$mwaccrc"
- [ ! -f "$mwmuttrc" ] && echo "# vim: filetype=neomuttrc" > "$mwmuttrc" && echo "muttrc created."
- ! grep "source.*mutt-wizard.muttrc" "$mwmuttrc" >/dev/null && echo "source $mwsharerc # mw-autogenerated" >> "$mwmuttrc"
- if [ "$mwtype" = "offline" ]; then
- ! grep "^macro .* gM .*" "$mwmuttrc" >/dev/null && echo "macro index gM '<shell-escape>mailsync -Va<enter>' \"sync all mail\" # mw-autogenerated" >> "$mwmuttrc"
- fi
- ! grep "^source.*$mwaccrc" "$mwmuttrc" >/dev/null && echo "source $mwaccrc # 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 $mwacc/&\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"; } >> "$mwaccrc"
- done
- }
-
- tryconnect() {
- if [ -z "$mailboxes" ]; then
- if [ ! -d "$mwaccmaildir" ]; then
- mwaccmaildirWasThere="NO" # we need to remove again for "online"
- mkdir -p "$mwaccmaildir"
- fi
- mailboxes="$($mbsyncbin -l $mwacc | sed 's/\//./')" >/dev/null 2>&1
- fi
- if [ -n "$mailboxes" ]; then
- printf "\033[32mMailboxes detected.\033[0m\\n"
- echo "$mailboxes" | xargs -I {} mkdir -p "$mwaccmaildir/{}"
- 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() {
- sed -i "/# mw-autogenerated/d" "$mwaccrc"
- sed -i "/^mailboxes\|^set record\|^set postponed\|^set trash\|^set spoolfile/d" "$mwaccrc"
- idnum=${mwaccrc%%-*}
- idnum=${idnum##*/}
- muttsync=$(printf '<sync-mailbox><enter-command>source %s<enter><change-folder>!<enter>;<check-stats>' $mwaccrc)
- echo "macro index,pager i$idnum '$muttsync' \"switch to $mwaddr\" # mw-autogenerated" >> "$mwaccrc"
- command -V urlview >/dev/null 2>&1 && [ ! -f "$HOME/.urlview" ] && echo "COMMAND \$BROWSER" > "$HOME/.urlview"
-
- echo "folder-hook \$folder '$muttsync' # mw-autogenerated" >> "$mwaccrc"
- boxes="$(find "$mwaccmaildir/" -mindepth 1 -maxdepth 1 | sed "s/\ /\\\ /g;s/^.*\//=/")"
- if [ "$boxes" = "" ]; then
- 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" "$mwacc"
- return
- fi
- 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')
- cat >> "$mwaccrc" <<EOF
- set spoolfile = "$spoolfile"
- set record = "$record"
- set postponed = "$postponed"
- set trash = "$trash"
- EOF
- echo "mailboxes =$mwaccmutt ===================== $(echo "$boxes" | sed -e "s/^\|$/\"/g" | tr "\n" " ")" >> "$mwaccrc"
- printf "Setting up your keyboard shortcuts for jumping between mailboxes...\\n"
- 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
- if [ "$mwtype" = "offline" ]; then
- notmuchauto
- printf "All done.\\n\033[33mYou can now run \`\033[32mmailsync [%s]\033[33m\` to sync your mail.\033[0m\\n" "$mwacc"
- else
- mkdir -p "$mwacccachedir"
- sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
- [ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir/"
- fi
- 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
- mwaddr="$(echo "$accounts" | grep "$input": | awk '{print $2}')"
- takemwaddr
- [ -z "$mwacc" ] && printf "Invalid response." && return 1
- return 0 ;
- }
-
- mwdelete() {
- sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
- rm -rf "$mwacccachedir"
- rm -rf "$mwaccrcdir/"[1-9]"-$mwacc.muttrc"
- sed -i "/[0-9]-$mwacc.muttrc/d" "$mwmuttrc"
- sed -i "/account $mwacc/,/^\(\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" "$mwaccrcdir" "$mwconfigdir/msmtp" "${mwmbsyncrc%/*}" "$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 \`$mwacc\` 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
|