Skip to content

Commit e81b5b8

Browse files
argenvctrfrnndz
authored andcommitted
Pixel2HTML Updates to jwt.io
1 parent 3ad52d6 commit e81b5b8

File tree

8 files changed

+550
-199
lines changed

8 files changed

+550
-199
lines changed

.DS_Store

6 KB
Binary file not shown.

dist/css/app.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/js/app.js

Lines changed: 15 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

html/index.html

Lines changed: 167 additions & 82 deletions
Large diffs are not rendered by default.

index.html

Lines changed: 121 additions & 81 deletions
Large diffs are not rendered by default.

js/app.js

Lines changed: 180 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,37 @@
2020
}
2121
}
2222

23+
var DEFAULT_HS_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ';
24+
25+
var DEFAULT_RS_TOKEN = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.EkN-DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8jO19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuhtF39yxJPAjUESwxk2J5k_4zM3O-vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE';
26+
27+
var DEFAULT_PUBLIC_RSA = "\
28+
-----BEGIN PUBLIC KEY-----\n\
29+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd\
30+
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs\
31+
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D\
32+
o2kQ+X5xK9cipRgEKwIDAQAB\n\
33+
-----END PUBLIC KEY-----\
34+
";
35+
36+
var DEFAULT_PRIVATE_RSA = "\
37+
-----BEGIN RSA PRIVATE KEY-----\n\
38+
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw\
39+
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW\
40+
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB\
41+
AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS\
42+
3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp\
43+
uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE\
44+
2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0\
45+
GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K\
46+
Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY\
47+
6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5\
48+
fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523\
49+
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP\
50+
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==\n\
51+
-----END RSA PRIVATE KEY-----\
52+
";
53+
2354
var codeMirror = CodeMirror;
2455

2556
function tabHack(instance) {
@@ -48,6 +79,9 @@
4879
lint: true
4980
});
5081

82+
var algorithmRadios = $('input[name="algorithm"]'),
83+
lastRestoredToken;
84+
5185
function setJSONEditorContent(jsonEditor, decodedJSON, selector) {
5286
jsonEditor.off('change', refreshTokenEditor);
5387
if (decodedJSON.result !== null && decodedJSON.result !== undefined) {
@@ -79,6 +113,13 @@
79113
}
80114

81115
var decodedHeader = window.decode(parts[0]);
116+
117+
try {
118+
selectDetectedAlgorithm(JSON.parse(decodedHeader.result).alg);
119+
}catch (e){
120+
console.log('Invalid header decoded');
121+
}
122+
82123
var selector = $('.jwt-header');
83124
setJSONEditorContent(headerEditor, decodedHeader, selector);
84125
var decodedPayload = window.decode(parts[1]);
@@ -88,6 +129,15 @@
88129
fireEvent(secretElement);
89130
}
90131

132+
function selectDetectedAlgorithm(alg){
133+
134+
var $algRadio = $('.algorithm input[value="'+alg+'"]');
135+
$algRadio.prop('checked', true);
136+
137+
fireEvent($algRadio.get(0));
138+
139+
}
140+
91141
function saveToStorage(jwt) {
92142
// Save last valid jwt value for refresh
93143
localStorage.jwtValue = jwt;
@@ -99,11 +149,20 @@
99149
}
100150

