aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Readme.textile24
-rwxr-xr-xtwofa31
2 files changed, 49 insertions, 6 deletions
diff --git a/Readme.textile b/Readme.textile
index 123c0d6..3051c29 100644
--- a/Readme.textile
+++ b/Readme.textile
@@ -2,12 +2,30 @@ h1. twofa
p. A terrible, should-not-be-used, wrote-it-for-fun-and-learning 2fa authenticator.
+h2. Requirements
+
+p. twofa requires the _base32_ and _optimist_ gems.
+
+h3. Clipboard
+
+p. For clipboard tasks, twofa requires the _clipboard_ gem, and either the _xclip_ or _xsel_ application.
+
h2. Usage
-bc. $ twofa ISSUER
+bc.. $ twofa -h
+twofa is a command line TOTP code generator.
+
+Usage:
+ twofa [opts] ISSUER
+
+where [opts] are:
+ -n, --no-clip Do not copy code to the clipboard
+ -t, --twofa-file=<s> Location of the twofa secrets file (default: /home/nl987/.twofa)
+ -v, --version Print version and exit
+ -h, --help Show this message
-h3. @~/.twofa@
+h3. twofa secrets file
-p. The twofa rc file has the format:
+p. The twofa secrets file is normally found at @~./twofa@, and has the format:
bc. ISSUER SECRET [interval | default(30)] [length | default(6)] [hashing algorithm | default(sha1)]
diff --git a/twofa b/twofa
index 01c6e0c..a63c37f 100755
--- a/twofa
+++ b/twofa
@@ -2,6 +2,7 @@
require "openssl"
require "base32"
+require "optimist"
def db32(str)
Base32.decode(str)
@@ -62,8 +63,24 @@ class Secrets
end
end
-TWOFAFILE = File.join(ENV["HOME"], ".twofa")
-fatal("No 2fa issuers file at ~/.twofa") unless File.exist?(TWOFAFILE)
+opts = Optimist::options do
+ version "twofa (c) 2019 Nat Lasseter"
+ banner <<-EOS
+twofa is a command line TOTP code generator.
+
+Usage:
+ twofa [opts] ISSUER
+
+where [opts] are:
+EOS
+
+ opt :no_clip, "Do not copy code to the clipboard"
+ opt :twofa_file, "Location of the twofa secrets file",
+ type: :string, default: File.join(ENV["HOME"], ".twofa")
+end
+
+TWOFAFILE = opts[:twofa_file]
+fatal("No 2fa issuers file at #{File.absolute_path(TWOFAFILE)}") unless File.exist?(TWOFAFILE)
SECRETS = Secrets.new(File.readlines(TWOFAFILE).map(&:strip))
@@ -73,4 +90,12 @@ fatal("Specify issuer") if ISSUER.nil?
sec = SECRETS[ISSUER]
fatal("No such issuer") if sec.nil?
-puts "#{sec.verify} (for #{sec.time_remaining} more seconds)"
+code = sec.verify
+time = sec.time_remaining
+puts "#{code} (for #{time} more seconds)"
+
+unless opts[:no_clip] then
+ require "clipboard"
+ Clipboard.copy(code)
+ puts "(Copied to clipboard)"
+end