thoughts/node_modules/jsonwebtoken/test/verify.tests.js
node_modules/jsonwebtoken/test/verify.tests.jsRaw
1var jwt = require('../index');
2var jws = require('jws');
3var fs = require('fs');
4var path = require('path');
5var sinon = require('sinon');
6
7var assert = require('chai').assert;
8
9describe('verify', function() {
10 var pub = fs.readFileSync(path.join(__dirname, 'pub.pem'));
11 var priv = fs.readFileSync(path.join(__dirname, 'priv.pem'));
12
13 it('should first assume JSON claim set', function (done) {
14 var header = { alg: 'RS256' };
15 var payload = { iat: Math.floor(Date.now() / 1000 ) };
16
17 var signed = jws.sign({
18 header: header,
19 payload: payload,
20 secret: priv,
21 encoding: 'utf8'
22 });
23
24 jwt.verify(signed, pub, {typ: 'JWT'}, function(err, p) {
25 assert.isNull(err);
26 assert.deepEqual(p, payload);
27 done();
28 });
29 });
30
31 it('should be able to validate unsigned token', function (done) {
32 var header = { alg: 'none' };
33 var payload = { iat: Math.floor(Date.now() / 1000 ) };
34
35 var signed = jws.sign({
36 header: header,
37 payload: payload,
38 secret: priv,
39 encoding: 'utf8'
40 });
41
42 jwt.verify(signed, null, {typ: 'JWT'}, function(err, p) {
43 assert.isNull(err);
44 assert.deepEqual(p, payload);
45 done();
46 });
47 });
48
49 it('should not mutate options', function (done) {
50 var header = { alg: 'none' };
51
52 var payload = { iat: Math.floor(Date.now() / 1000 ) };
53
54 var options = {typ: 'JWT'};
55
56 var signed = jws.sign({
57 header: header,
58 payload: payload,
59 secret: priv,
60 encoding: 'utf8'
61 });
62
63 jwt.verify(signed, null, options, function(err) {
64 assert.isNull(err);
65 assert.deepEqual(Object.keys(options).length, 1);
66 done();
67 });
68 });
69
70 describe('expiration', function () {
71 // { foo: 'bar', iat: 1437018582, exp: 1437018583 }
72 var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE0MzcwMTg1ODIsImV4cCI6MTQzNzAxODU4M30.NmMv7sXjM1dW0eALNXud8LoXknZ0mH14GtnFclwJv0s';
73 var key = 'key';
74
75 var clock;
76 afterEach(function () {
77 try { clock.restore(); } catch (e) {}
78 });
79
80 it('should error on expired token', function (done) {
81 clock = sinon.useFakeTimers(1437018650000);
82 var options = {algorithms: ['HS256']};
83
84 jwt.verify(token, key, options, function (err, p) {
85 assert.equal(err.name, 'TokenExpiredError');
86 assert.equal(err.message, 'jwt expired');
87 assert.equal(err.expiredAt.constructor.name, 'Date');
88 assert.equal(Number(err.expiredAt), 1437018583000);
89 assert.isUndefined(p);
90 done();
91 });
92 });
93
94 it('should not error on expired token within clockTolerance interval', function (done) {
95 clock = sinon.useFakeTimers(1437018584000);
96 var options = {algorithms: ['HS256'], clockTolerance: 100}
97
98 jwt.verify(token, key, options, function (err, p) {
99 assert.isNull(err);
100 assert.equal(p.foo, 'bar');
101 done();
102 });
103 });
104
105 it('should not error if within maxAge timespan', function (done) {
106 clock = sinon.useFakeTimers(1437018582500);
107 var options = {algorithms: ['HS256'], maxAge: '600ms'};
108
109 jwt.verify(token, key, options, function (err, p) {
110 assert.isNull(err);
111 assert.equal(p.foo, 'bar');
112 done();
113 });
114 });
115
116 describe('option: maxAge', function () {
117 it('should error for claims issued before a certain timespan', function (done) {
118 clock = sinon.useFakeTimers(1437018582500);
119 var options = {algorithms: ['HS256'], maxAge: '321ms'};
120
121 jwt.verify(token, key, options, function (err, p) {
122 assert.equal(err.name, 'TokenExpiredError');
123 assert.equal(err.message, 'maxAge exceeded');
124 assert.equal(err.expiredAt.constructor.name, 'Date');
125 assert.equal(Number(err.expiredAt), 1437018582321);
126 assert.isUndefined(p);
127 done();
128 });
129 });
130
131 it('should not error for claims issued before a certain timespan but still inside clockTolerance timespan', function (done) {
132 clock = sinon.useFakeTimers(1437018582500);
133 var options = {algorithms: ['HS256'], maxAge: '321ms', clockTolerance: 100};
134
135 jwt.verify(token, key, options, function (err, p) {
136 assert.isNull(err);
137 assert.equal(p.foo, 'bar');
138 done();
139 });
140 });
141
142 it('should not error if within maxAge timespan', function (done) {
143 clock = sinon.useFakeTimers(1437018582500);
144 var options = {algorithms: ['HS256'], maxAge: '600ms'};
145
146 jwt.verify(token, key, options, function (err, p) {
147 assert.isNull(err);
148 assert.equal(p.foo, 'bar');
149 done();
150 });
151 });
152 it('can be more restrictive than expiration', function (done) {
153 clock = sinon.useFakeTimers(1437018582900);
154 var options = {algorithms: ['HS256'], maxAge: '800ms'};
155
156 jwt.verify(token, key, options, function (err, p) {
157 assert.equal(err.name, 'TokenExpiredError');
158 assert.equal(err.message, 'maxAge exceeded');
159 assert.equal(err.expiredAt.constructor.name, 'Date');
160 assert.equal(Number(err.expiredAt), 1437018582800);
161 assert.isUndefined(p);
162 done();
163 });
164 });
165 it('cannot be more permissive than expiration', function (done) {
166 clock = sinon.useFakeTimers(1437018583100);
167 var options = {algorithms: ['HS256'], maxAge: '1200ms'};
168
169 jwt.verify(token, key, options, function (err, p) {
170 // maxAge not exceded, but still expired
171 assert.equal(err.name, 'TokenExpiredError');
172 assert.equal(err.message, 'jwt expired');
173 assert.equal(err.expiredAt.constructor.name, 'Date');
174 assert.equal(Number(err.expiredAt), 1437018583000);
175 assert.isUndefined(p);
176 done();
177 });
178 });
179 it('should error if maxAge is specified but there is no iat claim', function (done) {
180 clock = sinon.useFakeTimers(1437018582900);
181 var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.0MBPd4Bru9-fK_HY3xmuDAc6N_embknmNuhdb9bKL_U';
182 var options = {algorithms: ['HS256'], maxAge: '1s'};
183
184 jwt.verify(token, key, options, function (err, p) {
185 assert.equal(err.name, 'JsonWebTokenError');
186 assert.equal(err.message, 'iat required when maxAge is specified');
187 assert.isUndefined(p);
188 done();
189 });
190 });
191 });
192 });
193
194});