|
|
@@ -2,13 +2,13 @@
|
|
|
#
|
|
|
# by Siddharth Dushantha 2020
|
|
|
#
|
|
|
-# Dependencies: jq, curl, w3m
|
|
|
+# Dependencies: jq, curl, w3m, awk
|
|
|
#
|
|
|
|
|
|
+export LC_ALL=C
|
|
|
export LC_CTYPE=C
|
|
|
-export LANG=C
|
|
|
|
|
|
-VERSION=1.0.1
|
|
|
+VERSION=1.0.5
|
|
|
|
|
|
# By default 'tmpmail' uses 'w3m' as it's web browser to render
|
|
|
# the HTML of the email
|
|
|
@@ -21,36 +21,43 @@ RAW_TEXT=false
|
|
|
# Everything related to 'tmpmail' will be stored in /tmp/tmpmail
|
|
|
# so that the old emails and email addresses get cleared after
|
|
|
# restarting the computer
|
|
|
-TMPMAIL_DIR="/tmp/tmpmail/"
|
|
|
+TMPMAIL_DIR="/tmp/tmpmail"
|
|
|
|
|
|
# TMPMAIL_EMAIL_ADDRESS is where we store the temporary email address
|
|
|
# that gets generated. This prevents the user from providing
|
|
|
# the email address everytime they run tmpmail
|
|
|
TMPMAIL_EMAIL_ADDRESS="$TMPMAIL_DIR/email_address"
|
|
|
-TMPMAIL_HTML_EMAIL="$TMPMAIL_DIR/tmpmail.html"
|
|
|
|
|
|
+# tmpmail.html is where the email gets stored.
|
|
|
+# Even though the file ends with a .html extension, the raw text version of
|
|
|
+# the email will also be stored in this file so that w3m and other browsers
|
|
|
+# are able to open this file
|
|
|
+TMPMAIL_HTML_EMAIL="$TMPMAIL_DIR/tmpmail.html"
|
|
|
|
|
|
-usage(){
|
|
|
+usage() {
|
|
|
# Using 'cat << EOF' we can easily output a multiline text. This is much
|
|
|
# better than using 'echo' for each line or using '\n' to create a new line.
|
|
|
- cat << EOF
|
|
|
-usage: tmpmail [-h] [--generate] CUSTOM [--browser BROWSER] [--recent] ID
|
|
|
+ cat <<EOF
|
|
|
+usage: tmpmail [-h] [--generate] [--browser BROWSER] [--recent] ID
|
|
|
|
|
|
optional arguments:
|
|
|
-h, --help Show this help message
|
|
|
--version Print version
|
|
|
--g, --generate Generate a new email address
|
|
|
+-g, --generate Generate a new email address. You may aslo pass a custom username along with this flag
|
|
|
-r, --recent View the most recent email
|
|
|
-t, --text View the email as raw text, where all the HTML tags are removed
|
|
|
-b, --browser Change the browser that is used to render the HTML of the email (default: w3m)
|
|
|
EOF
|
|
|
}
|
|
|
|
|
|
+has() {
|
|
|
+ # Check if the user 'has' a command installed
|
|
|
+ command -v "$1" >/dev/null 2>&1
|
|
|
+}
|
|
|
|
|
|
-generate_email_address(){
|
|
|
+generate_email_address() {
|
|
|
# There are 2 ways which this function is called in this script.
|
|
|
- # [1] The user wants to generate a new email and runs 'tmpmail --generate $OPTIONAL'
|
|
|
- # with or without the `$OPTIONAL` command.
|
|
|
+ # [1] The user wants to generate a new email and runs 'tmpmail --generate'
|
|
|
# [2] The user runs 'tmpmail' to check the inbox , but /tmp/tmpmail/email_address
|
|
|
# is empty or nonexistant. Therefore a new email gets automatically
|
|
|
# generated before showing the inbox. But of course the inbox will
|
|
|
@@ -66,42 +73,36 @@ generate_email_address(){
|
|
|
EXTERNALLY=${1:-false}
|
|
|
CUSTOM=${2:-false}
|
|
|
|
|
|
- # Generate an email address.
|
|
|
- #
|
|
|
+ # Generate a random email address.
|
|
|
# This function is called whenever the user wants to generate a new email
|
|
|
- # address by running 'tmpmail --generate $OPTIONAL' or when the user runs 'tmpmail'
|
|
|
+ # address by running 'tmpmail --generate' or when the user runs 'tmpmail'
|
|
|
# but /tmp/tmpmail/email_address is empty or nonexistent.
|
|
|
#
|
|
|
- # If a user does not pass $OPTIONAL, we create a random username by taking the first
|
|
|
- # 10 lines from /dev/random and delete all the characters which are *not* lower case
|
|
|
- # letters from A to Z. So charcters such as dashes, periods, underscore, and numbers are
|
|
|
- # all deleted, giving us a text which only contains lower case letters form A to Z. We
|
|
|
- # then take the first 10 characters, which will be the username of the email address
|
|
|
+ # We create a random username by taking the first 10 lines from /dev/random
|
|
|
+ # and delete all the characters which are *not* lower case letters from A to Z.
|
|
|
+ # So charcters such as dashes, periods, underscore, and numbers are all deleted,
|
|
|
+ # giving us a text which only contains lower case letters form A to Z. We then take
|
|
|
+ # the first 10 characters, which will be the username of the email address
|
|
|
USERNAME=$(head /dev/urandom | tr -dc a-z | cut -c1-11)
|
|
|
+
|
|
|
[ "$CUSTOM" != false ] && USERNAME=$CUSTOM
|
|
|
|
|
|
# This is an array of the valid TLDS which 1secmail provides.
|
|
|
TLDS=(com net org)
|
|
|
|
|
|
# Randomly pick one of the TLDS mentiond above.
|
|
|
- # This is done by first echoing all the TLDS into 'tr' which then
|
|
|
- # replaces the white spaces with a new line. This is done because we use
|
|
|
- # 'sort' to put the TLDS in a random order, but 'sort' requires the TLDS to
|
|
|
- # be on seperate lines. After the randomizing is done we take the first line
|
|
|
- # which is one of the TLDS
|
|
|
- TLD=$(echo "${TLDS[@]}" | tr " " "\n" | sort -R | head -n 1)
|
|
|
+ TLD=${TLDS[$RANDOM % ${#TLDS[@]}]}
|
|
|
|
|
|
# Save the generated email address to the $TMPMAIL_EMAIL_ADDRESS file
|
|
|
# so that it can be whenever 'tmpmail' is run
|
|
|
- echo "$USERNAME@1secmail.$TLD" > "$TMPMAIL_EMAIL_ADDRESS"
|
|
|
+ echo "$USERNAME@1secmail.$TLD" >"$TMPMAIL_EMAIL_ADDRESS"
|
|
|
|
|
|
# If this function was called because the user wanted to generate a new
|
|
|
# email address, show them the email address
|
|
|
[ "$EXTERNALLY" = true ] && cat "$TMPMAIL_EMAIL_ADDRESS"
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-get_email_address(){
|
|
|
+get_email_address() {
|
|
|
# This function is only called once and that is when this script
|
|
|
# get executed. The output of this function gets stored in $EMAIL_ADDRESS
|
|
|
#
|
|
|
@@ -113,16 +114,15 @@ get_email_address(){
|
|
|
head -n 1 "$TMPMAIL_EMAIL_ADDRESS"
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-list_emails(){
|
|
|
+list_emails() {
|
|
|
# List all the received emails in a nicely formatted order
|
|
|
#
|
|
|
# Fetch the email data using 1secmail's API
|
|
|
- DATA=$(curl -skL "https://1secmail.$TLD/api/v1/?action=getMessages&login=$USERNAME&domain=1secmail.$TLD")
|
|
|
+ DATA=$(curl -sL "https://1secmail.com/api/v1/?action=getMessages&login=$USERNAME&domain=1secmail.$TLD")
|
|
|
|
|
|
# Using 'jq' we get the length of the JSON data. From this we can determine whether or not
|
|
|
# the email address has gotten any emails
|
|
|
- DATA_LENGTH=$(jq length <<< "$DATA")
|
|
|
+ DATA_LENGTH=$(jq length <<<"$DATA")
|
|
|
|
|
|
# We are showing what email address is currently being used
|
|
|
# in case the user has forgotten what the email address was.
|
|
|
@@ -134,7 +134,7 @@ list_emails(){
|
|
|
|
|
|
# This is where we store all of our emails, which is then
|
|
|
# displayed using 'column'
|
|
|
- INBOX=""
|
|
|
+ INBOX=()
|
|
|
|
|
|
# This for loop goes through each mail that have been received.
|
|
|
#
|
|
|
@@ -165,39 +165,33 @@ list_emails(){
|
|
|
#
|
|
|
# We can then put those results into the foor loop
|
|
|
for index in $(seq 1 "$DATA_LENGTH"); do
|
|
|
- # Since arrays in JSON data start at 0, we must subtract
|
|
|
- # the value of $index by 1 so that we dont miss one of the
|
|
|
- # emails in the array
|
|
|
- MAIL_DATA=$(jq -r ".[$index-1]" <<< "$DATA")
|
|
|
-
|
|
|
- ID=$(jq -r ".id" <<< "$MAIL_DATA")
|
|
|
- FROM=$(jq -r ".from" <<< "$MAIL_DATA")
|
|
|
- SUBJECT=$(jq -r ".subject" <<< "$MAIL_DATA")
|
|
|
-
|
|
|
- # The '||' are used as a divideder for 'column'. 'column' will use this divider as
|
|
|
- # a point of reference to create the division. By default 'column' uses a blank space
|
|
|
- # but that would not work in our case as the email subject could have multiple white spaces
|
|
|
- # and 'column' would split the words that are seperated by white space, in different columns.
|
|
|
- #
|
|
|
- # Yes, there a double quote all by it self on the line under this one.
|
|
|
- # This serves as a new line. So that the 'column' command works properly.
|
|
|
- # I know I could have used '\n' but 'column' does not intepret it as a new line.
|
|
|
- INBOX+="$ID ||$FROM ||$SUBJECT
|
|
|
-"
|
|
|
+ # Since arrays in JSON data start at 0, we must subtract
|
|
|
+ # the value of $index by 1 so that we dont miss one of the
|
|
|
+ # emails in the array
|
|
|
+ MAIL_DATA=$(jq -r ".[$index-1]" <<<"$DATA")
|
|
|
+
|
|
|
+ ID=$(jq -r ".id" <<<"$MAIL_DATA")
|
|
|
+ FROM=$(jq -r ".from" <<<"$MAIL_DATA")
|
|
|
+ SUBJECT=$(jq -r ".subject" <<<"$MAIL_DATA")
|
|
|
+
|
|
|
+ # The '||' are used as a divideder for 'column'. 'column' will use this divider as
|
|
|
+ # a point of reference to create the division. By default 'column' uses a blank space
|
|
|
+ # but that would not work in our case as the email subject could have multiple white spaces
|
|
|
+ # and 'column' would split the words that are seperated by white space, in different columns.
|
|
|
+ INBOX+=("$ID ||$FROM ||$SUBJECT")
|
|
|
done
|
|
|
|
|
|
# Show the emails cleanly
|
|
|
- column -t -s "||" <<< "$INBOX"
|
|
|
+ column -t -s "||" < <(printf '%s\n' "${INBOX[@]}")
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-view_email(){
|
|
|
+view_email() {
|
|
|
# View an email by providing it's ID
|
|
|
#
|
|
|
# The first argument provided to this function will be the ID of the email
|
|
|
# that has been received
|
|
|
EMAIL_ID="$1"
|
|
|
- DATA=$(curl -skL "https://www.1secmail.$TLD/api/v1/?action=readMessage&login=$USERNAME&domain=1secmail.$TLD&id=$EMAIL_ID")
|
|
|
+ DATA=$(curl -sL "https://www.1secmail.com/api/v1/?action=readMessage&login=$USERNAME&domain=1secmail.$TLD&id=$EMAIL_ID")
|
|
|
|
|
|
# After the data is retrieved using the API, we have to check if we got any emails.
|
|
|
# Luckly 1secmail's API is not complicated and returns 'Message not found' as plain text
|
|
|
@@ -206,21 +200,25 @@ view_email(){
|
|
|
[[ "$DATA" == "Message not found" ]] && echo "Message not found" && exit 1
|
|
|
|
|
|
# We pass the $DATA to 'jq' which extracts the values
|
|
|
- FROM=$(jq -r ".from" <<< "$DATA")
|
|
|
- SUBJECT=$(jq -r ".subject" <<< "$DATA")
|
|
|
- HTML_BODY=$(jq -r ".htmlBody" <<< "$DATA")
|
|
|
+ FROM=$(jq -r ".from" <<<"$DATA")
|
|
|
+ SUBJECT=$(jq -r ".subject" <<<"$DATA")
|
|
|
+ HTML_BODY=$(jq -r ".htmlBody" <<<"$DATA")
|
|
|
+
|
|
|
+ # If you get an email that is in pure text, the .htmlBody field will be empty and
|
|
|
+ # we will need to get the content from .textBody instead
|
|
|
+ [ -z "$HTML_BODY" ] && HTML_BODY="<pre>$(jq -r ".textBody" <<<"$DATA")</pre>"
|
|
|
|
|
|
# Create the HTML with all the information that is relevant and then
|
|
|
# assigning that HTML to the variable HTML_MAIL. This is the best method
|
|
|
# to create a multiline variable
|
|
|
- read -r -d '' HTML_MAIL << EOF
|
|
|
+ read -r -d '' HTML_MAIL <<EOF
|
|
|
<pre><b>To: </b>$EMAIL_ADDRESS
|
|
|
<b>From: </b>$FROM
|
|
|
<b>Subject: </b>$SUBJECT</pre>
|
|
|
$HTML_BODY
|
|
|
EOF
|
|
|
# Save the $HTML_MAIL into $TMPMAIL_HTML_EMAIL
|
|
|
- echo "$HTML_MAIL" > "$TMPMAIL_HTML_EMAIL"
|
|
|
+ echo "$HTML_MAIL" >"$TMPMAIL_HTML_EMAIL"
|
|
|
|
|
|
# If the '--text' flag is used, then use 'w3m' to convert the HTML of
|
|
|
# the email to pure text by removing all the HTML tags
|
|
|
@@ -232,8 +230,7 @@ EOF
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-view_recent_email(){
|
|
|
+view_recent_email() {
|
|
|
# View the most recent email.
|
|
|
#
|
|
|
# This is done by listing all the received email like you
|
|
|
@@ -244,15 +241,14 @@ view_recent_email(){
|
|
|
view_email "$MAIL_ID"
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-main(){
|
|
|
+main() {
|
|
|
# Iterate of the array of dependencies and check if the user has them installed
|
|
|
dependencies=(jq w3m curl awk)
|
|
|
for dependency in "${dependencies[@]}"; do
|
|
|
- type -p "$dependency" &>/dev/null || {
|
|
|
- echo "error: Could not find '${dependency}', is it installed?" >&2
|
|
|
- exit 1
|
|
|
- }
|
|
|
+ if ! has "$dependency"; then
|
|
|
+ echo "error: Could not find '${dependency}', is it installed?" >&2
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
done
|
|
|
|
|
|
# Create the $TMPMAIL_DIR directory and dont throw any errors
|
|
|
@@ -277,21 +273,22 @@ main(){
|
|
|
|
|
|
while [[ "$1" ]]; do
|
|
|
case "$1" in
|
|
|
- --help|-h) usage && exit ;;
|
|
|
- --generate|-g) generate_email_address true $2 && exit;;
|
|
|
- --browser|-b) BROWSER="$2" ;;
|
|
|
- --text|-t) RAW_TEXT=true ;;
|
|
|
- --version) echo "$VERSION" && exit;;
|
|
|
- --recent|-r) view_recent_email && exit;;
|
|
|
- # If the user provides number as an argument,
|
|
|
- # assume its the ID of an email and try getting
|
|
|
- # the email that belongs to the ID
|
|
|
- *[0-9]*) view_email "$1" && exit;;
|
|
|
- -*) echo "error: option $1 does not exist"
|
|
|
+ --help | -h) usage && exit ;;
|
|
|
+ --generate | -g) generate_email_address true "$2" && exit ;;
|
|
|
+ --browser | -b) BROWSER="$2" ;;
|
|
|
+ --text | -t) RAW_TEXT=true ;;
|
|
|
+ --version) echo "$VERSION" && exit ;;
|
|
|
+ --recent | -r) view_recent_email && exit ;;
|
|
|
+ *[0-9]*)
|
|
|
+ # If the user provides number as an argument,
|
|
|
+ # assume its the ID of an email and try getting
|
|
|
+ # the email that belongs to the ID
|
|
|
+ view_email "$1" && exit
|
|
|
+ ;;
|
|
|
+ -*) echo "error: option $1 does not exist" ;;
|
|
|
esac
|
|
|
shift
|
|
|
done
|
|
|
}
|
|
|
|
|
|
-
|
|
|
main "$@"
|