clarion 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Dockerfile +13 -0
- data/Gemfile +2 -0
- data/app/public/register.js +33 -11
- data/app/public/sign.js +12 -3
- data/app/views/authn.erb +8 -0
- data/app/views/layout.erb +2 -2
- data/app/views/register.erb +18 -0
- data/lib/clarion/app.rb +8 -5
- data/lib/clarion/key.rb +2 -2
- data/lib/clarion/version.rb +1 -1
- metadata +2 -2
- data/Gemfile.lock +0 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 587de9691a8ad2c343fb006830a7ad625489e1dafe3470a7b9f69797db777ab7
|
4
|
+
data.tar.gz: a2cc0b81450d83f3c581e0de7186fe6ff95b6cac6e3c7272d89b0e58098f5a28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39fb7f981bf9738f9675b5116f0e1a62a793d280c634e416887c8be9f19bc1d5d0596689d194ac189ab137352e8804d1230afeab6ebabfe77f02f6d4c741d3ee
|
7
|
+
data.tar.gz: 65fee6e98b981f03d3e1abff530f5b92c90975c4beda98f8bec440773376a551fb3eab9ce1e9e1bb40e0c38cc745fa8a2c63237d12d3efef35b45046fe562183
|
data/.gitignore
CHANGED
data/Dockerfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
FROM sorah/ruby:2.4
|
2
|
+
|
3
|
+
EXPOSE 8080
|
4
|
+
|
5
|
+
RUN mkdir -p /app /app/tmp /app/lib/clarion
|
6
|
+
|
7
|
+
COPY Gemfile* /app/
|
8
|
+
COPY *.gemspec /app/
|
9
|
+
COPY lib/clarion/version.rb /app/lib/clarion/version.rb
|
10
|
+
RUN cd /app && bundle install -j4 --deployment --without 'development test'
|
11
|
+
|
12
|
+
WORKDIR /app
|
13
|
+
CMD ["bundle", "exec", "puma", "-w", "2", "-t", "4:16", "-p", "8080"]
|
data/Gemfile
CHANGED
data/app/public/register.js
CHANGED
@@ -17,6 +17,7 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
17
17
|
let state = processionElem.attributes['data-state'].value;
|
18
18
|
let callbackUrl = processionElem.attributes['data-callback'].value;
|
19
19
|
|
20
|
+
var u2fResponse;
|
20
21
|
|
21
22
|
let processCallback = (json) => {
|
22
23
|
processionElem.className = 'procession_ok';
|
@@ -37,18 +38,13 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
37
38
|
}
|
38
39
|
}
|
39
40
|
|
40
|
-
let
|
41
|
-
console.log(response);
|
42
|
-
|
43
|
-
if (response.errorCode) {
|
44
|
-
processionElem.className = 'procession_error';
|
45
|
-
return;
|
46
|
-
}
|
41
|
+
let submitKey = () => {
|
47
42
|
processionElem.className = 'procession_contact';
|
48
43
|
|
49
44
|
let payload = JSON.stringify({
|
50
45
|
reg_id: regId,
|
51
|
-
response: JSON.stringify(
|
46
|
+
response: JSON.stringify(u2fResponse),
|
47
|
+
name: document.getElementById("key_name").value,
|
52
48
|
});
|
53
49
|
|
54
50
|
let handleError = (err) => {
|
@@ -72,10 +68,36 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
72
68
|
});
|
73
69
|
}).catch(handleError);
|
74
70
|
};
|
71
|
+
document.getElementById("key_name_form").addEventListener("submit", (e) => {
|
72
|
+
e.preventDefault();
|
73
|
+
if (u2fResponse) submitKey();
|
74
|
+
});
|
75
|
+
|
76
|
+
let u2fCallback = (response) => {
|
77
|
+
console.log(response);
|
78
|
+
|
79
|
+
if (response.errorCode == window.u2f.ErrorCodes.TIMEOUT) {
|
80
|
+
processionElem.className = 'procession_timeout';
|
81
|
+
return;
|
82
|
+
} else if (response.errorCode) {
|
83
|
+
processionElem.className = 'procession_error';
|
84
|
+
return;
|
85
|
+
}
|
86
|
+
u2fResponse = response;
|
87
|
+
processionElem.className = 'procession_edit';
|
88
|
+
document.getElementById("key_name").focus();
|
89
|
+
};
|
90
|
+
|
91
|
+
let startRequest = () => {
|
92
|
+
processionElem.className = 'procession_wait';
|
93
|
+
window.u2f.register(appId, requests, [], u2fCallback);
|
94
|
+
};
|
95
|
+
|
96
|
+
document.getElementById("retry_button").addEventListener("click", (e) => {
|
97
|
+
startRequest();
|
98
|
+
});
|
75
99
|
|
76
|
-
|
77
|
-
console.log(requests);
|
78
|
-
window.u2f.register(appId, requests, [], cb, 300000);
|
100
|
+
startRequest();
|
79
101
|
});
|
80
102
|
|
81
103
|
|
data/app/public/sign.js
CHANGED
@@ -26,7 +26,10 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
26
26
|
let cb = (response) => {
|
27
27
|
console.log(response);
|
28
28
|
|
29
|
-
if (response.errorCode) {
|
29
|
+
if (response.errorCode == window.u2f.ErrorCodes.TIMEOUT) {
|
30
|
+
processionElem.className = 'procession_timeout';
|
31
|
+
return;
|
32
|
+
} else if (response.errorCode) {
|
30
33
|
processionElem.className = 'procession_error';
|
31
34
|
return;
|
32
35
|
}
|
@@ -59,8 +62,14 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
59
62
|
}).catch(handleError);
|
60
63
|
};
|
61
64
|
|
62
|
-
|
63
|
-
|
65
|
+
let startRequest = () => {
|
66
|
+
processionElem.className = 'procession_wait';
|
67
|
+
window.u2f.sign(appId, challenge, requests, cb);
|
68
|
+
};
|
69
|
+
document.getElementById("retry_button").addEventListener("click", (e) => {
|
70
|
+
startRequest();
|
71
|
+
});
|
72
|
+
startRequest();
|
64
73
|
});
|
65
74
|
|
66
75
|
|
data/app/views/authn.erb
CHANGED
@@ -20,6 +20,10 @@
|
|
20
20
|
#procession.procession_error > div.procession_error {
|
21
21
|
display: block;
|
22
22
|
}
|
23
|
+
#procession.procession_timeout > div.procession_timeout {
|
24
|
+
display: block;
|
25
|
+
}
|
26
|
+
|
23
27
|
</style>
|
24
28
|
|
25
29
|
<p class='center'><strong>U2F 2FA <%- if @authn.name -%> for <%= @authn.name %><%- end -%></strong></p>
|
@@ -42,6 +46,10 @@
|
|
42
46
|
<div class="procession_error">
|
43
47
|
<p>Error: Reload and try again?</p>
|
44
48
|
</div>
|
49
|
+
<div class="procession_timeout">
|
50
|
+
<p>Timed out...</p>
|
51
|
+
<p><button id="retry_button">Try again</button></p>
|
52
|
+
</div>
|
45
53
|
</div>
|
46
54
|
<%- if @authn.comment -%>
|
47
55
|
<p><small><%= @authn.comment %></small></p>
|
data/app/views/layout.erb
CHANGED
@@ -76,14 +76,14 @@
|
|
76
76
|
-webkit-box-sizing: border-box;
|
77
77
|
box-sizing: border-box;
|
78
78
|
|
79
|
-
|
80
|
-
padding: 6px 4px;
|
79
|
+
padding: 8px 4px;
|
81
80
|
|
82
81
|
border: 1px solid #e9e9e9;
|
83
82
|
border-radius: 3px;
|
84
83
|
}
|
85
84
|
|
86
85
|
input[type="submit"], button {
|
86
|
+
font-size: 16px;
|
87
87
|
background-color: #337AB7;
|
88
88
|
color: white;
|
89
89
|
}
|
data/app/views/register.erb
CHANGED
@@ -11,6 +11,9 @@
|
|
11
11
|
#procession.procession_wait > div.procession_wait {
|
12
12
|
display: block;
|
13
13
|
}
|
14
|
+
#procession.procession_edit > div.procession_edit {
|
15
|
+
display: block;
|
16
|
+
}
|
14
17
|
#procession.procession_contact > div.procession_contact {
|
15
18
|
display: block;
|
16
19
|
}
|
@@ -20,6 +23,9 @@
|
|
20
23
|
#procession.procession_error > div.procession_error {
|
21
24
|
display: block;
|
22
25
|
}
|
26
|
+
#procession.procession_timeout > div.procession_timeout {
|
27
|
+
display: block;
|
28
|
+
}
|
23
29
|
</style>
|
24
30
|
|
25
31
|
<p><strong>U2F key registration<%- if @name -%> for <%= @name %><%- end -%></strong></p>
|
@@ -37,6 +43,13 @@
|
|
37
43
|
<div class="procession_wait">
|
38
44
|
<p>Insert and tap your security key.</p>
|
39
45
|
</div>
|
46
|
+
<div class="procession_edit">
|
47
|
+
<p>Security key recognized:</p>
|
48
|
+
<form id="key_name_form">
|
49
|
+
<p><input type="text" id="key_name" placeholder="Name your key" required></p>
|
50
|
+
<p><input type="submit" value="Save"></p>
|
51
|
+
</form>
|
52
|
+
</div>
|
40
53
|
<div class="procession_contact">
|
41
54
|
<p>Contacting...</p>
|
42
55
|
</div>
|
@@ -46,7 +59,12 @@
|
|
46
59
|
<div class="procession_error">
|
47
60
|
<p>Error: try again from the previous page?</p>
|
48
61
|
</div>
|
62
|
+
<div class="procession_timeout">
|
63
|
+
<p>Timed out...</p>
|
64
|
+
<p><button id="retry_button">Try again</button></p>
|
65
|
+
</div>
|
49
66
|
</div>
|
67
|
+
|
50
68
|
<%- if @comment -%>
|
51
69
|
<p><small><%= @comment %></small></p>
|
52
70
|
<%- end -%>
|
data/lib/clarion/app.rb
CHANGED
@@ -127,11 +127,13 @@ module Clarion
|
|
127
127
|
@reg_id = SecureRandom.urlsafe_base64(12)
|
128
128
|
registrator = Registrator.new(u2f, counter)
|
129
129
|
@app_id, @requests = registrator.request
|
130
|
-
session[:
|
131
|
-
session[:
|
130
|
+
session[:regis] ||= []
|
131
|
+
session[:regis] << {
|
132
|
+
id: @reg_id,
|
132
133
|
challenges: @requests.map(&:challenge),
|
133
134
|
key: public_key.to_der,
|
134
135
|
}
|
136
|
+
session[:regis].shift(session[:regis].size - 4) if session[:regis].size > 4
|
135
137
|
|
136
138
|
@callback = params[:callback]
|
137
139
|
@state = params[:state]
|
@@ -150,8 +152,8 @@ module Clarion
|
|
150
152
|
halt 400, '{"error": "Missing params"}'
|
151
153
|
end
|
152
154
|
|
153
|
-
session[:
|
154
|
-
reg = session[:
|
155
|
+
session[:regis] ||= []
|
156
|
+
reg = session[:regis].find { |_| _[:id] == data[:reg_id] }
|
155
157
|
unless reg && reg[:challenges] && reg[:key]
|
156
158
|
halt 400, '{"error": "Invalid :reg"}'
|
157
159
|
end
|
@@ -164,8 +166,9 @@ module Clarion
|
|
164
166
|
|
165
167
|
registrator = Registrator.new(u2f, counter)
|
166
168
|
key = registrator.register!(reg[:challenges], data[:response])
|
169
|
+
key.name = data[:name]
|
167
170
|
|
168
|
-
session[:
|
171
|
+
session[:regis].reject! { |_| _[:id] == data[:reg_id] }
|
169
172
|
|
170
173
|
{ok: true, encrypted_key: key.to_encrypted_json(public_key, :all)}.to_json
|
171
174
|
end
|
data/lib/clarion/key.rb
CHANGED
data/lib/clarion/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clarion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sorah Fukumori
|
@@ -132,8 +132,8 @@ files:
|
|
132
132
|
- ".gitignore"
|
133
133
|
- ".rspec"
|
134
134
|
- ".travis.yml"
|
135
|
+
- Dockerfile
|
135
136
|
- Gemfile
|
136
|
-
- Gemfile.lock
|
137
137
|
- LICENSE.txt
|
138
138
|
- README.md
|
139
139
|
- Rakefile
|
data/Gemfile.lock
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
clarion (0.1.0)
|
5
|
-
aws-sdk-dynamodb
|
6
|
-
aws-sdk-s3
|
7
|
-
erubis
|
8
|
-
sinatra
|
9
|
-
u2f
|
10
|
-
|
11
|
-
GEM
|
12
|
-
remote: https://rubygems.org/
|
13
|
-
specs:
|
14
|
-
aws-partitions (1.45.0)
|
15
|
-
aws-sdk-core (3.11.0)
|
16
|
-
aws-partitions (~> 1.0)
|
17
|
-
aws-sigv4 (~> 1.0)
|
18
|
-
jmespath (~> 1.0)
|
19
|
-
aws-sdk-dynamodb (1.3.0)
|
20
|
-
aws-sdk-core (~> 3)
|
21
|
-
aws-sigv4 (~> 1.0)
|
22
|
-
aws-sdk-kms (1.3.0)
|
23
|
-
aws-sdk-core (~> 3)
|
24
|
-
aws-sigv4 (~> 1.0)
|
25
|
-
aws-sdk-s3 (1.8.0)
|
26
|
-
aws-sdk-core (~> 3)
|
27
|
-
aws-sdk-kms (~> 1)
|
28
|
-
aws-sigv4 (~> 1.0)
|
29
|
-
aws-sigv4 (1.0.2)
|
30
|
-
diff-lcs (1.3)
|
31
|
-
erubis (2.7.0)
|
32
|
-
jmespath (1.3.1)
|
33
|
-
mustermann (1.0.1)
|
34
|
-
rack (2.0.3)
|
35
|
-
rack-protection (2.0.0)
|
36
|
-
rack
|
37
|
-
rake (12.3.0)
|
38
|
-
rspec (3.7.0)
|
39
|
-
rspec-core (~> 3.7.0)
|
40
|
-
rspec-expectations (~> 3.7.0)
|
41
|
-
rspec-mocks (~> 3.7.0)
|
42
|
-
rspec-core (3.7.0)
|
43
|
-
rspec-support (~> 3.7.0)
|
44
|
-
rspec-expectations (3.7.0)
|
45
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
46
|
-
rspec-support (~> 3.7.0)
|
47
|
-
rspec-mocks (3.7.0)
|
48
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
49
|
-
rspec-support (~> 3.7.0)
|
50
|
-
rspec-support (3.7.0)
|
51
|
-
sinatra (2.0.0)
|
52
|
-
mustermann (~> 1.0)
|
53
|
-
rack (~> 2.0)
|
54
|
-
rack-protection (= 2.0.0)
|
55
|
-
tilt (~> 2.0)
|
56
|
-
tilt (2.0.8)
|
57
|
-
u2f (1.0.0)
|
58
|
-
|
59
|
-
PLATFORMS
|
60
|
-
ruby
|
61
|
-
|
62
|
-
DEPENDENCIES
|
63
|
-
bundler
|
64
|
-
clarion!
|
65
|
-
rake
|
66
|
-
rspec (~> 3.0)
|
67
|
-
|
68
|
-
BUNDLED WITH
|
69
|
-
1.16.0
|