mytotp 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5430db4643c04284680830dfa98af44f421c088260dbfdfc654550a249d3707e
4
- data.tar.gz: dc7d8b9400f9f98c3b6b4b1d01d11d2dbfb4d887ee25a17687067f9b08256d59
3
+ metadata.gz: 1709c81172ffaea43aee506997a66c17bb611fa4d6a0eca9ba363b27164a1785
4
+ data.tar.gz: f192b136f75dc6401f5878794fc763ebc28ee611aea886322c4310e049078797
5
5
  SHA512:
6
- metadata.gz: bba5a6a3d08fab02caf637088acf15792452411b0a6ba7b80db72286e6349ccba89201031baa7f2e99e74866310c6fd073217ba3c1d3e7b0a111c95ac1a8c0fb
7
- data.tar.gz: 10d327657644c0a8b996faf8cf2a879d715dac6c7a5df94d86877f5172b81d40f3a58ec1ad26e6c080aa3177e05f6f67388caeaa72cb6e319b676ed75797bc5f
6
+ metadata.gz: 308f62c11949e20672b4b928b46b5985cf94e143f3db63c886bfe3010419fdaef24443bf98918d53121f7c1b2203bf6bcfb6caf1e62c2208dd808eee121fc7a4
7
+ data.tar.gz: 9031ab707aa6a941048eaa8c72491b455c0fc82aa500c994f132477952d1b02d9bb91333bb6e01c8e07209fe5b2796f90ae0d6b984d7f98443c23e90f63b9957
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Another TOTP cli app. Nice UI, simple to use and user-friendly.
4
4
 
