require "option_parser" require "yaml" require "colorize" # password serializer class Password include YAML::Serializable @[YAML::Field(key: "url")] property url : String @[YAML::Field(key: "email")] property email : String @[YAML::Field(key: "login")] property login : String @[YAML::Field(key: "password")] property password : String @[YAML::Field(key: "desc")] property desc : String @[YAML::Field(key: "profile_url")] property profile_url : String @[YAML::Field(key: "update")] property update : Int32 end VERSION = "0.2.2" # program options begin OptionParser.parse do |parser| parser.banner = "The very simple password manager for humans\n" parser.on "-v", "--version", "Show version" do puts "Version #{VERSION}" exit(0) end parser.on "-h", "--help", "Show help" do puts parser exit(0) end parser.on "-g", "--generate-password", "Generate password" do puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:black).back(:white) puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:white).back(:blue) puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:white).back(:red) exit(0) end parser.on "-t", "--unixtime", "Return local timestamp" do puts Time.local.to_unix.colorize(:yellow) exit(0) end end rescue ex puts ex.message, "" end # password_file_path = PROGRAM_NAME.split("/") # password_file_path.pop # password_file_path.insert(-1, "pwd.yml") # password_file_path = password_file_path.join("/") # TODO: Fix later password_file_path = "#{ENV["HOME"]}/.pwd.yml" # check password file exists if File.exists?(password_file_path) yaml = File.open(password_file_path) do |file| YAML.parse(file) end else puts "No password.yml file exists." exit(1) end # fill passwords array passwords_array = [] of Password count = 0 while count < yaml.size passwords_array << Password.from_yaml(yaml[count].to_yaml) count += 1 end # main loop loop = true while loop # shell prompt print "Enter URL (or :q for exit)\n".colorize(:white).mode(:bold) print "> ".colorize(:green).mode(:bold) password_string = gets # if ':q' to close program if password_string.to_s == ":q" puts "Bye! 👋🏻" exit(0) # if puts empty, retry prompt elsif password_string.to_s.size == 0 puts # if ':h' to view help elsif password_string.to_s == ":h" puts "Help:\n-----" puts ":s - Return stats" # if ':s' to view Statistics elsif password_string.to_s == ":s" puts "Statistics:\n----------" print "Elements: ".colorize(:yellow) puts passwords_array.size print "Outdated: ".colorize(:red) outdated_count = 0 current_time = Time.local.to_unix a = [] of String passwords_array.each do |item| if item.update + (2629743 * 2) < current_time # 2629743 * 2 -- 2 month outdated_count += 1 a << item.url end end puts outdated_count # list search password else passwords_array.each do |item| if item.url.includes?(password_string.to_s) puts item.url.colorize(:magenta).mode(:bold).mode(:underline) if !item.email.blank? puts item.email.colorize(:red) end if !item.login.blank? puts item.login.colorize(:yellow) end if !item.password.blank? puts item.password.colorize(:red).back(:red) end if !item.desc.blank? puts item.desc.colorize(:cyan) end if !item.profile_url.blank? puts item.profile_url.colorize(:green) end puts "-----".colorize(:dark_gray).mode(:bold) end end end puts end