2021-07-03 13:56:53 +00:00
|
|
|
import crypto from 'crypto'
|
|
|
|
import * as base64UrlSafe from './base64urlsafe.mjs'
|
2021-10-09 00:11:52 +00:00
|
|
|
import defaults from '../defaults.mjs'
|
2021-07-03 13:56:53 +00:00
|
|
|
|
2021-10-11 00:21:57 +00:00
|
|
|
export default function encode(orgHeader, orgBody, privateKeyPassword = null, disableAutofill = false) {
|
2021-07-03 13:56:53 +00:00
|
|
|
if (
|
2021-10-11 00:21:57 +00:00
|
|
|
typeof orgHeader !== 'object' ||
|
|
|
|
typeof orgBody !== 'object'
|
2021-07-03 13:56:53 +00:00
|
|
|
) {
|
|
|
|
throw new Error('both header and body should be of type object')
|
|
|
|
}
|
|
|
|
|
2021-10-11 00:21:57 +00:00
|
|
|
let header = defaults(orgHeader)
|
|
|
|
let body = defaults(orgBody)
|
|
|
|
|
|
|
|
if (!header.alg) {
|
|
|
|
header.alg = 'HS256'
|
|
|
|
}
|
|
|
|
if (!header.typ) {
|
|
|
|
header.typ = 'JWT'
|
|
|
|
}
|
|
|
|
|
2021-07-03 13:56:53 +00:00
|
|
|
let hmacAlgo = null
|
|
|
|
switch (header.alg) {
|
|
|
|
case 'HS256':
|
|
|
|
hmacAlgo = 'sha256'
|
|
|
|
break
|
|
|
|
case 'HS384':
|
|
|
|
hmacAlgo = 'sha384'
|
|
|
|
break
|
|
|
|
case 'HS512':
|
|
|
|
hmacAlgo = 'sha512'
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
throw new Error(
|
|
|
|
'Only alg HS256, HS384 and HS512 are supported'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-10-09 00:11:52 +00:00
|
|
|
if (!body.iat && !disableAutofill) {
|
|
|
|
body.iat = Math.floor(Date.now() / 1000)
|
|
|
|
}
|
|
|
|
if (!body.exp && !disableAutofill) {
|
|
|
|
body.exp = body.iat + 300
|
|
|
|
}
|
|
|
|
|
2021-07-03 13:56:53 +00:00
|
|
|
// Base64 encode header and body
|
|
|
|
let headerBase64 = base64UrlSafe.encode(Buffer.from(JSON.stringify(header)))
|
|
|
|
let bodyBase64 = base64UrlSafe.encode(Buffer.from(JSON.stringify(body)))
|
|
|
|
let headerBodyBase64 = headerBase64 + '.' + bodyBase64
|
|
|
|
|
|
|
|
const hmac = crypto.createHmac(hmacAlgo, privateKeyPassword)
|
|
|
|
hmac.update(headerBodyBase64)
|
|
|
|
let signatureBuffer = hmac.digest()
|
|
|
|
|
|
|
|
// Construct final JWT
|
|
|
|
let signatureBase64 = base64UrlSafe.encode(signatureBuffer)
|
|
|
|
return headerBodyBase64 + '.' + signatureBase64
|
|
|
|
}
|