5
+ ![mytotp-gif](https://github.com/a-chacon/mytotp/blob/aa60f18d3ec9885440796a13f66d553f0d656e96/mytotp.gif)
6
+
5
7
  ## Main features
6
8
 
7
9
  - Add, remove and update services.
data/exe/mytotp CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "mytotp"
4
- require "dry/cli"
3
+ require 'mytotp'
4
+ require 'dry/cli'
5
5
 
6
6
  Dry::CLI.new(Mytotp::Commands).call
@@ -2,15 +2,17 @@ module Mytotp
2
2
  module Commands
3
3
  ##
4
4
  # Class command for generate a totp token.
5
- # return IO
6
5
  class Generate < Dry::CLI::Command
7
- require "clipboard"
6
+ require 'clipboard'
8
7
 
9
- desc "Generate a totp for a specific service."
10
- argument :service, require: true, desc: "Service name."
11
- argument :username, desc: "Username."
12
- option :mode, default: "once", values: %w[once continuos], desc: "The generator mode"
8
+ desc 'Generate a totp for a specific service.'
9
+ argument :service, require: true, desc: 'Service name.'
10
+ argument :username, desc: 'Username.'
11
+ option :mode, default: 'once', values: %w[once continuos], desc: 'The generator mode'
13
12
 
13
+ # call the command function
14
+ # @param service [String] Service's name to generate the totp code.
15
+ # @param username [String] Service's username to generate the totp code.
14
16
  def call(service: nil, username: nil, **options)
15
17
  # find services
16
18
  services = Mytotp::Models::Service.where(Sequel.ilike(:service, "%#{service}%"))
@@ -29,12 +31,9 @@ module Mytotp
29
31
  generate_code(service, options.fetch(:mode))
30
32
  end
31
33
 
32
- private
33
-
34
34
  ##
35
35
  # Print message when is found one
36
- # Params: [Mytotp::Models::Service]
37
- # Returns: IO
36
+ # @param services [Collection[Mytotp::Models::Service]] Collection of services.
38
37
  def found_one_message(services)
39
38
  puts CLI::UI.fmt "{{green:Service:}} #{services.first.service.capitalize}"
40
39
  puts CLI::UI.fmt "{{green:Username:}} #{services.first.username.capitalize}"
@@ -42,10 +41,10 @@ module Mytotp
42
41
 
43
42
  ##
44
43
  # Ask which service when we have more than one found.
45
- # Params: [Mytotp::Models::Service]
46
- # Returns: Mytotp::Models::Service
44
+ # @param services [Collection[Mytotp::Models::Service]] Collection of services.
45
+ # @return [Mytotp::Models::Service] selected service
47
46
  def select_one(services)
48
- CLI::UI::Prompt.ask("Which service?") do |handler|
47
+ CLI::UI::Prompt.ask('Which service?') do |handler|
49
48
  services.each do |s|
50
49
  handler.option("#{s.service} : #{s.username}") { |_selection| s }
51
50
  end
@@ -54,11 +53,11 @@ module Mytotp
54
53
 
55
54
  ##
56
55
  # Generate the complete message with the code
57
- # Params: Mytotp::Models::Service,String
58
- # Returns: IO
56
+ # @param service [Mytotp::Models::Service] Selected service for generate the totp code
57
+ # @param mode [String] Mode for generate the code, it can be 'continuos' or by default 'once'
59
58
  def generate_code(service, mode)
60
59
  totp = ROTP::TOTP.new(service.key, interval: service.period, digits: service.digits)
61
- if mode == "continuos"
60
+ if mode == 'continuos'
62
61
  # infinit loop
63
62
  loop do
64
63
  actual_code = totp.now
@@ -80,8 +79,6 @@ module Mytotp
80
79
 
81
80
  ##
82
81
  # clear last line in the console
83
- # Params: nil
84
- # Returns: IO
85
82
  def clear_last_line
86
83
  # Clear the line
87
84
  print(CLI::UI::ANSI.previous_line + CLI::UI::ANSI.clear_to_end_of_line)
@@ -91,24 +88,24 @@ module Mytotp
91
88
 
92
89
  ##
93
90
  # Count seconds
94
- # Params: Mytotp::Models::Service, ROTP::TOTP
95
- # Returns: Integer
91
+ # @param service [Mytotp::Models::Service] Service to validate.
92
+ # @param totp [ROTP::TOTP] totp object generated with the service token.
93
+ # @return [Integer] seconds
96
94
  def valid_for(service, totp)
97
95
  (service.period - (Time.now - Time.at(totp.verify(totp.now)))).round
98
96
  end
99
97
 
100
98
  ##
101
99
  # Print valid for
102
- # Params: Mytotp::Models::Service, ROTP::TOTP
103
- # Returns: IO
100
+ # @param service [Mytotp::Models::Service] Service to validate.
101
+ # @param totp [ROTP::TOTP] totp object generated with the service token.
104
102
  def message_valid_for(service, totp)
105
103
  puts CLI::UI.fmt "{{green:Valid for:}} #{valid_for(service, totp)} seconds"
106
104
  end
107
105
 
108
106
  ##
109
107
  # Print the code
110
- # Params: String
111
- # Returns: IO
108
+ # @param totp [String] totp code generate for print.
112
109
  def message_code(totp)
113
110
  if copy_to_clipboard(totp)
114
111
  puts CLI::UI.fmt "{{green:Current TOTP:}} #{totp} - {{green:Copy!}}"
@@ -119,8 +116,8 @@ module Mytotp
119
116
 
120
117
  ##
121
118
  # Copy code to clipboar
122
- # Params: String
123
- # Returns: String
119
+ # @param code [String] Code to be copy on the clipboard.
120
+ # @return [Boolean] True or false depending if it was copy to clipboard or not.
124
121
  def copy_to_clipboard(code)
125
122
  Clipboard.copy(code)
126
123
  Clipboard.paste == code
@@ -2,9 +2,9 @@ module Mytotp
2
2
  module Commands
3
3
  ##
4
4
  # Class command for manage services.
5
- # return boolean.
6
5
  class Service < Dry::CLI::Command
7
- desc "Manage your services. Whitout subcommands print services."
6
+ desc 'Manage your services. Whitout subcommands print services.'
7
+ # call the command function
8
8
  def call(*)
9
9
  Mytotp::Models::Service.all.each do |s|
10
10
  puts CLI::UI.fmt "{{green:#{s.service.capitalize}}} - #{s.username.downcase}"
@@ -1,42 +1,47 @@
1
1
  module Mytotp
2
2
  module Commands
3
+ # services subcommands module
4
+ # it's group the service subcommands
3
5
  module Services
4
6
  ##
5
7
  # Class command for add a new service.
6
- # return String
7
8
  class Add < Dry::CLI::Command
8
- desc "Add a new service."
9
+ desc 'Add a new service.'
9
10
 
10
- argument :service, desc: "Service name."
11
+ argument :service, desc: 'Service name.'
11
12
  argument :username, desc: "Account's username"
12
- argument :key, desc: "Secret key"
13
+ argument :key, desc: 'Secret key'
13
14
 
15
+ # execute the command
16
+ # @param service [String] service name to add
17
+ # @param username [String] username used in the service
18
+ # @param key [String] totp key shared for generate the otp codes
14
19
  def call(service: nil, username: nil, key: nil, **)
15
20
  service_obj = Mytotp::Models::Service.new(service: service, username: username,
16
21
  key: key)
17
22
  service_obj = ask_for_incomplete(service_obj)
18
23
  service_obj.save
19
- puts CLI::UI.fmt "{{green:Correct saved!}}"
24
+ puts CLI::UI.fmt '{{green:Correct saved!}}'
20
25
  rescue StandardError => e
21
26
  print(e.to_s)
22
- puts CLI::UI.fmt "{{red:Something is not fine, try again!}}"
27
+ puts CLI::UI.fmt '{{red:Something is not fine, try again!}}'
23
28
  end
24
29
 
25
30
  ##
26
31
  # Ask incomplete information for a service_obj
27
- # Params: Mytotp::Models::Service
28
- # Returns: Mytotp::Models::Service
32
+ # @param service_obj [Mytotp::Models::Service] the service object created with the arguments provided
33
+ # @return [Mytotp::Models::Service] the service object modify by the questions to the user
29
34
  def ask_for_incomplete(service_obj)
30
35
  # Check service if was input by argument or interactive ask
31
36
  if service_obj.service.nil?
32
37
  service_obj.service = CLI::UI.ask(
33
- "Which service do you want to add?", allow_empty: false
38
+ 'Which service do you want to add?', allow_empty: false
34
39
  )
35
40
  end
36
41
  # Check service if was input by argument or interactive ask
37
- service_obj.username = CLI::UI.ask("Username?", allow_empty: false) if service_obj.username.nil?
42
+ service_obj.username = CLI::UI.ask('Username?', allow_empty: false) if service_obj.username.nil?
38
43
  # Check service if was input by argument or interactive ask
39
- service_obj.key = CLI::UI.ask("Key?", allow_empty: false) if service_obj.key.nil?
44
+ service_obj.key = CLI::UI.ask('Key?', allow_empty: false) if service_obj.key.nil?
40
45
  service_obj
41
46
  end
42
47
  end
@@ -2,13 +2,16 @@ module Mytotp
2
2
  module Commands
3
3
  module Services
4
4
  ##
5
- # Class command for add a new service.
6
- # return String
5
+ # Class command for remove a service.
6
+ # the service can be search by service's name and username for remove.
7
7
  class Remove < Dry::CLI::Command
8
- desc "Remove a service."
9
- argument :service, desc: "Service name."
10
- argument :username, desc: "Username."
8
+ desc 'Remove a service.'
9
+ argument :service, desc: 'Service name.'
10
+ argument :username, desc: 'Username.'
11
11
 
12
+ # Execute the command
13
+ # @param service [String] service name to remove.
14
+ # @param username [String] username in the service.
12
15
  def call(service: nil, username: nil, **)
13
16
  services = Mytotp::Models::Service.where(
14
17
  Sequel.ilike(:service, "%#{service}%")
@@ -17,9 +20,9 @@ module Mytotp
17
20
  )
18
21
  case services.count
19
22
  when 0
20
- puts CLI::UI.fmt "{{yellow:No service found}}"
23
+ puts CLI::UI.fmt '{{yellow:No service found}}'
21
24
  when 1
22
- CLI::UI::Frame.open("We found one service!") do
25
+ CLI::UI::Frame.open('We found one service!') do
23
26
  # ask to remove
24
27
  remove(services.first.id)
25
28
  end
@@ -31,12 +34,11 @@ module Mytotp
31
34
 
32
35
  ##
33
36
  # Ask for which remove
34
- # Params: [Mytotp::Models::Service]
35
- # Returns: Nil
37
+ # @param services [Array[Mytotp::Models::Service]] Collection of services found by the input of the user.
36
38
  def multiple_options(services)
37
- CLI::UI::Frame.open("We found more than one!") do
39
+ CLI::UI::Frame.open('We found more than one!') do
38
40
  # puts services.map { |s| s.service + " " + s.username }
39
- id = CLI::UI::Prompt.ask("Which service do you want to remove?") do |handler|
41
+ id = CLI::UI::Prompt.ask('Which service do you want to remove?') do |handler|
40
42
  services.each do |s|
41
43
  handler.option("#{s.service} : #{s.username}") { |_selection| s.id }
42
44
  end
@@ -47,16 +49,15 @@ module Mytotp
47
49
 
48
50
  ##
49
51
  # Remove a service by id
50
- # Params: String
51
- # Returns: IO
52
+ # @param id [Integer] Unic ID of the service to remove.
52
53
  def remove(id)
53
54
  service_obj = Mytotp::Models::Service[id]
54
- answer = CLI::UI.ask("Are you sure?", options: %w[yes no])
55
- if answer == "yes"
55
+ answer = CLI::UI.ask('Are you sure?', options: %w[yes no])
56
+ if answer == 'yes'
56
57
  service_obj.delete
57
- puts CLI::UI.fmt "{{red:Service successfull removed!}}"
58
+ puts CLI::UI.fmt '{{red:Service successfull removed!}}'
58
59
  else
59
- puts CLI::UI.fmt "{{green:No service removed.}}"
60
+ puts CLI::UI.fmt '{{green:No service removed.}}'
60
61
  end
61
62
  end
62
63
  end
@@ -2,9 +2,10 @@ module Mytotp
2
2
  module Commands
3
3
  ##
4
4
  # Class command for show the app version
5
- # return String
6
5
  class Version < Dry::CLI::Command
7
6
  desc "Print #{::Mytotp::APP_NAME} version."
7
+
8
+ # execute the command
8
9
  def call(*)
9
10
  puts VERSION
10
11
  end
@@ -1,12 +1,13 @@
1
1
  module Mytotp
2
+ # It's include and register all commands available in the app
2
3
  module Commands
3
4
  extend Dry::CLI::Registry
4
5
 
5
6
  # register clasess like commands
6
- register "version", Mytotp::Commands::Version, aliases: ["v", "-v", "--version"]
7
- register "generate", Mytotp::Commands::Generate, aliases: ["g"]
8
- register "service", Mytotp::Commands::Service
9
- register "service add", Mytotp::Commands::Services::Add
10
- register "service remove", Mytotp::Commands::Services::Remove
7
+ register 'version', Mytotp::Commands::Version, aliases: ['v', '-v', '--version']
8
+ register 'generate', Mytotp::Commands::Generate, aliases: ['g']
9
+ register 'service', Mytotp::Commands::Service
10
+ register 'service add', Mytotp::Commands::Services::Add
11
+ register 'service remove', Mytotp::Commands::Services::Remove
11
12
  end
12
13
  end
@@ -1,8 +1,11 @@
1
1
  module Mytotp
2
+ # It's include the model created for save services
2
3
  module Models
3
4
  ##
4
5
  # Service model
5
6
  class Service < Sequel::Model
7
+ # callback for apply upcase to service and username,
8
+ # this is doing for make easy to search later
6
9
  def before_save
7
10
  self.service = service.upcase
8
11
  self.username = username.upcase
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mytotp
4
- VERSION = "0.1.2"
4
+ # app version
5
+ VERSION = '0.1.3'
5
6
  end
data/lib/mytotp.rb CHANGED
@@ -1,23 +1,25 @@
1
1
  # require_relative "mytotp/version"
2
- require "dry/cli"
3
- require "sequel"
4
- require "zeitwerk"
5
- require "cli/ui"
6
- require "rotp"
2
+ require 'dry/cli'
3
+ require 'sequel'
4
+ require 'zeitwerk'
5
+ require 'cli/ui'
6
+ require 'rotp'
7
7
  # code loader
8
8
  Zeitwerk::Loader.eager_load_all
9
9
  loader = Zeitwerk::Loader.for_gem
10
10
  loader.setup # ready!
11
- ##
12
- # Mytotp module
11
+
12
+ # Main module of the app,
13
+ # its contains the global variables and configurations
14
+ # @author a-chacon
13
15
  module Mytotp
14
16
  # app name
15
- APP_NAME = "Mytotp".freeze
17
+ APP_NAME = 'Mytotp'.freeze
16
18
  # cli configuration
17
19
  CLI::UI.frame_style = :bracket
18
20
  CLI::UI::StdoutRouter.enable
19
21
 
20
- if ENV.fetch("MYTOTP_ENV", nil) == "test"
22
+ if ENV.fetch('MYTOTP_ENV', nil) == 'test'
21
23
  # db connection, in memmory only
22
24
  DB = Sequel.sqlite
23
25
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mytotp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - a-chacon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-20 00:00:00.000000000 Z
11
+ date: 2022-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -120,8 +120,8 @@ dependencies:
120
120
  - - ">="
121
121
  - !ruby/object:Gem::Version
122
122
  version: 2.5.4
123
- description: Totp cli tool for who loves the cli. With features that I don't found
124
- in another totp cli.
123
+ description: Totp cli tool for who loves the cli. I made it for myself, I don't like
124
+ others.
125
125
  email:
126
126
  - andres.ch@protonmail.com
127
127
  executables:
@@ -145,10 +145,11 @@ homepage: https://github.com/a-chacon/mytotp
145
145
  licenses:
146
146
  - GPL-3.0
147
147
  metadata:
148
+ bug_tracker_uri: https://github.com/a-chacon/mytotp/issues
149
+ changelog_uri: https://github.com/a-chacon/mytotp
150
+ documentation_uri: https://www.rubydoc.info/gems/mytotp
148
151
  homepage_uri: https://github.com/a-chacon/mytotp
149
152
  source_code_uri: https://github.com/a-chacon/mytotp
150
- changelog_uri: https://github.com/a-chacon/mytotp
151
- rubygems_mfa_required: 'true'
152
153
  post_install_message:
153
154
  rdoc_options: []
154
155
  require_paths:
@@ -167,5 +168,5 @@ requirements: []
167
168
  rubygems_version: 3.2.22
168
169
  signing_key:
169
170
  specification_version: 4
170
- summary: Another totp cli
171
+ summary: Another boring totp cli.
171
172
  test_files: []