2pass 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/2pass.gemspec +2 -0
- data/bin/2pass +29 -9
- data/lib/2pass/version.rb +1 -1
- data/lib/2pass.rb +59 -46
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbffa6c36a23a40c4ec93bc9f0277cf43d3e2388b61459a89aad0bb89458451e
|
4
|
+
data.tar.gz: 5ab72d0c03fb7b718aaec180fdb530755ad69394acb6f808918b978044174e47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f0bce6612b408712dac5d313331b8721703f89a4a695ff0d7fd23076d6fcaf7bd2fdec67bdf75c1504f98d59dd400fe04bfa70f729847e234b13ab114d03eb6
|
7
|
+
data.tar.gz: 06d625e2325531c59eff3d197eab64ed3265de9c93ab4046ff39c81f7057ceecb3c2cd640cccc70f9073da3975a3eac9e14fdbaf185242ff4141a0ea1bc6a517
|
data/2pass.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = ["2pass"]
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.required_ruby_version = ">= 3.3"
|
22
|
+
|
21
23
|
spec.add_development_dependency "bundler", "~> 2.0"
|
22
24
|
spec.add_development_dependency "rake", "~> 13.0"
|
23
25
|
spec.add_development_dependency "minitest", "~> 5.0"
|
data/bin/2pass
CHANGED
@@ -7,7 +7,8 @@ def help_message
|
|
7
7
|
Usage:
|
8
8
|
2pass add <vault_name> <id> <value> - Add new secret
|
9
9
|
2pass get <vault_name> <id> - Get content by ID from the specified vault
|
10
|
-
2pass list <vault_name> - List the content of the specified vault
|
10
|
+
2pass list <vault_name> - List the content of the specified vault as key-value pairs
|
11
|
+
2pass list <vault_name> --json - List the content of the specified vault as JSON
|
11
12
|
2pass link <vault_name> <target_path> - Create a symlink for an existing vault. Useful when the vault is stored in a synced place (iCloud, Dropbox, etc.)
|
12
13
|
2pass -h - Display this help message
|
13
14
|
HELP
|
@@ -20,6 +21,15 @@ OptionParser.new do |opts|
|
|
20
21
|
opts.on("-h", "--help", "Display this help message") do
|
21
22
|
options[:help] = true
|
22
23
|
end
|
24
|
+
opts.on("-v", "--version", "Display the version") do
|
25
|
+
options[:version] = true
|
26
|
+
end
|
27
|
+
opts.on("-f", "--format", "Specify output format (e.g., json)") do |format|
|
28
|
+
options[:format] = format == "json" ? :json : :text
|
29
|
+
end
|
30
|
+
opts.on("--json", "Use JSON output format (same as -f json)") do
|
31
|
+
options[:format] = :json
|
32
|
+
end
|
23
33
|
end.parse!
|
24
34
|
|
25
35
|
if options[:help]
|
@@ -27,6 +37,11 @@ if options[:help]
|
|
27
37
|
exit
|
28
38
|
end
|
29
39
|
|
40
|
+
if options[:version]
|
41
|
+
puts TwoPass::VERSION
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
30
45
|
if ARGV.length < 2
|
31
46
|
help_message
|
32
47
|
exit(1)
|
@@ -35,30 +50,35 @@ end
|
|
35
50
|
command, vault_name, *args = ARGV
|
36
51
|
|
37
52
|
begin
|
38
|
-
case command
|
39
|
-
when
|
53
|
+
case command&.to_sym
|
54
|
+
when :get
|
40
55
|
if args.length < 1
|
41
56
|
help_message
|
42
57
|
exit(1)
|
43
58
|
end
|
44
59
|
id = args[0]
|
45
60
|
puts TwoPass.get_secret(vault_name, id)
|
46
|
-
when
|
61
|
+
when :add
|
47
62
|
if args.length != 2
|
48
63
|
help_message
|
49
64
|
exit(1)
|
50
65
|
end
|
51
66
|
TwoPass.add_secret(vault_name, args[0], args[1])
|
52
|
-
when
|
53
|
-
|
54
|
-
|
67
|
+
when :list
|
68
|
+
if options[:format] == :json
|
69
|
+
puts TwoPass.list_content(vault_name, format: :json)
|
70
|
+
else
|
71
|
+
puts TwoPass.list_content(vault_name)
|
72
|
+
end
|
73
|
+
exit(1)
|
74
|
+
when :link
|
55
75
|
if args.length < 1
|
56
76
|
help_message
|
57
77
|
exit(1)
|
58
78
|
end
|
59
79
|
target_path = args[0]
|
60
80
|
TwoPass.create_symlink(vault_name, target_path)
|
61
|
-
when
|
81
|
+
when :help
|
62
82
|
help_message
|
63
83
|
else
|
64
84
|
help_message
|
@@ -71,5 +91,5 @@ rescue => e
|
|
71
91
|
STDERR.puts e.backtrace
|
72
92
|
end
|
73
93
|
|
74
|
-
exit
|
94
|
+
exit(1)
|
75
95
|
end
|
data/lib/2pass/version.rb
CHANGED
data/lib/2pass.rb
CHANGED
@@ -9,61 +9,74 @@ require_relative "2pass/version"
|
|
9
9
|
module TwoPass
|
10
10
|
VAULT_DIR = "#{Dir.home}/.2pass"
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
class << self
|
13
|
+
def create_symlink(vault_name, target_path)
|
14
|
+
FileUtils.mkdir_p(VAULT_DIR)
|
15
|
+
symlink_path = "#{VAULT_DIR}/#{vault_name}.yml"
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
if File.exist?(symlink_path)
|
18
|
+
puts "Symlink already exists: #{symlink_path}"
|
19
|
+
else
|
20
|
+
File.symlink(target_path, symlink_path)
|
21
|
+
puts "Created symlink: #{symlink_path} -> #{target_path}"
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
def load_vault(vault_name)
|
26
|
+
file_path = "#{VAULT_DIR}/#{vault_name}.yml"
|
27
|
+
return [] unless File.exist?(file_path)
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
YAML.load_file(file_path, symbolize_names: true) || []
|
30
|
+
rescue Psych::SyntaxError => e
|
31
|
+
STDERR.puts "Error parsing YAML file: #{e.message}"
|
32
|
+
[]
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
def save_vault(vault_name, data)
|
36
|
+
FileUtils.mkdir_p(VAULT_DIR)
|
37
|
+
file_path = "#{VAULT_DIR}/#{vault_name}.yml"
|
38
|
+
File.write(file_path, YAML.dump(data))
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
def list_content(vault_name, format: :text)
|
42
|
+
vault = load_vault(vault_name)
|
43
|
+
if format == :text
|
44
|
+
vault
|
45
|
+
.map { |h| "#{h[:id]}=#{h[:value]}" }
|
46
|
+
.sort
|
47
|
+
.join("\n")
|
48
|
+
else
|
49
|
+
JSON.pretty_generate(
|
50
|
+
vault
|
51
|
+
.map { |hash| hash.slice(:id, :value) }
|
52
|
+
.sort_by { |hash| hash[:id] }
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
44
56
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
57
|
+
def add_secret(vault_name, id, value)
|
58
|
+
new_secret = {
|
59
|
+
id: id,
|
60
|
+
value: value,
|
61
|
+
uuid: SecureRandom.uuid
|
62
|
+
}
|
63
|
+
data = load_vault(vault_name)
|
64
|
+
existing_entry_id = data.find_index { |hash| hash[:id] == new_secret[:id] }
|
65
|
+
if existing_entry_id
|
66
|
+
raise "The secret already exists"
|
67
|
+
end
|
68
|
+
data << new_secret
|
69
|
+
save_vault(vault_name, data)
|
55
70
|
end
|
56
|
-
data << new_secret
|
57
|
-
save_vault(vault_name, data)
|
58
|
-
end
|
59
71
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
72
|
+
def get_secret(vault_name, id)
|
73
|
+
vault = load_vault(vault_name)
|
74
|
+
entry = vault.find { |hash| hash[:id] == id }
|
75
|
+
if entry
|
76
|
+
entry[:value]
|
77
|
+
else
|
78
|
+
raise "Entry not found"
|
79
|
+
end
|
67
80
|
end
|
68
81
|
end
|
69
82
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: 2pass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olivier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -99,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
99
|
requirements:
|
100
100
|
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: '
|
102
|
+
version: '3.3'
|
103
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
104
|
requirements:
|
105
105
|
- - ">="
|