uppy/private/dev/generateSignatureIfSecret.js

42 lines
1.1 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) {
params.auth.expires = getExpiration(5 * 60 * 1000)
params = JSON.stringify(params)
signature = await sign(secret, params)
}
return { params, signature }
}