101151
function refreshTokenEditor(instance) {
152+
102153
tokenEditor.off('change', tokenEditorOnChangeListener);
154+
155+
var algorithm = getAlgorithm();
103156
var secretElement = document.getElementsByName('secret')[0];
104157
var isBase64EncodedElement = document.getElementsByName('is-base64-encoded')[0];
105-
var signResult = window.sign(headerEditor.getValue(), payloadEditor.getValue(), secretElement.value,
106-
isBase64EncodedElement.checked);
158+
159+
var signResult = window.sign(
160+
algorithm,
161+
headerEditor.getValue(),
162+
payloadEditor.getValue(),
163+
getKey(algorithm, 'sign'),
164+
isBase64EncodedElement.checked);
165+
107166

108167
if (signResult.error) {
109168
tokenEditor.setValue('');
@@ -158,6 +217,8 @@
158217
var isBase64EncodedElement = document.getElementsByName('is-base64-encoded')[0];
159218

160219
function updateSignature () {
220+
221+
var algorithm = getAlgorithm();
161222
var signatureElement = getFirstElementByClassName('js-signature');
162223
var signatureContainerElement = getFirstElementByClassName('jwt-signature');
163224

@@ -172,7 +233,14 @@
172233
} else {
173234
$(signatureContainerElement).removeClass('error');
174235
}
175-
var result = window.verify(value, secretElement.value, isBase64);
236+
237+
var result = window.verify(
238+
algorithm,
239+
value,
240+
getKey(algorithm, 'verify'),
241+
isBase64);
242+
243+
176244
var error = result.error;
177245
result = result.result;
178246
if (!error && result) {
@@ -185,10 +253,92 @@
185253
signatureElement.innerHTML = '<i class="fa fa-times-circle-o"></i> invalid signature';
186254
}
187255
}
256+
257+
function getKey(algorithm, action){
258+
259+
var secretElement = $('input[name="secret"]'),
260+
privateKeyElement = $('textarea[name="private-key"]'),
261+
publicKeyElement = $('textarea[name="public-key"]');
262+
263+
if(algorithm === 'HS256'){
264+
return secretElement.val();
265+
}else{
266+
return action === 'sign' ? privateKeyElement.val() : publicKeyElement.val();
267+
}
268+
269+
}
270+
271+
function getAlgorithm(){
272+
273+
return algorithmRadios.filter(':checked').val();
274+
}
275+
276+
function updateAlgorithm () {
277+
278+
var algorithm = algorithmRadios.filter(':checked').val();
279+
280+
$('.jwt-signature pre')
281+
.hide()
282+
.filter('.' + algorithm)
283+
.show();
284+
285+
if(getTrimmedValue(tokenEditor) === DEFAULT_HS_TOKEN &&
286+
algorithm === 'RS256'){
287+
setDefaultsForRSA();
288+
}else if(getTrimmedValue(tokenEditor) === DEFAULT_RS_TOKEN &&
289+
algorithm === 'HS256'){
290+
setDefaultsForHMAC();
291+
}
292+
293+
}
294+
295+
function setDefaultsForRSA(){
296+
297+
tokenEditor.setValue(DEFAULT_RS_TOKEN);
298+
299+
$('.jwt-signature textarea[name=public-key]').val(DEFAULT_PUBLIC_RSA);
300+
$('.jwt-signature textarea[name=private-key]').val(DEFAULT_PRIVATE_RSA);
301+
}
302+
303+
function setDefaultsForHMAC(){
304+
305+
tokenEditor.setValue(DEFAULT_HS_TOKEN);
306+
}
307+
308+
updateAlgorithm();
309+
310+
algorithmRadios.on('change', function(){
311+
updateAlgorithm();
312+
updateSignature();
313+
});
314+
315+
$('.jwt-signature textarea').on('change', updateSignature, false);
316+
$('.jwt-signature textarea').on('keyup', updateSignature, false);
317+
$('.jwt-signature textarea').on('keyup', validateKey, false);
318+
188319
secretElement.addEventListener('change', updateSignature, false);
189320
secretElement.addEventListener('keyup', updateSignature, false);
190321
isBase64EncodedElement.addEventListener('change', updateSignature, false);
191322

323+
function validateKey(){
324+
325+
$textarea = $(this);
326+
var valid;
327+
328+
if($textarea.prop('name') === 'public-key'){
329+
valid = /-----BEGIN (PUBLIC KEY|CERTIFICATE)-----(.|\n)*-----END (PUBLIC KEY|CERTIFICATE)-----/.test($textarea.val());
330+
}else{
331+
valid = /-----BEGIN RSA PRIVATE KEY-----(.|\n)*-----END RSA PRIVATE KEY-----/.test($textarea.val());
332+
}
333+
334+
if (valid) {
335+
$textarea.removeClass('error');
336+
}else{
337+
$textarea.addClass('error');
338+
}
339+
340+
}
341+
192342
if (document.location.search) {
193343
var qs = document.location.search.slice(1);
194344
var d = {};
@@ -212,8 +362,11 @@
212362
}
213363

214364
loadFromStorage(function (jwt) {
365+
366+
lastRestoredToken = jwt || DEFAULT_HS_TOKEN;
367+
215368
tokenEditor.setValue(
216-
jwt || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ'
369+
lastRestoredToken
217370
);
218371
});
219372

@@ -230,6 +383,29 @@
230383
}, 1000);
231384
}).call(this);
232385

