adamantite 0.0.6 → 0.0.7
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/lib/adamantite.rb +99 -70
- data/lib/base/adamantite.rb +43 -3
- data/lib/file_utils/adamantite_file_utils.rb +12 -1
- data/lib/gui/form/license_form.rb +49 -0
- data/lib/gui/request/set_master_license_key_request.rb +21 -0
- data/lib/gui/screen/login_screen.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c3fa0d2056a2b58771a3d36c7e7a93d6d1ef280778d55b27aa6d43662746e50
|
4
|
+
data.tar.gz: 631ccf39897ad7f96fa4ffec126a9cf2a1f7c50e30e7cd74fb772a3de6662473
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1c46782cd2252a23a3b1017683c1202ce7ba551f71425a93d7901440da1413eeb89c48bd116507edc46be6d147d6d3ab47ba2be0af1adb334d40a1ba97d4950
|
7
|
+
data.tar.gz: 5a5d5b8a5b3e7e89c3c3a59b69e21d4ac5bed6899da9ff572b5940b8353cedfdea6354192201469e31355dee3059f6a5643128a68b96626b9a0c5a42d5a1ed26
|
data/lib/adamantite.rb
CHANGED
@@ -1,25 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'glimmer-dsl-libui'
|
4
|
-
require 'bcrypt'
|
5
|
-
require 'openssl'
|
6
|
-
require 'base64'
|
7
|
-
require 'json'
|
8
|
-
require 'io/console'
|
9
4
|
|
10
5
|
require 'fileutils'
|
11
6
|
require 'file_utils/adamantite_file_utils'
|
12
7
|
require 'base/adamantite'
|
13
8
|
require 'base/password_object'
|
14
|
-
require 'gui/screen/login_screen'
|
15
9
|
require 'gui/screen/copy_screen'
|
16
|
-
require 'gui/screen/
|
10
|
+
require 'gui/screen/login_screen'
|
17
11
|
require 'gui/screen/set_master_password_screen'
|
12
|
+
require 'gui/screen/show_screen'
|
18
13
|
require 'gui/screen/update_master_password_screen'
|
19
14
|
require 'gui/request/login_request'
|
20
15
|
require 'gui/request/add_password_request'
|
21
16
|
require 'gui/request/update_master_password_request'
|
17
|
+
require 'gui/request/set_master_license_key_request'
|
22
18
|
require 'gui/request/set_master_password_request'
|
19
|
+
require 'gui/form/license_form'
|
23
20
|
require 'gui/form/password_object_form_window'
|
24
21
|
|
25
22
|
module Adamantite
|
@@ -51,83 +48,115 @@ module Adamantite
|
|
51
48
|
@add_password_request = GUI::Request::AddPasswordRequest.new(@master_password, @master_password_salt)
|
52
49
|
end
|
53
50
|
|
51
|
+
menu('About') do
|
52
|
+
menu_item('Software Information') do
|
53
|
+
on_clicked do
|
54
|
+
msg_box('For more information please visit adamantitehomepage.com')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
menu_item('Author') do
|
58
|
+
on_clicked do
|
59
|
+
msg_box('Jake Bruemmer - https://x.com/jakebruemmer')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
54
64
|
body do
|
55
|
-
window('Adamantite', 800, 400) do
|
65
|
+
window('Adamantite', 800, 400, true) do
|
56
66
|
margined true
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
67
|
+
if @adamantite.licensed?
|
68
|
+
vertical_box do
|
69
|
+
table do
|
70
|
+
text_column('Title')
|
71
|
+
text_column('Username')
|
72
|
+
button_column('Edit') do
|
73
|
+
on_clicked do |row|
|
74
|
+
on_save = lambda do |password_object|
|
75
|
+
stored_password = []
|
76
|
+
stored_password << password_object.website_title
|
77
|
+
stored_password << password_object.username
|
78
|
+
stored_password << 'Edit'
|
79
|
+
stored_password << 'Copy'
|
80
|
+
stored_password << 'Show'
|
81
|
+
stored_password << 'Delete'
|
82
|
+
@stored_passwords[password_object.row_index] = stored_password
|
83
|
+
adamantite_stored_password = {
|
84
|
+
'dir_name': password_object.dir_name,
|
85
|
+
'website_title': password_object.website_title,
|
86
|
+
'username': @adamantite.retrieve_password_info(password_object.dir_name, 'username')
|
87
|
+
}
|
88
|
+
@adamantite.stored_passwords[password_object.row_index] = adamantite_stored_password
|
89
|
+
end
|
90
|
+
website_title = @stored_passwords[row][0]
|
91
|
+
username = @stored_passwords[row][1]
|
92
|
+
dir_name = @adamantite.stored_passwords[row][:dir_name]
|
93
|
+
password = @adamantite.retrieve_password_info(dir_name, 'password')
|
94
|
+
password_object = Base::PasswordObject.new(website_title, username, password, password, row, dir_name)
|
95
|
+
password_object_form_window(adamantite: @adamantite, on_save: on_save, password_object: password_object).show
|
79
96
|
end
|
80
|
-
website_title = @stored_passwords[row][0]
|
81
|
-
username = @stored_passwords[row][1]
|
82
|
-
dir_name = @adamantite.stored_passwords[row][:dir_name]
|
83
|
-
password = @adamantite.retrieve_password_info(dir_name, 'password')
|
84
|
-
password_object = Base::PasswordObject.new(website_title, username, password, password, row, dir_name)
|
85
|
-
password_object_form_window(adamantite: @adamantite, on_save: on_save, password_object: password_object).show
|
86
97
|
end
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
98
|
+
button_column('Copy') do
|
99
|
+
on_clicked do |row|
|
100
|
+
IO.popen('pbcopy', 'w') do |f|
|
101
|
+
dir_name = @adamantite.stored_passwords[row][:dir_name]
|
102
|
+
f << @adamantite.retrieve_password_info(dir_name, 'password')
|
103
|
+
end
|
104
|
+
copy_screen(password_title: @stored_passwords[row].first).show
|
105
|
+
end
|
106
|
+
end
|
107
|
+
button_column('Show') do
|
108
|
+
on_clicked do |row|
|
91
109
|
dir_name = @adamantite.stored_passwords[row][:dir_name]
|
92
|
-
|
110
|
+
show_screen(password: @adamantite.retrieve_password_info(dir_name, 'password')).show
|
93
111
|
end
|
94
|
-
copy_screen(password_title: @stored_passwords[row].first).show
|
95
112
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
113
|
+
button_column('Delete') do
|
114
|
+
on_clicked do |row|
|
115
|
+
@adamantite.delete_password(@adamantite.stored_passwords[row][:dir_name])
|
116
|
+
@stored_passwords.delete_at(row)
|
117
|
+
end
|
101
118
|
end
|
119
|
+
cell_rows <=> [self, :stored_passwords]
|
102
120
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
121
|
+
horizontal_box do
|
122
|
+
button('Add Password') do
|
123
|
+
on_clicked do
|
124
|
+
on_save = lambda do |password_object|
|
125
|
+
stored_password = []
|
126
|
+
stored_password << password_object.website_title
|
127
|
+
stored_password << password_object.username
|
128
|
+
stored_password << 'Edit'
|
129
|
+
stored_password << 'Copy'
|
130
|
+
stored_password << 'Show'
|
131
|
+
stored_password << 'Delete'
|
132
|
+
@stored_passwords << stored_password
|
133
|
+
end
|
134
|
+
password_object_form_window(adamantite: @adamantite, on_save: on_save).show
|
135
|
+
end
|
107
136
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
button('Add Password') do
|
113
|
-
on_clicked do
|
114
|
-
on_save = lambda do |password_object|
|
115
|
-
stored_password = []
|
116
|
-
stored_password << password_object.website_title
|
117
|
-
stored_password << password_object.username
|
118
|
-
stored_password << 'Edit'
|
119
|
-
stored_password << 'Copy'
|
120
|
-
stored_password << 'Show'
|
121
|
-
stored_password << 'Delete'
|
122
|
-
@stored_passwords << stored_password
|
137
|
+
button('Update Master Password') do
|
138
|
+
on_clicked do
|
139
|
+
update_master_password_request = GUI::Request::UpdateMasterPasswordRequest.new(@adamantite)
|
140
|
+
update_master_password_screen(update_master_password_request: update_master_password_request).show
|
123
141
|
end
|
124
|
-
password_object_form_window(adamantite: @adamantite, on_save: on_save).show
|
125
142
|
end
|
126
143
|
end
|
127
|
-
|
144
|
+
horizontal_box do
|
145
|
+
label('This is valid Adamantite installation.')
|
146
|
+
end
|
147
|
+
end
|
148
|
+
else
|
149
|
+
vertical_box do
|
150
|
+
license_label = <<-TEXT
|
151
|
+
No license detected. Please add one to start using Adamantite.
|
152
|
+
If you need one, visit https://jakebruemmer.github.io/adamantite-info/
|
153
|
+
for more information.
|
154
|
+
TEXT
|
155
|
+
label(license_label)
|
156
|
+
button('Add License Info') do
|
128
157
|
on_clicked do
|
129
|
-
|
130
|
-
|
158
|
+
set_master_license_key_request = GUI::Request::SetMasterLicenseKeyRequest.new(@adamantite)
|
159
|
+
license_form(set_master_license_key_request: set_master_license_key_request).show
|
131
160
|
end
|
132
161
|
end
|
133
162
|
end
|
data/lib/base/adamantite.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'file_utils/adamantite_file_utils'
|
4
|
-
require 'rbnacl'
|
5
3
|
require 'base64'
|
4
|
+
require 'httparty'
|
5
|
+
require 'rbnacl'
|
6
|
+
|
7
|
+
require 'file_utils/adamantite_file_utils'
|
6
8
|
|
7
9
|
module Adamantite
|
8
10
|
module Base
|
9
11
|
class Adamantite
|
10
12
|
include AdamantiteFileUtils
|
11
13
|
|
12
|
-
attr_reader :authenticated, :master_password, :master_password_salt, :stored_passwords
|
14
|
+
attr_reader :authenticated, :master_password, :master_password_salt, :stored_passwords,
|
15
|
+
:master_license_key
|
13
16
|
|
14
17
|
OPSLIMIT = 2**20
|
15
18
|
MEMLIMIT = 2**24
|
16
19
|
DIGEST_SIZE = 32
|
20
|
+
LICENSE_ACTIVATION_URL = 'https://api.keygen.sh/v1/accounts/c8f50eb9-eb87-4431-a680-d8f181441ef8/licenses/actions/validate-key'
|
17
21
|
|
18
22
|
def initialize(master_password)
|
19
23
|
@master_password = master_password
|
@@ -33,6 +37,7 @@ module Adamantite
|
|
33
37
|
@master_password_salt = master_password_salt
|
34
38
|
@vault = rbnacl_box(@master_vault_key)
|
35
39
|
update_stored_passwords!
|
40
|
+
read_license_key! if has_license_key?
|
36
41
|
true
|
37
42
|
rescue RbNaCl::CryptoError
|
38
43
|
false
|
@@ -42,6 +47,31 @@ module Adamantite
|
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
50
|
+
def activate_license!(master_license_key)
|
51
|
+
return unless authenticated?
|
52
|
+
|
53
|
+
headers = {
|
54
|
+
'Content-Type': 'application/vnd.api+json',
|
55
|
+
'Accept': 'application/vnd.api+json'
|
56
|
+
}
|
57
|
+
body = {
|
58
|
+
'meta': {
|
59
|
+
'key': master_license_key,
|
60
|
+
'scope': {
|
61
|
+
'product': 'bb6542ab-7d74-44d0-b4f5-1fbc39cdeb99'
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
res = HTTParty.post(LICENSE_ACTIVATION_URL, headers: headers, body: body.to_json)
|
66
|
+
|
67
|
+
if res['meta']['valid']
|
68
|
+
@master_license_key = master_license_key
|
69
|
+
write_to_file(password_file('master_license_key'), @vault.encrypt(@master_license_key), true)
|
70
|
+
true
|
71
|
+
end
|
72
|
+
licensed?
|
73
|
+
end
|
74
|
+
|
45
75
|
def save_password(website_title, username, password, password_confirmation)
|
46
76
|
return unless password == password_confirmation && authenticated?
|
47
77
|
|
@@ -130,6 +160,10 @@ module Adamantite
|
|
130
160
|
end
|
131
161
|
end
|
132
162
|
|
163
|
+
def licensed?
|
164
|
+
!@master_license_key.nil?
|
165
|
+
end
|
166
|
+
|
133
167
|
private
|
134
168
|
|
135
169
|
def rbnacl_box(key)
|
@@ -153,6 +187,12 @@ module Adamantite
|
|
153
187
|
write_to_file(password_file('master_password_salt'), master_password_salt, true)
|
154
188
|
write_to_file(password_file('master_encrypted_vault_key'), master_vault_key, true)
|
155
189
|
end
|
190
|
+
|
191
|
+
def read_license_key!
|
192
|
+
return unless authenticated?
|
193
|
+
|
194
|
+
@master_license_key = @vault.decrypt(get_license_key)
|
195
|
+
end
|
156
196
|
end
|
157
197
|
end
|
158
198
|
end
|
@@ -92,13 +92,24 @@ module Adamantite
|
|
92
92
|
File.open(pw_file('master_encrypted_vault_key'), 'rb', &:read)
|
93
93
|
end
|
94
94
|
|
95
|
+
def get_license_key
|
96
|
+
File.open(pw_file('master_license_key'), 'rb', &:read)
|
97
|
+
end
|
98
|
+
|
95
99
|
def get_stored_pws
|
96
|
-
excluded_filenames = [
|
100
|
+
excluded_filenames = [
|
101
|
+
'.', '..', 'master_password_hash', 'master_password_salt', 'master_encrypted_vault_key',
|
102
|
+
'master_license_key'
|
103
|
+
]
|
97
104
|
Dir.entries(pwmanager_dir).filter { |f| !excluded_filenames.include?(f) }
|
98
105
|
end
|
99
106
|
|
100
107
|
def master_password_exists?
|
101
108
|
pw_file_exists?('master_encrypted_vault_key') && pw_file_exists?('master_password_salt')
|
102
109
|
end
|
110
|
+
|
111
|
+
def has_license_key?
|
112
|
+
pw_file_exists?('master_license_key')
|
113
|
+
end
|
103
114
|
end
|
104
115
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Adamantite
|
4
|
+
module GUI
|
5
|
+
module Screen
|
6
|
+
class LicenseForm
|
7
|
+
include Glimmer::LibUI::CustomWindow
|
8
|
+
|
9
|
+
option :set_master_license_key_request
|
10
|
+
|
11
|
+
body do
|
12
|
+
window('Adamantite - Set License', 600, 150) do
|
13
|
+
margined true
|
14
|
+
vertical_box do
|
15
|
+
horizontal_box do
|
16
|
+
form do
|
17
|
+
entry do
|
18
|
+
label 'License - please include hyphens'
|
19
|
+
text <=> [set_master_license_key_request, :master_license_key]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
horizontal_box do
|
24
|
+
button('Set License') do
|
25
|
+
on_clicked do
|
26
|
+
set_master_license_key_request.activate_license!
|
27
|
+
if set_master_license_key_request.master_license_key_activated
|
28
|
+
body_root.destroy
|
29
|
+
::LibUI.quit
|
30
|
+
else
|
31
|
+
set_master_license_key_request.master_license_key = ''
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
horizontal_box do
|
37
|
+
info = <<-TEXT
|
38
|
+
This window will close if your license is entered successfully. Restart
|
39
|
+
Adamantite to begin using it.
|
40
|
+
TEXT
|
41
|
+
label(info)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Adamantite
|
4
|
+
module GUI
|
5
|
+
module Request
|
6
|
+
class SetMasterLicenseKeyRequest
|
7
|
+
attr_accessor :adamantite, :master_license_key, :master_license_key_activated
|
8
|
+
|
9
|
+
def initialize(adamantite)
|
10
|
+
@adamantite = adamantite
|
11
|
+
@master_license_key_activated = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def activate_license!
|
15
|
+
@adamantite.activate_license!(master_license_key)
|
16
|
+
@master_license_key_activated = true if @adamantite.licensed?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adamantite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jake Bruemmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A local password manager written in Ruby.
|
14
14
|
email: jakebruemmer@gmail.com
|
@@ -23,9 +23,11 @@ files:
|
|
23
23
|
- lib/base/editor/password_object_editor.rb
|
24
24
|
- lib/base/password_object.rb
|
25
25
|
- lib/file_utils/adamantite_file_utils.rb
|
26
|
+
- lib/gui/form/license_form.rb
|
26
27
|
- lib/gui/form/password_object_form_window.rb
|
27
28
|
- lib/gui/request/add_password_request.rb
|
28
29
|
- lib/gui/request/login_request.rb
|
30
|
+
- lib/gui/request/set_master_license_key_request.rb
|
29
31
|
- lib/gui/request/set_master_password_request.rb
|
30
32
|
- lib/gui/request/update_master_password_request.rb
|
31
33
|
- lib/gui/screen/copy_screen.rb
|