diff --git a/js/modules/debuglogs.js b/js/modules/debuglogs.js new file mode 100644 index 000000000..a753f104d --- /dev/null +++ b/js/modules/debuglogs.js @@ -0,0 +1,48 @@ +/* eslint-env node */ + +const FormData = require('form-data'); +const got = require('got'); + + +const BASE_URL = 'https://debuglogs.org'; + +// Workaround: Submitting `FormData` using native `FormData::submit` procedure +// as integration with `got` results in S3 error saying we haven’t set the +// `Content-Length` header: +const submitFormData = (form, url) => + new Promise((resolve, reject) => { + form.submit(url, (error) => { + if (error) { + return reject(error); + } + + return resolve(); + }); + }); + +// upload :: String -> Promise URL +exports.upload = async (content) => { + const signedForm = await got.get(BASE_URL, { json: true }); + const { fields, url } = signedForm.body; + + const form = new FormData(); + form.append('key', fields.key); + + Object.entries(fields) + .filter(([key]) => key !== 'key') + .forEach(([key, value]) => { + form.append(key, value); + }); + + const contentBuffer = Buffer.from(content, 'utf8'); + const contentType = 'text/plain'; + form.append('Content-Type', contentType); + form.append('file', contentBuffer, { + contentType, + filename: 'signal-desktop-debug-log.txt', + }); + + await submitFormData(form, url); + + return `${BASE_URL}/${fields.key}`; +}; diff --git a/test/modules/debuglogs_test.js b/test/modules/debuglogs_test.js new file mode 100644 index 000000000..3a6e45e90 --- /dev/null +++ b/test/modules/debuglogs_test.js @@ -0,0 +1,17 @@ +const { assert } = require('chai'); +const got = require('got'); + +const debuglogs = require('../../js/modules/debuglogs'); + + +describe('debuglogs', () => { + describe('upload', () => { + it('should upload log content', async () => { + const nonce = Math.random().toString().slice(2); + const url = await debuglogs.upload(nonce); + + const { body } = await got.get(url); + assert.equal(nonce, body); + }); + }); +});