386+
387+
//Inizialize bootstrap widgets
388+
$('[data-toggle="tooltip"]').tooltip();
389+
390+
// Fetch stargazers count for each repo from GitHub's API
391+
$('.stars').each(function(idx, element){
392+
393+
var $el = $(element);
394+
var repo = $el.attr('data-repo');
395+
396+
if (repo){
397+
$.getJSON('http://api.github.com/repos/' + repo, function(repoData){
398+
399+
var $count = $('<span>');
400+
$count.text(repoData.stargazers_count);
401+
402+
$el.find('i').after($count);
403+
404+
$el.show();
405+
});
406+
}
407+
});
408+
233409
//CANVAS
234410
// $(function(){
235411
// var canvas = document.querySelector('canvas'),

js/jwt.js

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ window.decode = function (base64json) {
4343
return {result: json, error: error};
4444
};
4545

46-
window.sign = function (header, payload, secret, isSecretBase64Encoded) {
46+
window.sign = function (
47+
algorithm,
48+
header,
49+
payload,
50+
key,
51+
isSecretBase64Encoded) {
52+
4753
var value = '', error = null, headerAsJSON, payloadAsJSON;
4854

4955
try {
@@ -65,19 +71,21 @@ window.sign = function (header, payload, secret, isSecretBase64Encoded) {
6571
return error;
6672
}
6773

68-
if (isSecretBase64Encoded) {
69-
try {
70-
secret = window.b64utob64(secret);
71-
secret = window.CryptoJS.enc.Base64.parse(secret).toString();
72-
} catch (e) {
73-
return {result: '', error: e};
74+
if(algorithm === 'HS256'){
75+
if (isSecretBase64Encoded) {
76+
try {
77+
key = window.b64utob64(key);
78+
key = window.CryptoJS.enc.Base64.parse(key).toString();
79+
} catch (e) {
80+
return {result: '', error: e};
81+
}
82+
} else {
83+
key = window.CryptoJS.enc.Latin1.parse(key).toString();
7484
}
75-
} else {
76-
secret = window.CryptoJS.enc.Latin1.parse(secret).toString();
7785
}
7886

7987
try {
80-
value = KJUR.jws.JWS.sign(null, headerAsJSON, payloadAsJSON, secret);
88+
value = KJUR.jws.JWS.sign(algorithm, headerAsJSON, payloadAsJSON, key);
8189
} catch (e) {
8290
error = e;
8391
}
@@ -95,22 +103,25 @@ window.isValidBase64String = function (s) {
95103
}
96104
};
97105

98-
window.verify = function (value, secret, isSecretBase64Encoded) {
106+
window.verify = function (algorithm, value, key, isSecretBase64Encoded) {
107+
99108
var result = '', error = null;
100109

101-
if (isSecretBase64Encoded) {
102-
try {
103-
secret = window.b64utob64(secret);
104-
secret = window.CryptoJS.enc.Base64.parse(secret).toString();
105-
} catch (e) {
106-
return {result: '', error: e};
110+
if (algorithm === 'HS256'){
111+
if (isSecretBase64Encoded) {
112+
try {
113+
key = window.b64utob64(key);
114+
key = window.CryptoJS.enc.Base64.parse(key).toString();
115+
} catch (e) {
116+
return {result: '', error: e};
117+
}
118+
} else {
119+
key = window.CryptoJS.enc.Latin1.parse(key).toString();
107120
}
108-
} else {
109-
secret = window.CryptoJS.enc.Latin1.parse(secret).toString();
110121
}
111122

112123
try {
113-
result = KJUR.jws.JWS.verify(value, secret);
124+
result = KJUR.jws.JWS.verify(value, key, 'passwd');
114125
} catch (e) {
115126
error = e;
116127
}

0 commit comments

Comments
 (0)