From 2a3a30dc720c49a5c3d148f8e5ff075622a468d9 Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Wed, 10 Feb 2021 16:49:30 -0500 Subject: [PATCH] [i3][rofi] Update rofi to be more useful Enter should call up hosts, not a blank terminal. And rofi can use pass for input! --- i3/.config/i3/config | 13 +- rofi/.config/rofi/config.rasi | 2 +- rofi/.config/rofi/rofi-pass.sh | 880 ++++++++++++++++++++++++++++++++ rofi/.config/rofi/web-search.sh | 1 + 4 files changed, 890 insertions(+), 6 deletions(-) create mode 100755 rofi/.config/rofi/rofi-pass.sh diff --git a/i3/.config/i3/config b/i3/.config/i3/config index 2fca4fd..6970bdd 100644 --- a/i3/.config/i3/config +++ b/i3/.config/i3/config @@ -64,7 +64,8 @@ bar { #bindsym $mod+shift+m exec --no-startup-id surf https://15five-dev.atlassian.net/secure/Dashboard.jspa # SCRATCHPAD -bindsym $mod+Return exec $term +bindsym $mod+Return exec rofi -show ssh +bindsym $mod+Shift+Return exec $term bindsym $mod+BackSpace exec $term --working-directory ~/src/ff/fifteen5/ #bindsym $mod+Shift+BackSpace floating enable, move position 48 px 48 px, move scratchpad #bindsym $mod+Ctrl+BackSpace exec $term -e tmux new-session -A -s scratch @@ -266,6 +267,12 @@ bindsym XF86Search exec ~/.config/i3/bright.sh 1 # decrease screen brightness # ROFI bindsym $mod+space exec rofi -show combi -display-window "W" +bindsym $mod+P exec --no-startup-id ~/.config/rofi/rofi-pass.sh +bindsym $mod+Shift+p exec --no-startup-id ~/.config/rofi/rofi-otp.sh +bindsym $mod+o exec --no-startup-id ~/.config/rofi/www.sh +bindsym $mod+Shift+o exec ~/.config/rofi/web-search.sh +bindsym $mod+Shift+b exec ~/.config/rofi/books-search.sh +bindsym $mod+Shift+s exec ~/.config/rofi/slack.sh # Lock with bindsym $mod+Shift+F12 exec --no-startup-id i3lock -i ~/var/media/backgrounds/astrobin/`ls -Ar ~/var/media/backgrounds/astrobin/ | tail -n 1` -t @@ -276,10 +283,6 @@ exec hsetroot -cover ~/var/media/backgrounds/bing/`ls -A ~/var/media/backgrounds ##### APP BINDS ################################### bindsym $mod+n exec $browser -bindsym $mod+o exec --no-startup-id ~/.config/rofi/www.sh -bindsym $mod+Shift+o exec ~/.config/rofi/web-search.sh -bindsym $mod+Shift+b exec ~/.config/rofi/books-search.sh -bindsym $mod+Shift+s exec ~/.config/rofi/slack.sh bindsym $mod+Shift+c exec org-capture bindsym $mod+Shift+y exec xfreerdp /u:powellc /p:mainroot /v:telesto.local /w:1200 /h:700 diff --git a/rofi/.config/rofi/config.rasi b/rofi/.config/rofi/config.rasi index 50d5dc4..cfefb04 100644 --- a/rofi/.config/rofi/config.rasi +++ b/rofi/.config/rofi/config.rasi @@ -5,6 +5,6 @@ configuration { terminal: "alacritty"; font: "Inconsolata 10"; show-icons: true; - combi-modi: "ssh,window,drun"; + combi-modi: "window,drun,ssh"; } @import "/usr/share/rofi/themes/gruvbox-dark-hard.rasi" diff --git a/rofi/.config/rofi/rofi-pass.sh b/rofi/.config/rofi/rofi-pass.sh new file mode 100755 index 0000000..22667e2 --- /dev/null +++ b/rofi/.config/rofi/rofi-pass.sh @@ -0,0 +1,880 @@ +#!/usr/bin/env bash + +# rofi-pass +# (c) 2015 Rasmus Steinke +basecommand="$0" + +# set default settings +_rofi () { + rofi -no-auto-select -i "$@" +} + +_pwgen () { + pwgen -y "$@" +} + +_image_viewer () { + feh - +} + +config_dir=${XDG_CONFIG_HOME:-$HOME/.config} +cache_dir=${XDG_CACHE_HOME:-$HOME/.cache} + +# We expect to find these fields in pass(1)'s output +URL_field='url' +USERNAME_field='user' +AUTOTYPE_field='autotype' +OTPmethod_field='otp_method' + +default_autotype="user :tab pass" +delay=2 +wait=0.2 +xdotool_delay=12 +default_do='menu' # menu, copyPass, typeUser, typePass, copyUser, copyUrl, viewEntry, typeMenu, actionMenu, copyMenu, openUrl +auto_enter='false' +notify='false' +help_color="" +clip=primary +clip_clear=45 +default_user="${ROFI_PASS_DEFAULT_USER-$(whoami)}" +default_user2=john_doe +password_length=12 +fix_layout=false + +# default shortcuts +autotype="Alt+1" +type_user="Alt+2" +type_pass="Alt+3" +open_url="Alt+4" +copy_name="Alt+u" +copy_url="Alt+l" +copy_pass="Alt+p" +show="Alt+o" +copy_menu="Alt+c" +action_menu="Alt+a" +type_menu="Alt+t" +help="Alt+h" +switch="Alt+x" +insert_pass="Alt+n" +qrcode="Alt+q" +previous_root="Shift+Left" +next_root="Shift+Right" + +# Safe permissions +umask 077 + +has_qrencode() { + command -v qrencode >/dev/null 2>&1 +} + +listgpg () { + mapfile -d '' pw_list < <(find -L . -name '*.gpg' -print0) + pw_list=("${pw_list[@]#./}") + printf '%s\n' "${pw_list[@]}" | sort -n +} + +# get all password files and output as newline-delimited text +list_passwords() { + cd "${root}" || exit + mapfile -t pw_list < <(listgpg) + printf '%s\n' "${pw_list[@]%.gpg}" | sort -n +} + +doClip () { + case "$clip" in + "primary") xclip ;; + "clipboard") xclip -selection clipboard;; + "both") xclip; xclip -o | xclip -selection clipboard;; + esac +} + +checkIfPass () { + printf '%s\n' "${root}: $selected_password" >| "$cache_dir/rofi-pass/last_used" +} + + +autopass () { + x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}') + xset r off + + rm -f "$cache_dir/rofi-pass/last_used" + printf '%s\n' "${root}: $selected_password" > "$cache_dir/rofi-pass/last_used" + for word in ${stuff["$AUTOTYPE_field"]}; do + case "$word" in + ":tab") xdotool key Tab;; + ":space") xdotool key space;; + ":delay") sleep "${delay}";; + ":enter") xdotool key Return;; + ":otp") printf '%s' "$(generateOTP)" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -;; + "pass") printf '%s' "${password}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -;; + "path") printf '%s' "${selected_password}" | rev | cut -d'/' -f1 | rev | xdotool type --clearmodifiers --file -;; + *) printf '%s' "${stuff[${word}]}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file -;; + esac + done + + if [[ ${auto_enter} == "true" ]]; then + xdotool key Return + fi + + xset r "$x_repeat_enabled" + unset x_repeat_enabled + clearUp +} + +generateQrCode() { + has_qrencode + + if [[ $? -eq "1" ]]; then + printf '%s\n' "qrencode not found" | _rofi -dmenu + exit_code=$? + if [[ $exit_code -eq "1" ]]; then + exit + else + "${basecommand}" + fi + fi + + checkIfPass + pass "$selected_password" | head -n 1 | qrencode -d 300 -v 8 -l H -o - | _image_viewer + if [[ $? -eq "1" ]]; then + printf '%s\n' "" | _rofi -dmenu -mesg "Image viewer not defined or cannot read from pipe" + exit_value=$? + if [[ $exit_value -eq "1" ]]; then + exit + else + "${basecommand}" + fi + fi + clearUp +} + +openURL () { + checkIfPass + $BROWSER "$(PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep "${URL_field}: " | gawk '{sub(/:/,"")}{print $2}1' | head -1)"; exit; + clearUp +} + +typeUser () { + checkIfPass + + x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}') + xset r off + + printf '%s' "${stuff[${USERNAME_field}]}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file - + + xset r "$x_repeat_enabled" + unset x_repeat_enabled + + clearUp +} + +typePass () { + checkIfPass + + x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}') + xset r off + + printf '%s' "${password}" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file - + + if [[ $notify == "true" ]]; then + if [[ "${stuff[notify]}" == "false" ]]; then + : + else + notify-send "rofi-pass" "finished typing password"; + fi + elif [[ $notify == "false" ]]; then + if [[ "${stuff[notify]}" == "true" ]]; then + notify-send "rofi-pass" "finished typing password"; + else + : + fi + fi + + xset r "$x_repeat_enabled" + unset x_repeat_enabled + clearUp +} + +typeField () { + checkIfPass + local to_type + + x_repeat_enabled=$(xset q | awk '/auto repeat:/ {print $3}') + xset r off + + case $typefield in + "OTP") to_type="$(generateOTP)" ;; + *) to_type="${stuff[${typefield}]}" ;; + esac + + printf '%s' "$to_type" | xdotool type --delay ${xdotool_delay} --clearmodifiers --file - + + xset r "$x_repeat_enabled" + unset x_repeat_enabled + unset to_type + + clearUp +} + +generateOTP () { + checkIfPass + + # First, we check if there is a non-conventional OTP command in the pass file + if PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep -q "${OTPmethod_field}: "; then + # We execute the commands after otp_method: AS-IS + bash -c "$(PASSWORD_STORE_DIR="${root}" pass "$selected_password" | grep "${OTPmethod_field}: " | cut -d' ' -f2-)" + else + # If there is no method defined, fallback to pass-otp + PASSWORD_STORE_DIR="${root}" pass otp "$selected_password" + fi + + clearUp +} + +copyUser () { + checkIfPass + printf '%s' "${stuff[${USERNAME_field}]}" | doClip + clearUp +} + +copyField () { + checkIfPass + printf '%s' "${stuff[${copyfield}]}" | doClip + clearUp +} + +copyURL () { + checkIfPass + printf '%s' "${stuff[${URL_field}]}" | doClip + clearUp +} + +copyPass () { + checkIfPass + printf '%s' "$password" | doClip + if [[ $notify == "true" ]]; then + notify-send "rofi-pass" "Copied Password\\nClearing in $clip_clear seconds" + fi + + if [[ $notify == "true" ]]; then + (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard | notify-send "rofi-pass" "Clipboard cleared") & + elif [[ $notify == "false" ]]; then + (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard) & + fi +} + +viewEntry () { + checkIfPass + showEntry "${selected_password}" +} + +generatePass () { + askmenu_content=( + "Yes" + "No" + ) + + askGenMenu=$(printf '%s\n' "${askmenu_content[@]}" | _rofi -dmenu -p "Generate new Password for ${selected_password}? > ") + askgen_exit=$? + + if [[ $askgen_exit -eq 1 ]]; then + exit + fi + if [[ $askGenMenu == "Yes" ]]; then + true + elif [[ $askGenMenu == "No" ]]; then + actionMenu + fi + + checkIfPass + + symbols_content=( + "0 Cancel" + "1 Yes" + "2 No" + ) + + symbols=$(printf '%s\n' "${symbols_content[@]}" | _rofi -dmenu -p "Use Symbols? > ") + symbols_val=$? + + if [[ $symbols_val -eq 1 ]]; then + exit + fi + if [[ $symbols == "0 Cancel" ]]; then + mainMenu; + elif [[ $symbols == "1 Yes" ]]; then + symbols=""; + elif [[ $symbols == "2 No" ]]; then + symbols="-n"; + fi + + HELP="Enter Number or hit Enter to use default length" + length=$(printf '%s' "" | _rofi -dmenu -mesg "${HELP}" -p "Password length? (Default: ${password_length}) > ") + length_exit=$? + + if [[ $length_exit -eq 1 ]]; then + exit + fi + if [[ $length == "" ]]; then + PASSWORD_STORE_DIR="${root}" pass generate ${symbols} -i "$selected_password" "${password_length}" > /dev/null; + else + PASSWORD_STORE_DIR="${root}" pass generate ${symbols} -i "$selected_password" "${length}" > /dev/null; + fi +} + +# main Menu +mainMenu () { + if [[ $1 == "--bmarks" ]]; then + selected_password="$(list_passwords 2>/dev/null \ + | _rofi -mesg "Bookmarks Mode. ${switch} to switch" \ + -dmenu \ + -kb-custom-10 "${switch}" \ + -select "$entry" \ + -p "rofi-pass > ")" + + rofi_exit=$? + + if [[ $rofi_exit -eq 1 ]]; then + exit + elif [[ $rofi_exit -eq 19 ]]; then + ${basecommand} + elif [[ $rofi_exit -eq 0 ]]; then + openURL + fi + else + unset selected_password + + args=( -dmenu + -kb-custom-1 "${autotype}" + -kb-custom-2 "${type_user}" + -kb-custom-3 "${type_pass}" + -kb-custom-4 "${open_url}" + -kb-custom-5 "${copy_name}" + -kb-custom-6 "${copy_pass}" + -kb-custom-7 "${show}" + -kb-custom-8 "${copy_url}" + -kb-custom-9 "${type_menu}" + -kb-custom-10 "${previous_root}" + -kb-custom-11 "${next_root}" + -kb-custom-14 "${action_menu}" + -kb-custom-15 "${copy_menu}" + -kb-custom-16 "${help}" + -kb-custom-17 "${switch}" + -kb-custom-18 "${insert_pass}" + -kb-custom-19 "${qrcode}" + ) + args+=( -kb-mode-previous "" # These keyboard shortcut options are needed, because + -kb-mode-next "" # Shift+ are otherwise taken by rofi. + -select "$entry" + -p "> " ) + + if [[ ${#roots[@]} -gt "1" || $custom_root == "true" ]]; then + args+=(-mesg "PW Store: ${root}") + fi + + selected_password="$(list_passwords 2>/dev/null | _rofi "${args[@]}")" + + rofi_exit=$? + if [[ $rofi_exit -eq 1 ]]; then + exit + fi + + # Actions based on exit code, which do not need the entry. + # The exit code for -kb-custom-X is X+9. + case "${rofi_exit}" in + 19) roots_index=$(( (roots_index-1+roots_length) % roots_length)); root=${roots[$roots_index]}; mainMenu; return;; + 20) roots_index=$(( (roots_index+1) % roots_length)); root=${roots[$roots_index]}; mainMenu; return;; + 25) helpMenu; return;; + 26) ${basecommand} --bmarks; return;; + esac + + mapfile -t password_temp < <(PASSWORD_STORE_DIR="${root}" pass show "$selected_password") + password=${password_temp[0]} + + if [[ ${password} == "#FILE="* ]]; then + pass_file="${password#*=}" + mapfile -t password_temp2 < <(PASSWORD_STORE_DIR="${root}" pass show "${pass_file}") + password=${password_temp2[0]} + fi + + fields=$(printf '%s\n' "${password_temp[@]:1}" | awk '$1 ~ /:$/ || /otpauth:\/\// {$1=$1;print}') + declare -A stuff + stuff["pass"]=${password} + + if [[ -n $fields ]]; then + while read -r LINE; do + unset _id _val + case "$LINE" in + "otpauth://"*|"${OTPmethod_field}"*) + _id="OTP" + _val="" + ;; + *) + _id="${LINE%%: *}" + _val="${LINE#* }" + ;; + esac + + if [[ -n "$_id" ]]; then + stuff["${_id}"]=${_val} + fi + done < <(printf '%s\n' "${fields}") + + if test "${stuff['autotype']+autotype}"; then + : + else + stuff["autotype"]="${USERNAME_field} :tab pass" + fi + fi + fi + + if [[ -z "${stuff["${AUTOTYPE_field}"]}" ]]; then + if [[ -n $default_autotype ]]; then + stuff["${AUTOTYPE_field}"]="${default_autotype}" + fi + fi + if [[ -z "${stuff["${USERNAME_field}"]}" ]]; then + if [[ -n $default_user ]]; then + if [[ "$default_user" == ":filename" ]]; then + stuff["${USERNAME_field}"]="$(basename "$selected_password")" + else + stuff["${USERNAME_field}"]="${default_user}" + fi + fi + fi + pass_content="$(for key in "${!stuff[@]}"; do printf '%s\n' "${key}: ${stuff[$key]}"; done)" + + # actions based on keypresses + # The exit code for -kb-custom-X is X+9. + case "${rofi_exit}" in + 0) typeMenu;; + 10) sleep $wait; autopass;; + 11) sleep $wait; typeUser;; + 12) sleep $wait; typePass;; + 13) openURL;; + 14) copyUser;; + 15) copyPass;; + 16) viewEntry;; + 17) copyURL;; + 18) default_do="menu" typeMenu;; + 23) actionMenu;; + 24) copyMenu;; + 27) insertPass;; + 28) generateQrCode;; + esac + clearUp +} + + +clearUp () { + password='' + selected_password='' + unset stuff + unset password + unset selected_password + unset password_temp + unset stuff +} + +helpMenu () { + _rofi -dmenu -mesg "Hint: All hotkeys are configurable in config file" -p "Help > " <<- EOM + ${autotype}: Autotype + ${type_user}: Type Username + ${type_pass}: Type Password + ${qrcode}: Generate and display qrcode + --- + ${copy_name}: Copy Username + ${copy_pass}: Copy Password + ${copy_url}: Copy URL + ${open_url}: Open URL + ${copy_menu}: Copy Custom Field + --- + ${action_menu}: Edit, Move, Delete, Re-generate Submenu + ${show}: Show Password File + ${insert_pass}: Insert new Pass Entry + ${switch}: Switch Pass/Bookmark Mode + --- + ${previous_root}: Switch to previous password store (--root) + ${next_root}: Switch to next password store (--root) +EOM +help_val=$? + +if [[ $help_val -eq 1 ]]; then + exit; +else + unset helptext; mainMenu; +fi +} + + +typeMenu () { + if [[ -n $default_do ]]; then + if [[ $default_do == "menu" ]]; then + checkIfPass + local -a keys=("${!stuff[@]}") + keys=("${keys[@]/$AUTOTYPE_field}") + typefield=$({ printf '%s' "${AUTOTYPE_field}" ; printf '%s\n' "${keys[@]}" | sort; } | _rofi -dmenu -p "Choose Field to type > ") + typefield_exit=$? + if [[ $typefield_exit -eq 1 ]]; then + exit + fi + case "$typefield" in + '') exit;; + 'pass') sleep $wait; typePass;; + "${AUTOTYPE_field}") sleep $wait; autopass;; + *) sleep $wait; typeField + esac + clearUp + elif [[ $default_do == "${AUTOTYPE_field}" ]]; then + sleep $wait; autopass + else + ${default_do} + fi + fi +} + +copyMenu () { + checkIfPass + copyfield=$(printf '%s\n' "${!stuff[@]}" | sort | _rofi -dmenu -p "Choose Field to copy > ") + val=$? + if [[ $val -eq 1 ]]; then + exit; + fi + if [[ $copyfield == "pass" ]]; then + copyPass; + else + copyField + fi + clearUp +} + +actionMenu () { + checkIfPass + action_content=("< Return" + "---" + "1 Move Password File" + "2 Copy Password File" + "3 Delete Password File" + "4 Edit Password File" + "5 Generate New Password" + ) + + action=$(printf '%s\n' "${action_content[@]}" | _rofi -dmenu -p "Choose Action > ") + if [[ ${action} == "1 Move Password File" ]]; then + manageEntry move; + elif [[ ${action} == "3 Delete Password File" ]]; then + manageEntry delete; + elif [[ ${action} == "2 Copy Password File" ]]; then + manageEntry copy; + elif [[ ${action} == "4 Edit Password File" ]]; then + manageEntry edit; + elif [[ ${action} == "5 Generate New Password" ]]; then + generatePass; + elif [[ ${action} == "< Return" ]]; then + mainMenu; + elif [[ ${action} == "" ]]; then + exit + fi +} + +showEntry () { + if [[ -z $pass_content ]]; then + pass_temp=$(PASSWORD_STORE_DIR="${root}" pass show "$selected_password") + password="${pass_temp%%$'\n'*}" + pass_key_value=$(printf '%s\n' "${pass_temp}" | tail -n+2 | grep ': ') + declare -A stuff + + while read -r LINE; do + _id="${LINE%%: *}" + _val="${LINE#* }" + stuff["${_id}"]=${_val} + done < <(printf '%s\n' "${pass_key_value}") + + stuff["pass"]=${password} + + if test "${stuff['autotype']+autotype}"; then + : + else + stuff["autotype"]="${USERNAME_field} :tab pass" + fi + + pass_content="$(for key in "${!stuff[@]}"; do printf '%s\n' "${key}: ${stuff[$key]}"; done)" + fi + + bla_content=("< Return" + "${pass_content}" + ) + + bla=$(printf '%s\n' "${bla_content[@]}" | _rofi -dmenu -mesg "Enter: Copy entry to clipboard" -p "> ") + rofi_exit=$? + + word=$(printf '%s' "$bla" | gawk -F': ' '{print $1}') + + if [[ ${rofi_exit} -eq 1 ]]; then + exit + elif [[ ${rofi_exit} -eq 0 ]]; then + if [[ ${bla} == "< Return" ]]; then + mainMenu + else + if [[ -z $(printf '%s' "${stuff[${word}]}") ]]; then + printf '%s' "$word" | doClip + else + printf '%s' "${stuff[${word}]}" | doClip + fi + if [[ $notify == "true" ]]; then + notify-send "rofi-pass" "Copied Password\\nClearing in $clip_clear seconds" + fi + if [[ $notify == "true" ]]; then + (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard | notify-send "rofi-pass" "Clipboard cleared") & + elif [[ $notify == "false" ]]; then + (sleep $clip_clear; printf '%s' "" | xclip; printf '%s' "" | xclip -selection clipboard) & + fi + exit + fi + fi + exit + unset stuff + unset password + unset selected_password + unset password_temp + unset stuff + exit +} + +manageEntry () { + if [[ "$1" == "edit" ]]; then + EDITOR=$EDITOR PASSWORD_STORE_DIR="${root}" pass edit "${selected_password}" + mainMenu + elif [[ $1 == "move" ]]; then + cd "${root}" || exit + group_array=(*/) + group=$(printf '%s\n' "${group_array[@]%/}" | _rofi -dmenu -p "Choose Group > ") + if [[ $group == "" ]]; then + exit + fi + PASSWORD_STORE_DIR="${root}" pass mv "$selected_password" "${group}" + mainMenu + elif [[ $1 == "copy" ]]; then + cd "${root}" || exit + group_array=(*/) + group=$(printf '%s\n' "${group_array[@]%/}" | _rofi -dmenu -p "Choose Group > ") + if [[ $group == "" ]]; then + exit + else + new_name="$(listgpg | _rofi -dmenu -format 'f' -mesg "Copying to same Group. Please enter a name for the new entry" -p "> ")" + fi + PASSWORD_STORE_DIR="${root}" pass cp "$selected_password" "${group}/${new_name}" + mainMenu + elif [[ "$1" == "delete" ]]; then + HELP="Selected entry: ${selected_password}" + ask_content=("Yes" + "No" + ) + ask=$(printf '%s\n' "${ask_content[@]}" | _rofi -mesg "${HELP}" -dmenu -p "Are You Sure? > ") + if [[ "$ask" == "Yes" ]]; then + PASSWORD_STORE_DIR="${root}" pass rm --force "${selected_password}" + elif [[ "$ask" == "No" ]]; then + mainMenu + elif [[ -z "$ask" ]]; then + exit + fi + else + mainMenu + fi +} + +insertPass () { + url=$(xclip --selection clipboard -o) + + if [[ "${url:0:4}" == "http" ]]; then + domain_name="$(printf '%s\n' "${url}" | awk -F / '{l=split($3,a,"."); print (a[l-1]=="com"?a[l-2] OFS:X) a[l-1] OFS a[l]}' OFS=".")" + help_content="Domain: ${domain_name} + Type name, make sure it is unique" + else + help_content="Hint: Copy URL to clipboard before calling this menu. + Type name, make sure it is unique" + fi + + cd "${root}" || exit + group_array=(*/) + grouplist=$(printf '%s\n' "${group_array[@]%/}") + name="$(listgpg | _rofi -dmenu -format 'f' -filter "${domain_name}" -mesg "${help_content}" -p "> ")" + val=$? + + if [[ $val -eq 1 ]]; then + exit + fi + + user_content=("${default_user2}" + "${USER}" + "${default_user}" + ) + + user=$(printf '%s\n' "${user_content[@]}" | _rofi -dmenu -mesg "Chose Username or type" -p "> ") + val=$? + + if [[ $val -eq 1 ]]; then + exit + fi + + group_content=("No Group" + "---" + "${grouplist}" + ) + + group=$(printf '%s\n' "${group_content[@]}" | _rofi -dmenu -p "Choose Group > ") + val=$? + + if [[ $val -eq 1 ]]; then + exit + fi + + pw=$(printf '%s' "Generate" | _rofi -dmenu -password -p "Password > " -mesg "Type Password or hit Enter to generate one") + + if [[ $pw == "Generate" ]]; then + pw=$(_pwgen "${password_length}") + fi + + clear + + if [[ "$group" == "No Group" ]]; then + if [[ $url == http* ]]; then + pass_content=("${pw}" + "---" + "${USERNAME_field}: ${user}" + "${URL_field}: ${url}" + ) + printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${name}" > /dev/null && PASSWORD_STORE_DIR="${root}" pass edit "${name}" + else + pass_content=("${pw}" + "---" + "${USERNAME_field}: ${user}" + ) + printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${name}" > /dev/null && PASSWORD_STORE_DIR="${root}" pass edit "${name}" + fi + else + if [[ $url == http* ]]; then + pass_content=("${pw}" + "---" + "${USERNAME_field}: ${user}" + "${URL_field}: ${url}" + ) + printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${group}/${name}" > /dev/null && PASSWORD_STORE_DIR="${root}" pass edit "${group}/${name}" + else + pass_content=("${pw}" + "---" + "${USERNAME_field}: ${user}" + ) + printf '%s\n' "${pass_content[@]}" | PASSWORD_STORE_DIR="${root}" pass insert -m "${group}/${name}" > /dev/null + if [[ $edit_new_pass == "true" ]]; then + PASSWORD_STORE_DIR="${root}" pass edit "${group}/${name}" + fi + fi + fi +} + +help_msg () { + cat <<'EOF' + Usage: + rofi-pass [command] + + Commands: + --insert insert new entry to password store + --root set custom root directories (colon separated) + --last-used highlight last used item + --show-last show details of last used Entry + --bmarks start in bookmarks mode + + rofi-pass version 1.5.3 +EOF +} + +get_config_file () { + configs=("$ROFI_PASS_CONFIG" + "$config_dir/rofi-pass/config" + "/etc/rofi-pass.conf") + + # return the first config file with a valid path + for config in "${configs[@]}"; do + # '-n' is needed in case ROFI_PASS_CONFIG is not set + if [[ -n "${config}" && -f "${config}" ]]; then + printf "%s" "$config" + return + fi + done +} + +main () { + # load config file + config_file="$(get_config_file)" + [[ -n "$config_file" ]] && source "$config_file" + + # create tmp dir + if [[ ! -d "$cache_dir/rofi-pass" ]]; then + mkdir -p "$cache_dir/rofi-pass" + fi + + # fix keyboard layout if enabled in config + if [[ $fix_layout == "true" ]]; then + layout_cmd + fi + + # set help color + if [[ $help_color == "" ]]; then + help_color=$(rofi -dump-xresources | grep 'rofi.color.normal' | gawk -F ',' '/,/{gsub(/ /, "", $2); print $2}') + fi + + # check for BROWSER variable, use xdg-open as fallback + if [[ -z $BROWSER ]]; then + export BROWSER=xdg-open + fi + + # check if alternative root directory was given on commandline + if [[ -r "$cache_dir/rofi-pass/last_used" ]] && [[ $1 == "--last-used" || $1 == "--show-last" ]]; then + roots=("$(awk -F ': ' '{ print $1 }' "$cache_dir/rofi-pass/last_used")") + elif [[ -n "$2" && "$1" == "--root" ]]; then + custom_root=true; IFS=: read -r -a roots <<< "$2" + elif [[ -n $root ]]; then + custom_root=true; IFS=: read -r -a roots <<< "${root}" + elif [[ -n ${PASSWORD_STORE_DIR} ]]; then + roots=("${PASSWORD_STORE_DIR}") + else + roots=("$HOME/.password-store") + fi + roots_index=0 + roots_length=${#roots[@]} + export root=${roots[$roots_index]} + export PASSWORD_STORE_DIR="${root}" + case $1 in + --insert) + insertPass + ;; + --root) + mainMenu + ;; + --help) + help_msg + ;; + --last-used) + if [[ -r "$cache_dir/rofi-pass/last_used" ]]; then + entry="$(awk -F ': ' '{ print $2 }' "$cache_dir/rofi-pass/last_used")" + fi + mainMenu + ;; + --show-last) + if [[ -r "$cache_dir/rofi-pass/last_used" ]]; then + selected_password="$(awk -F ': ' '{ print $2 }' "$cache_dir/rofi-pass/last_used")" viewEntry + else + mainMenu + fi + ;; + --bmarks) + mainMenu --bmarks; + ;; + *) + mainMenu + ;; + esac +} + +main "$@" diff --git a/rofi/.config/rofi/web-search.sh b/rofi/.config/rofi/web-search.sh index 70f31e1..f677c94 100755 --- a/rofi/.config/rofi/web-search.sh +++ b/rofi/.config/rofi/web-search.sh @@ -32,6 +32,7 @@ URLS=( ["maps"]="https://www.openstreetmap.com/search?query=" ["pirate"]="https://thepiratebay.zone/search/" ["search"]="https://search.unbl.ink/?q=" + ["ebay"]="https://www.ebay.com/sch/" ) # List for rofi