clarion 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/public/sign.js +29 -0
- data/app/views/authn.erb +17 -4
- data/app/views/layout.erb +7 -1
- data/lib/clarion/app.rb +46 -9
- data/lib/clarion/authn.rb +21 -1
- data/lib/clarion/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9dc196ee5f2c8ed0672cd8ac94a7da79df64610526ba0590ee49a6a06e8a11f
|
4
|
+
data.tar.gz: c4c9253becb0aa8825b3f5c3e40826f0dba345d87f97fc5625b0b46b095ab625
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 599032ddf520cd979702ed6abb808c1340e7dc123d38754abdecda59c97f6508bbdcb88bcdc55a9899d7f4e41ae635fecf9e591ce1dcf55ea8e6b5d31302c3d2
|
7
|
+
data.tar.gz: 02a673769db0de5f84f51806c5ad130cbc278240c620bc8f35c3719b117819b63ec32fb10d9e2266809a4af51e07607e9440a1a4821185c31c0c1b459f6bb4e8
|
data/app/public/sign.js
CHANGED
@@ -18,9 +18,38 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
18
18
|
let requests = JSON.parse(processionElem.attributes['data-requests'].value);
|
19
19
|
let challenge = JSON.parse(processionElem.attributes['data-challenge'].value);
|
20
20
|
|
21
|
+
let requestCancel = (e) => {
|
22
|
+
if (e) e.preventDefault();
|
23
|
+
let payload = JSON.stringify({
|
24
|
+
req_id: reqId,
|
25
|
+
});
|
26
|
+
|
27
|
+
let handleError = (err) => {
|
28
|
+
console.log(err);
|
29
|
+
processionElem.className = 'procession_error';
|
30
|
+
};
|
31
|
+
|
32
|
+
fetch(`/ui/cancel/${authnId}`, {credentials: 'include', method: 'POST', body: payload}).then((resp) => {
|
33
|
+
console.log(resp);
|
34
|
+
if (!resp.ok) {
|
35
|
+
processionElem.className = 'procession_error';
|
36
|
+
return;
|
37
|
+
}
|
38
|
+
return resp.json().then((json) => {
|
39
|
+
console.log(json);
|
40
|
+
if (json.ok) {
|
41
|
+
processionElem.className = 'procession_cancel';
|
42
|
+
} else {
|
43
|
+
processionElem.className = 'procession_error';
|
44
|
+
}
|
45
|
+
});
|
46
|
+
}).catch(handleError);
|
47
|
+
};
|
48
|
+
document.getElementById("cancel_link").addEventListener("click", requestCancel);
|
21
49
|
|
22
50
|
let processCallback = (json) => {
|
23
51
|
processionElem.className = 'procession_ok';
|
52
|
+
if (window.opener) window.close();
|
24
53
|
}
|
25
54
|
|
26
55
|
let cb = (response) => {
|
data/app/views/authn.erb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
#procession > div {
|
3
3
|
display: none;
|
4
4
|
}
|
5
|
+
#procession > div.procession_always {
|
6
|
+
display: block;
|
7
|
+
}
|
5
8
|
#procession.procession_init > div.procession_init {
|
6
9
|
display: block;
|
7
10
|
}
|
@@ -20,13 +23,20 @@
|
|
20
23
|
#procession.procession_error > div.procession_error {
|
21
24
|
display: block;
|
22
25
|
}
|
26
|
+
#procession.procession_cancel > div.procession_cancel {
|
27
|
+
display: block;
|
28
|
+
}
|
23
29
|
#procession.procession_timeout > div.procession_timeout {
|
24
30
|
display: block;
|
25
31
|
}
|
26
32
|
|
27
33
|
</style>
|
28
34
|
|
29
|
-
<p class='center'><strong>U2F 2FA <%- if @authn.name -%> for <%= @authn.name %><%- end -%></strong
|
35
|
+
<p class='center'><strong>U2F 2FA <%- if @authn.name -%> for <%= @authn.name %><%- end -%></strong><br>
|
36
|
+
<%- if @authn.comment -%>
|
37
|
+
<small><%= @authn.comment %></small></p>
|
38
|
+
<%- end -%>
|
39
|
+
</p>
|
30
40
|
<div id="procession" class="procession_init" data-authn-id="<%= @authn.id %>" data-app-id="<%= @app_id %>" data-requests='<%= @requests.to_json %>' data-challenge='<%= @challenge.to_json %>' data-req-id='<%= @req_id %>'>
|
31
41
|
<div class="procession_init">
|
32
42
|
<p>Initializing...</p>
|
@@ -46,14 +56,17 @@
|
|
46
56
|
<div class="procession_error">
|
47
57
|
<p>Error: Reload and try again?</p>
|
48
58
|
</div>
|
59
|
+
<div class="procession_cancel">
|
60
|
+
<p>Cancelled: You may now close this page.</p>
|
61
|
+
</div>
|
49
62
|
<div class="procession_timeout">
|
50
63
|
<p>Timed out...</p>
|
51
64
|
<p><button id="retry_button">Try again</button></p>
|
52
65
|
</div>
|
66
|
+
<div class="procession_unsupported procession_error procession_wait procession_timeout">
|
67
|
+
<p class='text-muted right'><a href='#' id="cancel_link"><small>Cancel</small></a></p>
|
68
|
+
</div>
|
53
69
|
</div>
|
54
|
-
<%- if @authn.comment -%>
|
55
|
-
<p><small><%= @authn.comment %></small></p>
|
56
|
-
<%- end -%>
|
57
70
|
|
58
71
|
|
59
72
|
<script src="/sign.js"></script>
|
data/app/views/layout.erb
CHANGED
@@ -20,13 +20,19 @@
|
|
20
20
|
strong {
|
21
21
|
font-weight: bold;
|
22
22
|
}
|
23
|
-
small {
|
23
|
+
small, small * {
|
24
24
|
font-size: 12px;
|
25
25
|
}
|
26
26
|
|
27
27
|
.center {
|
28
28
|
text-align: center;
|
29
29
|
}
|
30
|
+
.right {
|
31
|
+
text-align: right;
|
32
|
+
}
|
33
|
+
.text-muted, .text-muted * {
|
34
|
+
color: #767676;
|
35
|
+
}
|
30
36
|
|
31
37
|
body {
|
32
38
|
text-align: center;
|
data/lib/clarion/app.rb
CHANGED
@@ -90,13 +90,12 @@ module Clarion
|
|
90
90
|
unless @authn
|
91
91
|
halt 404, "authn not found"
|
92
92
|
end
|
93
|
-
if @authn.verified?
|
94
|
-
halt 410, "Authn already processed"
|
95
|
-
end
|
96
93
|
if @authn.expired?
|
97
94
|
halt 410, "Authn expired"
|
98
95
|
end
|
99
|
-
|
96
|
+
if @authn.closed?
|
97
|
+
halt 410, "Authn already processed"
|
98
|
+
end
|
100
99
|
|
101
100
|
authenticator = Authenticator.new(@authn, u2f, counter, store)
|
102
101
|
@app_id, @requests, @challenge = authenticator.request
|
@@ -114,8 +113,14 @@ module Clarion
|
|
114
113
|
unless params[:name] && params[:callback] && params[:public_key]
|
115
114
|
halt 400, 'missing params'
|
116
115
|
end
|
117
|
-
if params[:callback].start_with?('js:')
|
118
|
-
|
116
|
+
if params[:callback].start_with?('js:')
|
117
|
+
unless conf.registration_allowed_url === params[:callback][3..-1]
|
118
|
+
halt 400, 'invalid callback'
|
119
|
+
end
|
120
|
+
else
|
121
|
+
unless conf.registration_allowed_url === params[:callback]
|
122
|
+
halt 400, 'invalid callback'
|
123
|
+
end
|
119
124
|
end
|
120
125
|
|
121
126
|
public_key = begin
|
@@ -173,9 +178,9 @@ module Clarion
|
|
173
178
|
{ok: true, name: key.name, encrypted_key: key.to_encrypted_json(public_key, :all)}.to_json
|
174
179
|
end
|
175
180
|
|
176
|
-
post '/ui/
|
181
|
+
post '/ui/cancel/:id' do
|
177
182
|
content_type :json
|
178
|
-
unless data[:req_id]
|
183
|
+
unless data[:req_id]
|
179
184
|
halt 400, '{"error": "missing params"}'
|
180
185
|
end
|
181
186
|
session[:reqs] ||= {}
|
@@ -191,12 +196,44 @@ module Clarion
|
|
191
196
|
unless @authn
|
192
197
|
halt 404, '{"error": "authn not found"}'
|
193
198
|
end
|
194
|
-
if @authn.
|
199
|
+
if @authn.expired?
|
200
|
+
halt 410, '{"error": "authn expired"}'
|
201
|
+
end
|
202
|
+
if @authn.closed?
|
195
203
|
halt 410, '{"error": "authn already processed"}'
|
196
204
|
end
|
205
|
+
|
206
|
+
@authn.cancel!
|
207
|
+
store.store_authn(@authn)
|
208
|
+
session[:reqs].delete data[:req_id]
|
209
|
+
|
210
|
+
'{"ok": true}'
|
211
|
+
end
|
212
|
+
|
213
|
+
post '/ui/verify/:id' do
|
214
|
+
content_type :json
|
215
|
+
unless data[:req_id] && data[:response]
|
216
|
+
halt 400, '{"error": "missing params"}'
|
217
|
+
end
|
218
|
+
session[:reqs] ||= {}
|
219
|
+
unless session[:reqs][data[:req_id]]
|
220
|
+
halt 400, '{"error": "invalid :req_id"}'
|
221
|
+
end
|
222
|
+
challenge = session[:reqs][data[:req_id]][:challenge]
|
223
|
+
unless challenge
|
224
|
+
halt 400, '{"error": "invalid :req_id"}'
|
225
|
+
end
|
226
|
+
|
227
|
+
@authn = store.find_authn(params[:id])
|
228
|
+
unless @authn
|
229
|
+
halt 404, '{"error": "authn not found"}'
|
230
|
+
end
|
197
231
|
if @authn.expired?
|
198
232
|
halt 410, '{"error": "authn expired"}'
|
199
233
|
end
|
234
|
+
if @authn.closed?
|
235
|
+
halt 410, '{"error": "authn already processed"}'
|
236
|
+
end
|
200
237
|
|
201
238
|
authenticator = Authenticator.new(@authn, u2f, counter, store)
|
202
239
|
|
data/lib/clarion/authn.rb
CHANGED
@@ -4,14 +4,19 @@ require 'clarion/key'
|
|
4
4
|
|
5
5
|
module Clarion
|
6
6
|
class Authn
|
7
|
-
STATUSES = %i(open verified)
|
7
|
+
STATUSES = %i(open cancelled verified expired)
|
8
8
|
|
9
9
|
class << self
|
10
10
|
def make(**kwargs)
|
11
11
|
kwargs.delete(:id)
|
12
|
+
kwargs.delete(:created_at)
|
13
|
+
kwargs.delete(:status)
|
14
|
+
kwargs.delete(:verified_at)
|
15
|
+
kwargs.delete(:verified_key)
|
12
16
|
new(
|
13
17
|
id: random_id,
|
14
18
|
created_at: Time.now,
|
19
|
+
status: :open,
|
15
20
|
**kwargs,
|
16
21
|
)
|
17
22
|
end
|
@@ -36,6 +41,8 @@ module Clarion
|
|
36
41
|
@expires_at = Time.xmlschema(@expires_at) if @expires_at && @expires_at.is_a?(String)
|
37
42
|
@verified_at = Time.xmlschema(@verified_at) if @verified_at && @verified_at.is_a?(String)
|
38
43
|
|
44
|
+
@status = :expired if expired?
|
45
|
+
|
39
46
|
raise ArgumentError, ":status not valid" unless STATUSES.include?(@status)
|
40
47
|
end
|
41
48
|
|
@@ -58,6 +65,14 @@ module Clarion
|
|
58
65
|
status == :verified
|
59
66
|
end
|
60
67
|
|
68
|
+
def cancelled?
|
69
|
+
status == :cancelled
|
70
|
+
end
|
71
|
+
|
72
|
+
def closed?
|
73
|
+
!open? || expired?
|
74
|
+
end
|
75
|
+
|
61
76
|
def key_for_handle(handle)
|
62
77
|
keys.find { |_| _.handle == handle }
|
63
78
|
end
|
@@ -72,6 +87,11 @@ module Clarion
|
|
72
87
|
true
|
73
88
|
end
|
74
89
|
|
90
|
+
def cancel!
|
91
|
+
@status = :cancelled
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
75
95
|
def to_h(all=false)
|
76
96
|
{
|
77
97
|
id: id,
|
data/lib/clarion/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clarion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sorah Fukumori
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: u2f
|