Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updated mytotp.rc, added mytotp.rc.README.md #2

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Basic set up for three package managers

version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
# Workflow files stored in the default location of `.github/workflows`. (You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.)
directory: "/"
schedule:
interval: "weekly"
day: "sunday"
time: "17:00"
102 changes: 102 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Release

on:
push:
tags:
- "v*.*.*"
workflow_dispatch:

jobs:
release:
runs-on: windows-latest
permissions:
contents: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history including tags

- name: Get previous tag
id: get_previous_tag
shell: pwsh
run: |
$tags = git tag --sort=-creatordate
$tagsArray = $tags -split "`n"
$prevTag = if ($tagsArray.Length -ge 2) { $tagsArray[1].Trim() } else { "" }
Write-Host "Previous tag: $prevTag"
echo "PREV_TAG=$prevTag" >> $env:GITHUB_ENV

- name: Create release notes
id: create_release_notes
shell: pwsh
run: |
echo "## Release Notes" > release_notes.md
echo "" >> release_notes.md
Get-Content "./latest_release_notes.md" >> release_notes.md
echo "" >> release_notes.md
echo "### Changes in this release:" >> release_notes.md
echo "" >> release_notes.md
$PREV_TAG = $env:PREV_TAG
Write-Host "Previous tag: $PREV_TAG"
if ([string]::IsNullOrEmpty($PREV_TAG)) {
Write-Host "No previous tag found. Using fallback."
git log --pretty=format:%s "${GITHUB_REF}~2..${GITHUB_REF}" >> release_notes.md
} else {
git log --pretty=format:%s "$PREV_TAG..${GITHUB_REF}" >> release_notes.md
}
echo "" >> release_notes.md

- name: Extract tag name
id: extract_tag_name
shell: pwsh
run: |
if ($env:GITHUB_REF -match 'refs/tags/(.*)') {
$tagName = $matches[1]
} else {
$tagName = git describe --tags $(git rev-list --tags --max-count=1)
}
Write-Host "Tag name: $tagName"
echo "TAG_NAME=$tagName" >> $env:GITHUB_ENV

- name: Create GitHub Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
with:
tag_name: ${{ env.TAG_NAME }}
release_name: Release ${{ env.TAG_NAME }}
body_path: ./release_notes.md
draft: false

- name: Upload PowerShell script
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./mytotp.rc.ps1
asset_name: mytotp.rc.ps1
asset_content_type: text/plain

- name: Upload Bash script
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./mytotp.rc
asset_name: mytotp.rc
asset_content_type: text/plain

- name: Upload README.md
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./mytotp.rc.README.md
asset_name: README.md
asset_content_type: text/markdown
Empty file added latest_release_notes.md
Empty file.
158 changes: 133 additions & 25 deletions mytotp.rc
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
#!/bin/bash
# this code is a fork of https://github.com/ThingCrimson/mytotp
# put this file in path and source it in .bashrc or .zshrc
# add next line to .bashrc or .zshrc
# source mytotp.sh
# there are prerequisites to use this code:
# 1. gpg
# 2. oathtool
# 3. xclip (optional, for Linux only) or pbpaste (it is included in MacOS)
# 4. that for MacOS only bash 5.2.26, if you have older version that is default case for MacOS, please upgrade it with brew or use previous version of script,
# see this repo releases for MacOS standard bash
# put this file in ~ path and source it in .bashrc or .zshrc
# if [ -f $HOME/mytotp.rc ]; then
# . $HOME/mytotp.rc
# fi
# or add next line to .bashrc or .zshrc
# source /path/to/somewhere/mytotp.rc
# create a directory for the keys ~/.config/mytotp
# usage, mannually creating SERVID.gpg file:
# Put TOTP key for service SERVID to GPG file crypted for '\''My TOTP'\''
Expand All @@ -12,30 +22,55 @@
# mytotpadd SERVID
# usage, listing all SERVIDs:
# mytotplist
function mytotp() {
if ! command -v oathtool &> /dev/null
then
echo "oathtool could not be found"
echo "Please install it with: brew install oath-toolkit"
KEYDIR=~/.config/mytotp
KEYEXT=.gpg
if [ "$(uname)" == "Darwin" ]; then
PASTECOMMAND="pbpaste"
# make check of bash version, if it is even to 3.2.57 then show warning and instructions how to upgrade shell to bash 5.2.26 with brew, then exit with code 1
if [ "$(echo $BASH_VERSION | awk -F. '{print $1}')" -eq 3 ] && [ "$(echo $BASH_VERSION | awk -F. '{print $2}')" -eq 2 ] && [ "$(echo $BASH_VERSION | awk -F. '{print $3}')" -eq 57 ]; then
echo "Your MacOS bash version is too old, please upgrade it to 5.2.26 with brew, following these steps"
echo "brew install bash"
echo "sudo ln -s /opt/homebrew/bin/bash /usr/local/bin/bash "
echo "sudo bash -c 'echo /usr/local/bin/bash >> /etc/shells'"
echo "optional step to change default zsh to bash, not really needed: chsh -s /usr/local/bin/bash"
return 1
fi
fi
if [ "$(uname)" == "Linux" ]; then
if ! command -v xclip &>/dev/null; then
echo "xclip could not be found. It is an optional tool for reading the initial key from the clipboard."
echo "If you want to use this optional feature, please install it with: sudo apt-get install xclip"
read -p "Do you want to continue without xclip? (y/n) " yn
case $yn in
[Yy]*) ;;
[Nn]*) return 1 ;;
*) echo "Please answer yes or no." ;;
esac
fi
PASTECOMMAND="xclip -o"
fi

