uppy/private/dev/generateSignatureIfSecret.js

34 lines
1.2 KiB
JavaScript

const enc = new TextEncoder('utf-8')
async function sign (secret, body) {
const algorithm = { name: 'HMAC', hash: 'SHA-384' }
const key = await crypto.subtle.importKey('raw', enc.encode(secret), algorithm, false, ['sign', 'verify'])
const signature = await crypto.subtle.sign(algorithm.name, key, enc.encode(body))
return `sha384:${Array.from(new Uint8Array(signature), x => x.toString(16).padStart(2, '0')).join('')}`
}
function getExpiration (future) {
return new Date(Date.now() + future)
.toISOString()
.replace('T', ' ')
.replace(/\.\d+Z$/, '+00:00')
}
/**
* Adds an expiration date and signs the params object if a secret is passed to
* it. If no secret is given, it returns the same object.
*
* @param {string | undefined} secret
* @param {object} params
* @returns {Promise<{ params: string, signature?: string }>}
*/
export default async function generateSignatureIfSecret (secret, params) {
let signature
if (secret) {
// eslint-disable-next-line no-param-reassign
params.auth.expires = getExpiration(5 * 60 * 1000)
// eslint-disable-next-line no-param-reassign
params = JSON.stringify(params)
signature = await sign(secret, params)
}
return { params, signature }
}