Skip to content

Commit 828868f

Browse files
committed
JWT sharing now working.
1 parent 4238932 commit 828868f

File tree

6 files changed

+81
-22
lines changed

6 files changed

+81
-22
lines changed

src/editor/index.js

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import { copyTextToClipboard, deferToNextLoop, safeLocalStorageSetItem } from '../utils.js';
1+
import {
2+
copyTextToClipboard,
3+
deferToNextLoop,
4+
safeLocalStorageSetItem,
5+
copyTokenLink
6+
} from '../utils.js';
27
import { downloadPublicKeyIfPossible } from './public-key-download.js';
38
import { tooltipHandler } from './tooltip.js';
49
import { tokenEditor, headerEditor, payloadEditor } from './instances.js';
510
import {
6-
copyTokenLink,
711
getTrimmedValue,
812
stringify,
913
fixEditorHeight
@@ -38,6 +42,14 @@ import {
3842
// passed to the event manager.
3943
const eventManager = new EventManager();
4044

45+
function isSharedSecretAlgorithm(algorithm) {
46+
return algorithm && algorithm.indexOf('HS') === 0;
47+
}
48+
49+
function isPublicKeyAlgorithm(algorithm) {
50+
return algorithm && algorithm.indexOf('HS') === -1;
51+
}
52+
4153
function markAsInvalid() {
4254
signatureStatusElement.classList.remove('valid-token');
4355
signatureStatusElement.classList.add('invalid-token');
@@ -115,7 +127,7 @@ export function useDefaultToken(algorithm) {
115127
headerEditor.setValue(stringify(decoded.header));
116128
payloadEditor.setValue(stringify(decoded.payload));
117129

118-
if(algorithm.indexOf('HS') === 0) {
130+
if(isSharedSecretAlgorithm(algorithm)) {
119131
secretInput.value = defaults.secret;
120132
} else {
121133
publicKeyTextArea.value = defaults.publicKey;
@@ -233,7 +245,7 @@ function encodeToken() {
233245

234246
try {
235247
const encoded = sign(header, payload,
236-
header.alg.indexOf('HS') === 0 ?
248+
isSharedSecretAlgorithm(header.alg) ?
237249
secretInput.value :
238250
privateKeyTextArea.value,
239251
secretBase64Checkbox.checked);
@@ -260,7 +272,7 @@ function decodeToken() {
260272
const decoded = decode(jwt);
261273

262274
selectAlgorithm(decoded.header.alg);
263-
if(decoded.header.alg && decoded.header.alg.indexOf('HS') === -1) {
275+
if(isPublicKeyAlgorithm(decoded.header.alg)) {
264276
downloadPublicKeyIfPossible(decoded).then(publicKey => {
265277
eventManager.withDisabledEvents(() => {
266278
publicKeyTextArea.value = publicKey;
@@ -294,7 +306,7 @@ function verifyToken() {
294306
}
295307

296308
const publicKeyOrSecret =
297-
decoded.header.alg.indexOf('HS') === 0 ?
309+
isSharedSecretAlgorithm(decoded.header.alg) ?
298310
secretInput.value :
299311
publicKeyTextArea.value;
300312

@@ -327,6 +339,17 @@ function setupTabEvents() {
327339
});
328340
}
329341

342+
function copyTokenHandler(event) {
343+
event.preventDefault();
344+
345+
const token = getTrimmedValue(tokenEditor);
346+
const publicKey = isPublicKeyAlgorithm(getSelectedAlgorithm()) ?
347+
publicKeyTextArea.value :
348+
null;
349+
350+
copyTokenLink(token, publicKey);
351+
}
352+
330353
function setupEvents() {
331354
// The event manager lets us enable/disable events as needed without
332355
// manually tracking them. Events that need to be disabled should be
@@ -356,7 +379,7 @@ function setupEvents() {
356379
// Human readable timestamp tooltips
357380
payloadElement.addEventListener('mousemove', tooltipHandler);
358381
// Temporary (share button not ready yet)
359-
signatureStatusElement.addEventListener('click', copyTokenLink);
382+
signatureStatusElement.addEventListener('click', copyTokenHandler);
360383

361384
setupTabEvents();
362385
}
@@ -365,6 +388,15 @@ export function setTokenEditorValue(value) {
365388
tokenEditor.setValue(value);
366389
}
367390

391+
export function getTokenEditorValue() {
392+
return {
393+
token: getTrimmedValue(tokenEditor),
394+
publicKey: isPublicKeyAlgorithm(getSelectedAlgorithm()) ?
395+
publicKeyTextArea.value :
396+
undefined
397+
};
398+
}
399+
368400
export function setupTokenEditor() {
369401
setupEvents();
370402
selectAlgorithm('HS256');

src/editor/utils.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,6 @@ export function getTrimmedValue(instance) {
1616
return value.replace(/\s/g, '');
1717
}
1818

19-
export function copyTokenLink() {
20-
const algorithm = algorithmSelect.querySelector(':selected').value;
21-
22-
let url = 'https://jwt.io/#debugger-io?'
23-
+ `token=${encodeURIComponent(getTrimmedValue(tokenEditor))}`;
24-
if (algorithm.indexOf('HS') === -1) {
25-
url += `&publicKey=${encodeURIComponent(publicKeyTextArea.value)}`;
26-
}
27-
28-
copyTextToClipboard(url);
29-
}
30-
3119
export function fixEditorHeight() {
3220
if(isWideScreen()) {
3321
editorElement.style.height = `${decodedElement.offsetHeight}px`;

src/extension/dom-elements.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
export * from '../dom-elements.js';
1+
export * from '../dom-elements.js';
2+
3+
export const shareJwtLink = document.querySelector('.jwt-clipboard-btn');
4+
export const shareJwtTextElement =
5+
document.getElementById('share-this-jwt-text');

src/extension/index.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
1-
import { setupTokenEditor } from '../editor';
1+
import { setupTokenEditor, getTokenEditorValue } from '../editor';
2+
import { shareJwtLink, shareJwtTextElement } from './dom-elements.js';
3+
import { copyTokenLink } from '../utils.js';
4+
import strings from '../strings.js';
5+
6+
function setupShareJwtButton() {
7+
shareJwtLink.addEventListener('click', event => {
8+
event.preventDefault();
9+
10+
const value = getTokenEditorValue();
11+
if(value.token) {
12+
// If the selected algorithm does not use public keys, publicKey will be
13+
// undefined.
14+
copyTokenLink(value.token, value.publicKey);
15+
}
16+
17+
shareJwtTextElement.firstChild.textContent =
18+
strings.extension.jwtIoUrlCopied;
19+
setTimeout(() => {
20+
shareJwtTextElement.firstChild.textContent =
21+
strings.extension.shareThisJwt;
22+
}, 2000);
23+
});
24+
}
225

326
// Initialization
427
setupTokenEditor();
28+
setupShareJwtButton();

src/strings.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
export default {
22
extension: {
33
alreadyInstalled: 'Already installed',
4-
addToChrome: 'Add to Chrome'
4+
addToChrome: 'Add to Chrome',
5+
shareThisJwt: 'Share this JWT',
6+
jwtIoUrlCopied: 'JWT.io URL copied'
57
},
68
editor: {
79
signatureVerified: 'signature verified',

src/utils.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,15 @@ export function copyTextToClipboard(text) {
160160
document.body.removeChild(textArea);
161161
}
162162

163+
export function copyTokenLink(token, publicKeyOptional) {
164+
let url = `https://jwt.io/#debugger-io?token=${encodeURIComponent(token)}`;
165+
if(publicKeyOptional) {
166+
url += `&publicKey=${encodeURIComponent(publicKeyOptional)}`;
167+
}
168+
169+
copyTextToClipboard(url);
170+
}
171+
163172
// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
164173
export function getParameterByName(name, url) {
165174
if(!url) {

0 commit comments

Comments
 (0)