KEYDIR=~/.config/mytotp
KEYEXT=.gpg
function mytotp() {
SERVID=$1

if [ -z "${SERVID}" ] ; then
echo -e "Usage: $0 SERVID\n\tSERVID is a service ID, abbreviated, w/o ext:"
find ${KEYDIR}/*${KEYEXT} | sed -e 's/\/home.*\// /; s/\.gpg//'
return 2
if ! command -v oathtool &>/dev/null; then
echo "oathtool could not be found"
echo "Please install it with: brew install oath-toolkit"
echo "or check further https://launchpad.net/oath-toolkit/+packages && https://www.nongnu.org/oath-toolkit/"
return 1
fi

if [ ! -f "${KEYDIR}/${SERVID}${KEYEXT}" ] ; then
echo "No key for ${KEYDIR}/${SERVID}${KEYEXT}"
if [ -z "$1" ]; then
echo "mytotp version 1.0.1.rc"
echo "Usage: mytotp SERVID"
echo "SERVID is a service ID, abbreviated, that you provided for mytotpadd before, check all with mytotplist command"
return 1
fi


if [ ! -f "${KEYDIR}/${SERVID}${KEYEXT}" ]; then
echo "No key for ${KEYDIR}/${SERVID}${KEYEXT}"
return 1
fi

SKEY=$(gpg -d --quiet "${KEYDIR}/${SERVID}${KEYEXT}")

Expand All @@ -47,7 +82,7 @@ function mytotp() {
echo -n "Seconds :${NOWS} (we need to wait ${WAIT}) ... "
sleep ${WAIT}

TOTP=$(echo "${SKEY}" | oathtool -b --totp - )
TOTP=$(echo "${SKEY}" | oathtool -b --totp -)

echo "${TOTP}"
SKEY="none"
Expand All @@ -57,22 +92,95 @@ function mytotp() {
# add new SERVID to GPG file in ~/.config/mytotp/SERVID.gpg
# paste the key in the prompt and press enter, then $SERVID.gpg will be created
function mytotpadd() {
SERVID=$1
# Check if "My TOTP" GPG key exists
if ! gpg --list-keys "My TOTP" >/dev/null 2>&1; then
echo "GPG key 'My TOTP' does not exist. Please create it first."
# ask user if they want to create the key
read -p "Do you want to create the key 'My TOTP' now ? (y/n) " yn
case $yn in
[Yy]*)
echo "Write and remember the password for 'My TOTP' gpg key in the next line:"
gpg --yes --batch --passphrase-fd 0 --quick-generate-key 'My TOTP'
;;
[Nn]*) return 1 ;;
*) echo "Please answer yes or no." ;;
esac
echo "get back with further usage: mytotpadd <SERVID>"
return
fi

# if no $1 supplied, exit
if [ -z "$1" ] ; then
if [ -z "$1" ]; then
echo -e "Usage: $0 SERVID\n\tSERVID is a service ID, abbreviated, w/o ext:"
return 1
fi
KEYDIR=~/.config/mytotp
KEYEXT=.gpg
SERVID=$1

# print user instruction about press control-D to stop gpg"
echo "Paste the key in the prompt, press enter, and then press control-D to stop gpg"
gpg -e -r "My TOTP" >~/.config/mytotp/$SERVID.gpg
# if you want paste again the key, this way it would be stored in ~/.config/mytotp/SERVIDS.keys.lst file
# read from clipboard with xclip
echo "Do you want to store the initial service key in .key.asc? Warn: it is unsafe (y/n) "
read -p "y/n " byn
case $byn in
[Yy]*) $PASTECOMMAND >>~/.config/mytotp/${SERVID}.key.asc ;;
[Nn]*) return ;;
*) echo "Please answer yes or no." ;;
esac
}

function mytotpdel() {
SERVID=$1
if [ -z "$1" ]; then
echo -e "Usage: $0 SERVID\n\tSERVID is a service ID, abbreviated, w/o ext:"
return 1
fi
if [ -f "${KEYDIR}/${SERVID}${KEYEXT}" ]; then
rm -f "${KEYDIR}/${SERVID}${KEYEXT}"
echo "Key for ${SERVID} deleted."
else
echo "No key for ${SERVID}"
fi
}

# function to list all SERVIDs in ~/.config/mytotp
function mytotplist() {
KEYDIR=~/.config/mytotp
KEYEXT=.gpg
find ${KEYDIR}/*${KEYEXT} | sed -e 's/\/home.*\// /; s/\.gpg//'
if [ ! -d "${KEYDIR}" ]; then
read -p "Directory ${KEYDIR} does not exist. Do you want to create it? (y/n) " yn
case $yn in
[Yy]*) mkdir -p "${KEYDIR}" ;;
[Nn]*) return ;;
*) echo "Please answer yes or no." ;;
esac
fi

ENTRIES=$(find ${KEYDIR}/*${KEYEXT} 2>/dev/null | sed -e 's/\/home.*\// /; s/\.gpg//')

if [ -z "$ENTRIES" ]; then
echo "Warning: No SERVID entries found."
else
echo "$ENTRIES"
fi
}

# Function to get the list of .gpg files in $KEYDIR
get_gpg_files() {
find "$KEYDIR" -name "*$KEYEXT" -type f 2>/dev/null | sed -e "s|$KEYDIR/||" -e "s|$KEYEXT||"
}

# Register argument completer for mytotpdel function
_mytotpdel_completions() {
local cur_word="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(compgen -W "$(get_gpg_files)" -- "$cur_word") )
}

# Register argument completer for mytotp function
_mytotp_completions() {
local cur_word="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(compgen -W "$(get_gpg_files)" -- "$cur_word") )
}

# Register the completion functions
complete -F _mytotpdel_completions mytotpdel
complete -F _mytotp_completions mytotp
Loading