Compare commits

...

45 Commits

Author SHA1 Message Date
a0775932ec
development version 2023-04-14 21:54:36 +03:00
45897a4f81
User input is converted to lowercase 2023-04-14 21:50:32 +03:00
8e01c4adb0
add Crystal badge 2022-08-21 18:23:54 +03:00
1fda6f7b14
add comments 2022-08-07 21:29:12 +03:00
abdb758aa2
user input timeout env variable 2022-08-07 21:23:59 +03:00
2ce1701039
update to 0.2.6 2022-08-05 23:29:36 +03:00
068c3a48f4
add download badges 2022-08-04 00:32:54 +03:00
dd67a7095c
remove list dots from readme 2022-08-04 00:24:14 +03:00
3b6c8af8cc
move screenshot 2022-08-04 00:22:11 +03:00
b820b7bb4d
add version to ascii logo 2022-08-04 00:19:57 +03:00
7d200ec423
Merge branch 'master' of git.a2s.su:iiiypuk/pmng 2022-08-04 00:15:33 +03:00
0ce3e506bb
custom pwd file path 2022-08-04 00:10:56 +03:00
0a5f51ff8f add musl check 2022-07-31 16:48:41 +03:00
51a09ffe61
add build releases script 2022-07-31 03:01:36 +03:00
526d29bef1
0.2.5 2022-07-31 02:31:37 +03:00
d08349f800
fix return code style 2022-07-31 02:25:56 +03:00
70a2e47727
add functions module 2022-07-31 02:23:58 +03:00
626e7cbe0b
separate source file 2022-07-31 01:40:30 +03:00
5152598804
add input timeout 2022-07-31 01:20:23 +03:00
b8de2dd0b8
change section level 2022-07-26 23:11:37 +03:00
0ff3a7da59
restore emoji 2022-07-26 20:25:40 +03:00
aea5284279
NO_COLOR info 2022-07-26 19:16:42 +03:00
a1bc755181 file password file name 2022-06-26 23:54:21 +03:00
9fae7124be
fix "finded records" for all query 2022-05-21 00:07:33 +03:00
0e6ed176b3
fix README 2022-05-02 11:34:18 +03:00
c28d5b66cb
0.2.3 2022-05-02 11:25:51 +03:00
93d15954e2
add screenshots 2022-05-02 11:22:14 +03:00
d28d402d40
add colors to help output 2022-05-02 11:04:29 +03:00
b2ec5fdfe1
add show count finded records 2022-05-02 10:51:25 +03:00
f7bb266cac
add logo 2022-05-02 10:41:31 +03:00
bc7ebefe61
change time password outdated 2022-04-09 22:06:40 +03:00
70153a6e42
0.2.2 2022-04-08 17:49:26 +03:00
d72acba22c
check file permissions 2022-04-08 17:35:56 +03:00
ddaa870668
🗿 2022-04-08 16:38:03 +03:00
5009a393c3
:-[ 2022-04-08 16:30:33 +03:00
237b811a80
Added clear terminal by close program 💻 2022-04-08 16:23:14 +03:00
71c6fbce7c
added to user prompt help tooltip 2022-04-08 16:11:44 +03:00
9818b43f80
add emoji to output 👦 2022-04-08 16:05:11 +03:00
1dead2cc47
change URL output 2022-04-08 15:59:24 +03:00
d49dcda651
0.2.1 2022-03-15 01:56:01 +03:00
6fc0459d81
change pwd path 2022-03-15 01:42:17 +03:00
ce5bca45a3 0.2.1 2022-03-13 13:46:29 +03:00
038e8a0b14 read pwd.yml from program folder 2022-01-04 22:31:02 +03:00
b3d0e8c058 fix exit() 2022-01-04 00:52:31 +03:00
fbe8c494ec using ameba 2022-01-04 00:30:41 +03:00
20 changed files with 388 additions and 148 deletions

BIN
.docs/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
.docs/passwords.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -13,3 +13,6 @@ indent_size = 2
[{*.ecr,*.json}]
indent_style = tab
indent_size = 4
[README.md]
trim_trailing_whitespace = false

6
.gitignore vendored
View File

@ -1,10 +1,6 @@
/docs/
/dist/
/lib/
/bin/
/.shards/
*.dwarf
/src/views/
data.json
pwd.yml

51
HISTORY.md Normal file
View File

@ -0,0 +1,51 @@
## Legend
- 🐛 - Bug
- ✔️ - Fixed
- ❌ - Removed
- - Added
- - Information
- ♻️ - Edited
## 0.2.7b - [14/04/2023]
- - Added environment variable for custom input timeout
- ✔️ - User input is converted to lowercase
## 0.2.6 - [03/08/2022]
- - Added environment variable for custom password file path
- - Added version in to ASCII logo
## 0.2.5 - [31/07/2022]
- - Added timeout user input
- ♻️ - Source file separated
## 0.2.4 - [26/07/2022]
- - Added hint for fix file permissions error.
- - Crystal version raise to 1.5.0 for NO_COLOR support
- ✔️ - Fixed output finding records for all queryes
- ✔️ - Fixed check password file name info
## 0.2.3 - [02/05/2022]
- ♻️ - Password outdated date change to 3 month
- - Added `pmng` logo
- - Added show count finded records
- - Added colors to help output
## 0.2.2 - [08/04/2022]
- - Added check permissions for password file
- - Added title by start program
- - Added terminal cleaning functionality
- - Added help tips to user prompt
- - Added emoji for output
- - Added colors for help sections
- ✔️ - Fixed bug on bye emoji color
- ♻️ - Edited color & style for data output
- 🐛 - After emoji label not view space symbol (emoji temporary changed)
## 0.2.1 - [14/03/2022]
- - prompt '>' set color green
- ♻️ - change default pwd path to '$HOME/.pwd.yml'
- ✔️ - fixed empty search field
- ✔️ - fixed password generate colors to russian flag
## 0.2.0 - [04/01/2022]
- reading passwords file from program folder (portable mode)

View File

@ -1 +1,15 @@
# passw0rd_manager
# 🔑 The very simple password manager for humans
![Crystal](https://img.shields.io/badge/Crystal-000000?style=for-the-badge&color=000000&logo=crystal)
![License](https://img.shields.io/badge/license-public_domain-brightgreen?style=for-the-badge&color=ffcc68)
![NO_COLOR](https://img.shields.io/badge/no__color-support-brightgreen?style=for-the-badge&color=d44e52)
![Emoji](https://img.shields.io/badge/emoji-like-brightgreen?style=for-the-badge&color=ec8a4b)
[![Download](https://img.shields.io/badge/Download-brightgreen?style=for-the-badge&color=38607c)](#download)
## 📷 Screenshots
See [SCREENSHOTS.md](SCREENSHOTS.md).
## 💾 Download
[![Linux x86_64](https://img.shields.io/badge/linux-x86--64-brightgreen?style=for-the-badge&color=55a894)](https://data.iiiypuk.me/pmng/alpha/pmng-0.2.6-linux-x86_64.tar.xz)

5
SCREENSHOTS.md Normal file
View File

@ -0,0 +1,5 @@
## 📷 Screenshots
![pmng](./.docs/logo.png)
![Passwords](./.docs/passwords.png)

25
build_release.sh Executable file
View File

@ -0,0 +1,25 @@
#!/bin/sh
# Preparing
if [ -d "./dist/" ];
then
rm dist/* 2> /dev/null
else
mkdir dist/
fi
# Detect Musl C library
# thx @Unmanned Player https://stackoverflow.com/a/60471114
libc=$(ldd /bin/ls | grep 'musl' | head -1 | cut -d ' ' -f1)
if [ -z $libc ];
then
# build libc
OUTPUT=pmng-$(shards version)-linux-x86_64
crystal build ./src/pmng.cr --release --progress -o ./dist/$OUTPUT
tar -cJf ./dist/$OUTPUT.tar.xz ./dist/$OUTPUT
else
# Build musl
crystal build ./src/pmng.cr --release --progress -o ./dist/pmng-$(shards version)-linux-musl-x86_64
fi

View File

@ -1,2 +1,6 @@
version: 2.0
shards: {}
shards:
ameba:
git: https://github.com/crystal-ameba/ameba.git
version: 1.4.3

View File

@ -1,15 +1,18 @@
name: passw0rd_manager
version: 0.1.0
name: pmng
version: 0.2.7
authors:
- Alexander Popov <iiiypuk@iiiypuk.me>
targets:
passw0rd_manager:
main: src/passw0rd_manager.cr
pmng:
main: src/pmng.cr
dependencies:
development_dependencies:
ameba:
github: crystal-ameba/ameba
version: ~> 1.4.0
crystal: 1.2.2
crystal: 1.7.0
license: MIT

View File

@ -1,9 +0,0 @@
require "./spec_helper"
describe Passw0rdManager do
# TODO: Write tests
it "works" do
false.should eq(true)
end
end

View File

@ -1,2 +1,2 @@
require "spec"
require "../src/passw0rd_manager"
require "../src/pmng"

View File

@ -1,125 +0,0 @@
require "option_parser"
require "yaml"
require "colorize"
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.1.0"
begin
OptionParser.parse do |parser|
parser.banner = "Welcome to The Beatles App!"
parser.on "-v", "--version", "Show version" do
puts "Version #{VERSION}"
exit
end
parser.on "-h", "--help", "Show help" do
puts parser
exit
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(:red)
puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:white).back(:blue)
exit
end
parser.on "-t", "--unixtime", "Return local timestamp" do
puts Time.local.to_unix.colorize(:yellow)
exit
end
end
rescue ex
puts ex.message, ""
end
if !File.exists?("pwd.yml")
puts "No password.yml file exists."
exit(1)
end
yaml = File.open("pwd.yml") do |file|
YAML.parse(file)
end
new_array = [] of Password
count = 0
while count < yaml.size
new_array << Password.from_yaml(yaml[count].to_yaml)
count += 1
end
while true
print "Enter URL (or :q for exit)\n> "
password_string = gets
if password_string.to_s == ":q"
puts "Bye! 👋🏻"
exit
elsif password_string.to_s == ":h"
puts "Help:\n-----"
puts ":s - Return stats"
elsif password_string.to_s == ":s"
puts "Statictics:\n----------"
print "Elements: ".colorize(:yellow)
puts new_array.size
print "Outdated: ".colorize(:red)
outdated_count = 0
current_time = Time.local.to_unix
a = [] of String
new_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
end
new_array.each do |item|
if item.url.includes?(password_string.to_s)
puts item.url.colorize(:magenta).mode(:blink)
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)
end
end
puts
end

118
src/pmng.cr Normal file
View File

@ -0,0 +1,118 @@
require "option_parser"
require "yaml"
require "colorize"
require "./pmng/*"
require "./pmng/functions/*"
module Pmng
# check password file exists
if File.exists?(PASSWORD_FILE_PATH)
yaml = File.open(PASSWORD_FILE_PATH) do |file|
YAML.parse(file)
end
else
print "~/.pwd.yml".colorize(:red).mode(:bold)
puts ": No such file"
exit(1)
end
# check file ppermissions
password_file_permissions = File.info(PASSWORD_FILE_PATH).permissions.to_s
if /\d{3}/.match(password_file_permissions).try &.[0] != "600"
puts "Password file permissions is not RW for you.".colorize(:red)
print "Execute: ".colorize(:yellow)
print "(chmod 600 ~/.pwd.yml) ".colorize(:green).mode(:bold)
puts "for fix.".colorize(:yellow)
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
# pmng title
system "clear"
puts ASCII_LOGO.colorize(:yellow)
puts "The very simple password manager for humans".colorize(:yellow).mode(:bold)
puts "-------------------------------------------".colorize(:yellow).mode(:bold)
statistics = Functions::Statistics.new(passwords_array)
# main loop
loop = true
while loop
# shell prompt
print "Enter URL (".colorize(:white).mode(:bold)
print ":h".colorize(:red).mode(:bold)
print " for help or ".colorize(:white).mode(:bold)
print ":q".colorize(:red).mode(:bold)
print " for exit)\n".colorize(:white).mode(:bold)
print "> ".colorize(:green).mode(:bold)
begin
STDIN.read_timeout = USER_INPUT_TIMEOUT
password_string = STDIN.gets
rescue IO::TimeoutError
loop = false
end
if password_string.to_s == ":q"
# if ':q' to close program
loop = false
elsif password_string.to_s.size == 0
# if puts empty, retry prompt
puts
elsif password_string.to_s == ":h"
# if ':h' to view help
system "clear"
puts "Help\n----".colorize(:yellow).mode(:bold)
print ":s".colorize(:red).mode(:bold)
puts " - Return stats"
elsif password_string.to_s == ":s"
# if ':s' to view Statistics
system "clear"
puts "Statistics\n----------".colorize(:yellow).mode(:bold)
print "All elements: ".colorize(:yellow).mode(:bold)
puts statistics.size
print "Passwords outdated: ".colorize(:red).mode(:bold)
puts statistics.outdated
else
# list search password
system "clear"
passwords_finded_array = 0
passwords_array.each do |item|
if item.url.includes?(password_string.to_s.downcase)
Functions.show_item(item)
puts "-----".colorize(:dark_gray).mode(:bold)
passwords_finded_array += 1
end
end
puts
print "Finded ".colorize(:yellow).mode(:bold)
print passwords_finded_array.colorize(:red).mode(:bold)
puts " records".colorize(:yellow).mode(:bold)
puts "-----".colorize(:dark_gray).mode(:bold)
end
puts
end
system "clear"
puts "Bye! 👋"
end

35
src/pmng/agrv_options.cr Normal file
View File

@ -0,0 +1,35 @@
begin
OptionParser.parse do |parser|
parser.banner = "The very simple password manager for humans\n"
parser.on "-v", "--version", "Show version" do
puts ASCII_LOGO.colorize(:yellow)
puts "The very simple password manager for humans.".colorize(:yellow)
print "Version ".colorize(:yellow)
puts VERSION.colorize(:red).mode(:bold)
puts "\nURL to full changes log: ".colorize(:yellow)
puts "https://git.a2s.su/iiiypuk/pmng/raw/branch/master/HISTORY.md".colorize(:green).mode(:bold)
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).mode(:bold)
exit(0)
end
end
rescue ex
puts ex.message, ""
end

28
src/pmng/app_settings.cr Normal file
View File

@ -0,0 +1,28 @@
def password_file
# Return password file path
begin
file_path = "#{ENV["PMNG_PWD_FILE"]}"
file_path.to_s
rescue KeyError
file_path = "#{ENV["HOME"]}/.pwd.yml"
file_path.to_s
end
end
def input_timeout
# Return user input timeout
user_input_timeout = 60
begin
user_input_timeout = "#{ENV["PMNG_TIMEOUT"]}"
user_input_timeout.to_i
rescue KeyError
user_input_timeout.to_i # return default 60s
end
end
VERSION = {{ `shards version "#{__DIR__}"`.chomp.stringify }}
PASSWORD_FILE_PATH = password_file()
USER_INPUT_TIMEOUT = input_timeout()

8
src/pmng/ascii_logo.cr Normal file
View File

@ -0,0 +1,8 @@
ASCII_LOGO = "
#{VERSION}
"

View File

@ -0,0 +1,33 @@
module Pmng::Functions
extend self
def show_item(password)
print "🌐 "
puts password.url.colorize(:magenta).mode(:bold).mode(:underline)
if !password.email.blank?
print "📧 "
puts password.email.colorize(:red)
end
if !password.login.blank?
print "🗿 "
puts password.login.colorize(:yellow)
end
if !password.password.blank?
print "🔐 "
puts password.password.colorize(:red).back(:red)
end
if !password.desc.blank?
print "📄 "
puts password.desc.colorize(:cyan)
end
if !password.profile_url.blank?
print "👦 "
puts password.profile_url.colorize(:green)
end
end
end

View File

@ -0,0 +1,33 @@
module Pmng::Functions
extend self
class Statistics
getter passwords : Array(Password)
getter outdated : Int32
getter size : Int32
def initialize(@passwords)
@size = passwords.size
outdated_count = 0
current_time = Time.local.to_unix
a = [] of String
@passwords.each do |item|
if item.update + (2629743 * 3) < current_time # 2629743 * 3 -- 3 month
outdated_count += 1
a << item.url
end
end
@outdated = outdated_count
end
def size
@size
end
def outdated
@outdated
end
end
end

View File

@ -0,0 +1,18 @@
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