storage-upload/api/jwt/encode.mjs

59 lines
1.5 KiB
JavaScript
Raw Normal View History

import crypto from 'crypto'
import * as base64UrlSafe from './base64urlsafe.mjs'
import defaults from '../defaults.mjs'
export default function encode(orgHeader, orgBody, privateKeyPassword = null, disableAutofill = false) {
if (
typeof orgHeader !== 'object' ||
typeof orgBody !== 'object'
) {
throw new Error('both header and body should be of type object')
}
let header = defaults(orgHeader)
let body = defaults(orgBody)
if (!header.alg) {
header.alg = 'HS256'
}
if (!header.typ) {
header.typ = 'JWT'
}
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'
)
}
if (!body.iat && !disableAutofill) {
body.iat = Math.floor(Date.now() / 1000)
}
if (!body.exp && !disableAutofill) {
body.exp = body.iat + 300
}
// 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
}