dev: sign requests sent to Transloadit (#3517)

* dev: sign requests sent to Transloadit

* Address review comments
This commit is contained in:
Antoine du Hamel 2022-04-21 16:08:28 +02:00 committed by GitHub
parent 305f0d864d
commit a77b039efc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 10 deletions

View file

@ -53,5 +53,6 @@ VITE_TUS_ENDPOINT=https://tusd.tusdemo.net/files/
VITE_XHR_ENDPOINT=https://xhr-server.herokuapp.com/upload
VITE_TRANSLOADIT_KEY=***
VITE_TRANSLOADIT_SECRET=***
VITE_TRANSLOADIT_TEMPLATE=***
VITE_TRANSLOADIT_SERVICE_URL=https://api2.transloadit.com

View file

@ -26,6 +26,8 @@ import Audio from '@uppy/audio'
import Compressor from '@uppy/compressor'
/* eslint-enable import/no-extraneous-dependencies */
import generateSignatureIfSecret from './generateSignatureIfSecret.js'
// DEV CONFIG: create a .env file in the project root directory to customize those values.
const {
VITE_UPLOADER : UPLOADER,
@ -33,17 +35,30 @@ const {
VITE_TUS_ENDPOINT : TUS_ENDPOINT,
VITE_XHR_ENDPOINT : XHR_ENDPOINT,
VITE_TRANSLOADIT_KEY : TRANSLOADIT_KEY,
VITE_TRANSLOADIT_SECRET : TRANSLOADIT_SECRET,
VITE_TRANSLOADIT_TEMPLATE : TRANSLOADIT_TEMPLATE,
VITE_TRANSLOADIT_SERVICE_URL : TRANSLOADIT_SERVICE_URL,
} = import.meta.env
import.meta.env.VITE_TRANSLOADIT_KEY = '***' // to avoid leaking secrets in screenshots.
import.meta.env.VITE_TRANSLOADIT_KEY &&= '***' // to avoid leaking secrets in screenshots.
import.meta.env.VITE_TRANSLOADIT_SECRET &&= '***' // to avoid leaking secrets in screenshots.
console.log(import.meta.env)
// DEV CONFIG: enable or disable Golden Retriever
const RESTORE = false
async function getAssemblyOptions () {
return generateSignatureIfSecret(TRANSLOADIT_SECRET, {
auth: {
key: TRANSLOADIT_KEY,
},
// It's more secure to use a template_id and enable
// Signature Authentication
template_id: TRANSLOADIT_TEMPLATE,
})
}
// Rest is implementation! Obviously edit as necessary...
export default () => {
@ -111,10 +126,7 @@ export default () => {
uppyDashboard.use(Transloadit, {
service: TRANSLOADIT_SERVICE_URL,
waitForEncoding: true,
params: {
auth: { key: TRANSLOADIT_KEY },
template_id: TRANSLOADIT_TEMPLATE,
},
getAssemblyOptions,
})
break
case 'transloadit-s3':
@ -122,10 +134,7 @@ export default () => {
uppyDashboard.use(Transloadit, {
waitForEncoding: true,
importFromUploadURLs: true,
params: {
auth: { key: TRANSLOADIT_KEY },
template_id: TRANSLOADIT_TEMPLATE,
},
getAssemblyOptions,
})
break
case 'transloadit-xhr':

View file

@ -11,7 +11,8 @@ const {
VITE_TUS_ENDPOINT : TUS_ENDPOINT,
} = import.meta.env
import.meta.env.VITE_TRANSLOADIT_KEY = '***' // to avoid leaking secrets in screenshots.
import.meta.env.VITE_TRANSLOADIT_KEY &&= '***' // to avoid leaking secrets in screenshots.
import.meta.env.VITE_TRANSLOADIT_SECRET &&= '***' // to avoid leaking secrets in screenshots.
console.log(import.meta.env)
export default () => {

View file

@ -0,0 +1,34 @@
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 {{ 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 }
}