UNPKG

2.25 kBJavaScriptView Raw
1/**
2 * Module dependencies
3 */
4
5var JWT = require('anvil-connect-jwt')
6var IDTokenError = require('./IDTokenError')
7var nowSeconds = require('./time-utils').nowSeconds
8
9/**
10 * Expires
11 */
12
13function expires (duration) {
14 var fromNow = {
15 day: (1000 * 60 * 60 * 24),
16 week: (1000 * 60 * 60 * 24 * 7),
17 month: (1000 * 60 * 60 * 24 * 30)
18 }
19
20 return function () {
21 return nowSeconds(fromNow[duration])
22 }
23}
24
25/**
26 * ID Token
27 */
28
29var IDToken = JWT.define({
30 // default header
31 header: {
32 alg: 'RS256'
33 },
34
35 // permitted headers
36 headers: [
37 'alg'
38 ],
39
40 // modify header schema
41 registeredHeaders: {
42 alg: { format: 'StringOrURI', required: true, enum: ['RS256'] }
43 },
44
45 // permitted claims
46 claims: ['iss', 'sub', 'aud', 'exp', 'iat', 'nonce', 'acr', 'at_hash'],
47
48 // modify payload schema
49 registeredClaims: {
50 iss: { format: 'StringOrURI', required: true },
51 sub: { format: 'StringOrURI', required: true },
52 aud: { format: 'StringOrURI', required: true },
53 exp: { format: 'IntDate', required: true, default: expires('day') },
54 iat: { format: 'IntDate', required: true, default: nowSeconds },
55 nonce: { format: 'String' },
56 acr: { format: 'String' },
57 at_hash: { format: 'String' }
58 }
59
60})
61
62/**
63 * Verify
64 */
65
66IDToken.verify = function (jwt, options, callback) {
67 var token = IDToken.decode(jwt, options.key)
68
69 if (!token || token instanceof Error) {
70 return callback(new IDTokenError({
71 error: 'Invalid JWT'
72 }))
73 }
74
75 var header = token.header
76 var claims = token.payload
77 var alg = options.alg || 'RS256'
78
79 // mismatching issuer
80 if (claims.iss !== options.iss) {
81 return callback(new IDTokenError({
82 error: 'Mismatching issuer'
83 }))
84 }
85
86 // mismatching audience
87 if (claims.aud.indexOf(options.aud) === -1) {
88 return callback(new IDTokenError({
89 error: 'Mismatching audience'
90 }))
91 }
92
93 // mismatching algorithm
94 if (header.alg !== alg) {
95 return callback(new IDTokenError({
96 error: 'Expected ' + alg + ' signature'
97 }))
98 }
99
100 // expired token
101 if (claims.exp < nowSeconds()) {
102 return callback(new IDTokenError({
103 error: 'Expired token'
104 }))
105 }
106
107 callback(null, token)
108}
109
110/**
111 * Exports
112 */
113
114module.exports = IDToken