@@ -274,7 +274,7 @@ describe('Editor', function() {
274274 expect ( oldToken ) . to . equal ( newToken ) ;
275275 } ) ;
276276
277- describe ( 'Decodes HS256/384/512 tokens' , async function ( ) {
277+ describe ( 'Decodes HS256/384/512 tokens' , function ( ) {
278278 const algs = Object . keys ( tokens ) . filter ( alg => alg . includes ( 'hs' ) ) ;
279279
280280 for ( const alg of algs ) {
@@ -311,5 +311,355 @@ describe('Editor', function() {
311311 } ) ;
312312 }
313313 } ) ;
314- } ) ;
314+
315+ it ( 'Signs tokens with an empty secret' , async function ( ) {
316+ const secretInput = await this . page . $ ( 'input[name="secret"]' ) ;
317+ await secretInput . click ( ) ;
318+ await this . page . keyboard . down ( 'ControlLeft' ) ;
319+ await this . page . keyboard . press ( 'KeyA' ) ;
320+ await this . page . keyboard . up ( 'ControlLeft' ) ;
321+ await this . page . keyboard . press ( 'Delete' ) ;
322+
323+ const valid = await this . page . $eval ( '.validation-status' , status => {
324+ return status . classList . contains ( 'valid-token' ) &&
325+ status . textContent . indexOf ( 'verified' ) !== - 1 ;
326+ } ) ;
327+
328+ expect ( valid ) . to . be . true ;
329+ } ) ;
330+ } ) ;
331+
332+ describe ( 'Public-key' , function ( ) {
333+ describe ( 'Decodes RS/ES/PS tokens' , function ( ) {
334+ const algs = Object . keys ( defaultTokens )
335+ . filter ( alg => ! alg . includes ( 'hs' ) ) ;
336+
337+ for ( const alg of algs ) {
338+ it ( alg . toUpperCase ( ) , async function ( ) {
339+ await this . page . click ( '.js-input' ) ;
340+ await this . page . keyboard . down ( 'ControlLeft' ) ;
341+ await this . page . keyboard . press ( 'KeyA' ) ;
342+ await this . page . keyboard . up ( 'ControlLeft' ) ;
343+ await this . page . keyboard . type ( tokens [ alg ] . token , {
344+ delay : 5
345+ } ) ;
346+
347+ const secretInput = await this . page . $ ( 'textarea[name="public-key"]' ) ;
348+ await secretInput . click ( ) ;
349+ await this . page . keyboard . down ( 'ControlLeft' ) ;
350+ await this . page . keyboard . press ( 'KeyA' ) ;
351+ await this . page . keyboard . up ( 'ControlLeft' ) ;
352+ await secretInput . type ( tokens [ alg ] . publicKey , {
353+ delay : 5
354+ } ) ;
355+
356+ const valid = await this . page . $eval ( '.validation-status' , status => {
357+ return status . classList . contains ( 'valid-token' ) &&
358+ status . textContent . indexOf ( 'verified' ) !== - 1 ;
359+ } ) ;
360+
361+ expect ( valid ) . to . be . true ;
362+
363+ const payload = await this . page . evaluate ( ( ) => {
364+ return window . test . payloadEditor . getValue ( ) ;
365+ } ) ;
366+
367+ expect ( payload ) . to . include ( alg + 'test' ) ;
368+ } ) ;
369+ }
370+ } ) ;
371+
372+ describe ( 'Encodes RS/ES/PS tokens' , function ( ) {
373+ const algs = Object . keys ( defaultTokens )
374+ . filter ( alg => ! alg . includes ( 'hs' ) && alg !== 'none' ) ;
375+
376+ for ( const alg of algs ) {
377+ it ( alg . toUpperCase ( ) , async function ( ) {
378+ this . timeout ( 30000 ) ;
379+
380+ await this . page . select ( '#algorithm-select' , alg . toUpperCase ( ) ) ;
381+
382+ const oldToken = await this . page . evaluate ( ( ) => {
383+ return window . test . tokenEditor . getValue ( ) ;
384+ } ) ;
385+
386+ await this . page . click ( 'textarea[name="public-key"]' ) ;
387+ await this . page . keyboard . down ( 'ControlLeft' ) ;
388+ await this . page . keyboard . press ( 'KeyA' ) ;
389+ await this . page . keyboard . up ( 'ControlLeft' ) ;
390+ await this . page . keyboard . type ( defaultTokens [ alg ] . publicKey , {
391+ delay : 5
392+ } ) ;
393+
394+ await this . page . click ( 'textarea[name="private-key"]' ) ;
395+ await this . page . keyboard . down ( 'ControlLeft' ) ;
396+ await this . page . keyboard . press ( 'KeyA' ) ;
397+ await this . page . keyboard . up ( 'ControlLeft' ) ;
398+ await this . page . keyboard . type ( defaultTokens [ alg ] . privateKey , {
399+ delay : 5
400+ } ) ;
401+
402+ await this . page . click ( '.js-header' ) ;
403+ await this . page . keyboard . down ( 'ControlLeft' ) ;
404+ await this . page . keyboard . press ( 'KeyA' ) ;
405+ await this . page . keyboard . up ( 'ControlLeft' ) ;
406+ await this . page . keyboard . type ( JSON . stringify ( {
407+ alg : alg . toUpperCase ( ) ,
408+ typ : 'JWT'
409+ } , null , 2 ) , {
410+ delay : 5
411+ } ) ;
412+
413+ await this . page . click ( '.js-payload' ) ;
414+ await this . page . keyboard . down ( 'ControlLeft' ) ;
415+ await this . page . keyboard . press ( 'KeyA' ) ;
416+ await this . page . keyboard . up ( 'ControlLeft' ) ;
417+ await this . page . keyboard . type ( JSON . stringify ( {
418+ sub : 'test'
419+ } , null , 2 ) , {
420+ delay : 5
421+ } ) ;
422+
423+ const newToken = await this . page . evaluate ( ( ) => {
424+ return window . test . tokenEditor . getValue ( ) ;
425+ } ) ;
426+
427+ expect ( newToken ) . to . not . equal ( oldToken ) ;
428+
429+ const valid = await this . page . $eval ( '.validation-status' , status => {
430+ return status . classList . contains ( 'valid-token' ) &&
431+ status . textContent . indexOf ( 'verified' ) !== - 1 ;
432+ } ) ;
433+
434+ expect ( valid ) . to . be . true ;
435+ } ) ;
436+ }
437+ } ) ;
438+
439+ describe ( 'Should download public-keys when possible' , function ( ) {
440+ before ( function ( ) {
441+
442+ } ) ;
443+
444+ after ( function ( ) {
445+
446+ } ) ;
447+
448+ it ( 'iss URL + .well-known' ) ;
449+ it ( 'jku' ) ;
450+ } ) ;
451+
452+ it ( 'Clears the token when the header is edited and there ' +
453+ 'is no private key' , async function ( ) {
454+ const secretInput = await this . page . $ ( 'textarea[name="private-key"]' ) ;
455+ await secretInput . click ( ) ;
456+ await this . page . keyboard . down ( 'ControlLeft' ) ;
457+ await this . page . keyboard . press ( 'KeyA' ) ;
458+ await this . page . keyboard . up ( 'ControlLeft' ) ;
459+ await this . page . keyboard . press ( 'Delete' ) ;
460+
461+ await this . page . click ( '.js-header' ) ;
462+ await this . page . keyboard . down ( 'ControlLeft' ) ;
463+ await this . page . keyboard . press ( 'KeyA' ) ;
464+ await this . page . keyboard . up ( 'ControlLeft' ) ;
465+
466+ const header = {
467+ alg : 'RS256' ,
468+ typ : 'JWT' ,
469+ test : 'test'
470+ } ;
471+ await this . page . keyboard . type ( JSON . stringify ( header , null , 2 ) , {
472+ delay : 5
473+ } ) ;
474+
475+ const token = await this . page . evaluate ( ( ) => {
476+ return window . test . tokenEditor . getValue ( ) ;
477+ } ) ;
478+
479+ expect ( token ) . to . be . empty ;
480+ } ) ;
481+
482+ it ( 'Clears the token when the payload is edited and there ' +
483+ 'is no private key' , async function ( ) {
484+ const secretInput = await this . page . $ ( 'textarea[name="private-key"]' ) ;
485+ await secretInput . click ( ) ;
486+ await this . page . keyboard . down ( 'ControlLeft' ) ;
487+ await this . page . keyboard . press ( 'KeyA' ) ;
488+ await this . page . keyboard . up ( 'ControlLeft' ) ;
489+ await this . page . keyboard . press ( 'Delete' ) ;
490+
491+ await this . page . click ( '.js-payload' ) ;
492+ await this . page . keyboard . down ( 'ControlLeft' ) ;
493+ await this . page . keyboard . press ( 'KeyA' ) ;
494+ await this . page . keyboard . up ( 'ControlLeft' ) ;
495+
496+ const payload = {
497+ sub : 'test'
498+ } ;
499+ await this . page . keyboard . type ( JSON . stringify ( payload , null , 2 ) , {
500+ delay : 5
501+ } ) ;
502+
503+ const token = await this . page . evaluate ( ( ) => {
504+ return window . test . tokenEditor . getValue ( ) ;
505+ } ) ;
506+
507+ expect ( token ) . to . be . empty ;
508+ } ) ;
509+
510+ it ( 'Marks token as invalid when there is no public key' , async function ( ) {
511+ await this . page . select ( '#algorithm-select' , 'RS256' ) ;
512+
513+ await this . page . click ( '.js-input' ) ;
514+ await this . page . keyboard . down ( 'ControlLeft' ) ;
515+ await this . page . keyboard . press ( 'KeyA' ) ;
516+ await this . page . keyboard . up ( 'ControlLeft' ) ;
517+ await this . page . keyboard . type ( tokens [ 'rs256' ] . token , {
518+ delay : 5
519+ } ) ;
520+
521+ const secretInput = await this . page . $ ( 'textarea[name="public-key"]' ) ;
522+ await secretInput . click ( ) ;
523+ await this . page . keyboard . down ( 'ControlLeft' ) ;
524+ await this . page . keyboard . press ( 'KeyA' ) ;
525+ await this . page . keyboard . up ( 'ControlLeft' ) ;
526+ await secretInput . type ( tokens [ 'rs256' ] . publicKey , {
527+ delay : 5
528+ } ) ;
529+
530+ const valid = await this . page . $eval ( '.validation-status' , status => {
531+ return status . classList . contains ( 'valid-token' ) &&
532+ status . textContent . indexOf ( 'verified' ) !== - 1 ;
533+ } ) ;
534+
535+ expect ( valid ) . to . be . true ;
536+
537+ await secretInput . click ( ) ;
538+ await this . page . keyboard . down ( 'ControlLeft' ) ;
539+ await this . page . keyboard . press ( 'KeyA' ) ;
540+ await this . page . keyboard . up ( 'ControlLeft' ) ;
541+ await this . page . keyboard . press ( 'Delete' ) ;
542+
543+ const invalid = await this . page . $eval ( '.validation-status' , status => {
544+ return status . classList . contains ( 'invalid-token' ) &&
545+ status . textContent . indexOf ( 'invalid' ) !== - 1 ;
546+ } ) ;
547+
548+ expect ( invalid ) . to . be . true ;
549+ } ) ;
550+
551+ it ( 'Marks token as invalid when the public key is wrong' , async function ( ) {
552+ await this . page . select ( '#algorithm-select' , 'RS256' ) ;
553+
554+ await this . page . click ( '.js-input' ) ;
555+ await this . page . keyboard . down ( 'ControlLeft' ) ;
556+ await this . page . keyboard . press ( 'KeyA' ) ;
557+ await this . page . keyboard . up ( 'ControlLeft' ) ;
558+ await this . page . keyboard . type ( tokens [ 'rs256' ] . token , {
559+ delay : 5
560+ } ) ;
561+
562+ const secretInput = await this . page . $ ( 'textarea[name="public-key"]' ) ;
563+ await secretInput . click ( ) ;
564+ await this . page . keyboard . down ( 'ControlLeft' ) ;
565+ await this . page . keyboard . press ( 'KeyA' ) ;
566+ await this . page . keyboard . up ( 'ControlLeft' ) ;
567+ await secretInput . type ( tokens [ 'rs256' ] . publicKey , {
568+ delay : 5
569+ } ) ;
570+
571+ const valid = await this . page . $eval ( '.validation-status' , status => {
572+ return status . classList . contains ( 'valid-token' ) &&
573+ status . textContent . indexOf ( 'verified' ) !== - 1 ;
574+ } ) ;
575+
576+ expect ( valid ) . to . be . true ;
577+
578+ await secretInput . click ( ) ;
579+ await this . page . keyboard . type ( 'sdfasdf389972389' , {
580+ delay : 5
581+ } ) ;
582+
583+ const invalid = await this . page . $eval ( '.validation-status' , status => {
584+ return status . classList . contains ( 'invalid-token' ) &&
585+ status . textContent . indexOf ( 'invalid' ) !== - 1 ;
586+ } ) ;
587+
588+ expect ( invalid ) . to . be . true ;
589+ } ) ;
590+
591+ it ( 'Marks token as valid when the public key is OK and private key is wrong' ) ;
592+ it ( 'Marks token as valid when the public key is OK and private key is missing' ) ;
593+ } ) ;
594+
595+ it ( 'Updates the header when the token algorithm ' +
596+ 'is changed' , async function ( ) {
597+ await this . page . select ( '#algorithm-select' , 'HS256' ) ;
598+
599+ await this . page . click ( '.js-input' ) ;
600+ await this . page . keyboard . down ( 'ControlLeft' ) ;
601+ await this . page . keyboard . press ( 'KeyA' ) ;
602+ await this . page . keyboard . up ( 'ControlLeft' ) ;
603+ await this . page . keyboard . type ( tokens . hs256 . token , {
604+ delay : 5
605+ } ) ;
606+
607+ await this . page . select ( '#algorithm-select' , 'HS384' ) ;
608+
609+ const header = await this . page . evaluate ( ( ) => {
610+ return JSON . parse ( window . test . headerEditor . getValue ( ) ) ;
611+ } ) ;
612+
613+ expect ( header . alg ) . to . equal ( 'HS384' ) ;
614+ } ) ;
615+
616+ it ( 'Marks token as invalid when "alg" is "none"' , async function ( ) {
617+ await this . page . click ( '.js-input' ) ;
618+ await this . page . keyboard . down ( 'ControlLeft' ) ;
619+ await this . page . keyboard . press ( 'KeyA' ) ;
620+ await this . page . keyboard . up ( 'ControlLeft' ) ;
621+ await this . page . keyboard . type ( tokens . none . token , {
622+ delay : 5
623+ } ) ;
624+
625+ const invalid = await this . page . $eval ( '.validation-status' , status => {
626+ return status . classList . contains ( 'invalid-token' ) &&
627+ status . textContent . indexOf ( 'invalid' ) !== - 1 ;
628+ } ) ;
629+
630+ expect ( invalid ) . to . be . true ;
631+ } ) ;
632+
633+ it ( 'Saves last edited token' , async function ( ) {
634+ await this . page . select ( '#algorithm-select' , 'HS256' ) ;
635+
636+ const secretInput = await this . page . $ ( 'input[name="secret"]' ) ;
637+ await secretInput . click ( ) ;
638+ await this . page . keyboard . down ( 'ControlLeft' ) ;
639+ await this . page . keyboard . press ( 'KeyA' ) ;
640+ await this . page . keyboard . up ( 'ControlLeft' ) ;
641+ await secretInput . type ( 'secret-test' , {
642+ delay : 5
643+ } ) ;
644+
645+ await this . page . click ( '.js-payload' ) ;
646+ await this . page . keyboard . down ( 'ControlLeft' ) ;
647+ await this . page . keyboard . press ( 'KeyA' ) ;
648+ await this . page . keyboard . up ( 'ControlLeft' ) ;
649+
650+ const payload = {
651+ sub : 'test'
652+ } ;
653+ await this . page . keyboard . type ( JSON . stringify ( payload , null , 2 ) , {
654+ delay : 5
655+ } ) ;
656+
657+ await this . page . reload ( ) ;
658+
659+ const storedPayload = await this . page . evaluate ( ( ) => {
660+ return JSON . parse ( window . test . payloadEditor . getValue ( ) ) ;
661+ } ) ;
662+
663+ expect ( storedPayload ) . to . deep . equal ( payload ) ;
664+ } ) ;
315665} ) ;
0 commit comments