This repository has been archived by the owner on Aug 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
97 lines (79 loc) · 2.99 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
'use strict'
// **Github:** https://github.com/toajs/toa-token
//
// **License:** MIT
const jsonwebtoken = require('jsonwebtoken')
const JWT_OPTIONS = ['algorithm', 'expiresIn', 'notBefore', 'audience', 'issuer',
'jwtid', 'subject', 'noTimestamp', 'header']
module.exports = toaToken
toaToken.jwt = jsonwebtoken
toaToken.JWT = JWT
function toaToken (app, secretOrPrivateKeys, options) {
options = options || {}
const jwt = new JWT(secretOrPrivateKeys)
const useProperty = options.useProperty || 'token'
const authScheme = options.authScheme || 'Bearer'
const getToken = typeof options.getToken === 'function' ? options.getToken : null
const authReg = new RegExp('^' + authScheme.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
if (options.expiresInMinutes && !options.expiresIn) {
options.expiresIn = options.expiresInMinutes * 60
}
const jwtOptions = {}
JWT_OPTIONS.forEach(function (key) {
if (options[key] != null) jwtOptions[key] = options[key]
})
app.verifyToken = app.context.verifyToken = function (payload, opts) {
return jwt.verifyToken(payload, opts || jwtOptions)
}
app.signToken = app.context.signToken = function (payload, opts) {
return jwt.signToken(payload, opts || jwtOptions)
}
app.decodeToken = app.context.decodeToken = function (token, opts) {
return jwt.decodeToken(token, opts || jwtOptions)
}
app.context._toaJsonWebToken = undefined
Object.defineProperty(app.context, useProperty, {
enumerable: true,
configurable: false,
get: function () {
if (this._toaJsonWebToken) return this._toaJsonWebToken
let token
const authorization = this.get('authorization')
if (getToken) token = getToken.call(this)
if (!token && authorization) {
if (authReg.test(authorization)) token = authorization.replace(authReg, '').trim()
if (!token) this.throw(401, 'Invalid authorization')
}
if (!token) this.throw(401, 'No authorization token was found')
try {
this._toaJsonWebToken = jwt.verifyToken(token, jwtOptions)
} catch (err) {
this.throw(401, String(err))
}
return this._toaJsonWebToken
}
})
}
function JWT (secretOrPrivateKeys) {
if (!secretOrPrivateKeys || !secretOrPrivateKeys.length) throw new Error('secretOrPrivateKey should be set')
if (!Array.isArray(secretOrPrivateKeys)) secretOrPrivateKeys = [secretOrPrivateKeys]
this.secretOrPrivateKeys = secretOrPrivateKeys
}
JWT.prototype.signToken = function (payload, options) {
return jsonwebtoken.sign(payload, this.secretOrPrivateKeys[0], options)
}
JWT.prototype.decodeToken = function (token, options) {
return jsonwebtoken.decode(token, options)
}
JWT.prototype.verifyToken = function (token, options) {
let error = null
const secretOrPrivateKeys = this.secretOrPrivateKeys
for (let i = 0, len = secretOrPrivateKeys.length - 1; i <= len; i++) {
try {
return jsonwebtoken.verify(token, secretOrPrivateKeys[i], options)
} catch (err) {
error = err
}
}
throw error
}