Skip to content

Commit

Permalink
address comments by @seaerchin and @mantariksh
Browse files Browse the repository at this point in the history
  • Loading branch information
frankchn committed May 7, 2021
1 parent 4972663 commit cbbe9ac
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 18 deletions.
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,49 @@ app.post(
}
)

// Example for submissions with attachments
app.post(
'/submissions-attachment',
// Endpoint authentication by verifying signatures
function (req, res, next) {
try {
formsg.webhooks.authenticate(req.get('X-FormSG-Signature'), POST_URI)
// Continue processing the POST body
return next()
} catch (e) {
return res.status(401).send({ message: 'Unauthorized' })
}
},
// Parse JSON from raw request body
express.json(),
// Decrypt the submission and attachments
async function (req, res, next) {
// `req.body.data` is an object fulfilling the DecryptParams interface.
// interface DecryptParams {
// encryptedContent: EncryptedContent
// version: number
// verifiedContent?: EncryptedContent
// }
/** @type {{content: DecryptedContent, attachments: DecryptedAttachments}} */
const submission = formsg.crypto.decryptWithAttachments(
formSecretKey,
// If `verifiedContent` is provided in `req.body.data`, the return object
// will include a verified key.
req.body.data
)

// If the decryption failed, submission will be `null`.
if (submission) {
// Continue processing the submission

// processSubmission(submission.content)
// processAttachments(submission.attachments)
} else {
// Could not decrypt the submission
}
}
)

app.listen(8080, () => console.log('Running on port 8080'))
```

Expand Down
1 change: 0 additions & 1 deletion spec/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,6 @@ describe('Crypto', function () {
attachmentDownloadUrls: { '6e771c946b3c5100240368e5': 'https://some.s3.url/some/encrypted/file' },
version: INTERNAL_TEST_VERSION,
})
mockAxios.mockResponse({ data: { encryptedFile: uploadedFile }})
const decryptedContents = await decryptedFilesPromise

// Assert
Expand Down
42 changes: 25 additions & 17 deletions src/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,32 +220,40 @@ export default class Crypto {
if (decryptedContent === null) return null

// Retrieve all original filenames for attachments for easy lookup
for (const i in decryptedContent.responses) {
const response = decryptedContent.responses[i]
decryptedContent.responses.forEach((response) => {
if (response.fieldType === 'attachment' && response.answer) {
filenames[response._id] = response.answer
}
}
})

const downloadPromises : Array<Promise<void>> = []
for (let fieldId in attachmentRecords) {
const downloadResponse = await axios.get(attachmentRecords[fieldId], { responseType: 'json' })
if (downloadResponse.status !== 200) return null
// Original name for the file is not found
if (filenames[fieldId] === undefined) return null

const encryptedAttachment: EncryptedAttachmentContent = downloadResponse.data
const encryptedFile: EncryptedFileContent = {
submissionPublicKey: encryptedAttachment.encryptedFile.submissionPublicKey,
nonce: encryptedAttachment.encryptedFile.nonce,
binary: decodeBase64(encryptedAttachment.encryptedFile.binary),
}
const decryptedFile = await this.decryptFile(formSecretKey, encryptedFile)
downloadPromises.push(
axios.get(attachmentRecords[fieldId], { responseType: 'json' })
.then((downloadResponse) => {
if (downloadResponse.status !== 200) throw new Error("Download failed")

// Decryption for a file failed
if (decryptedFile === null) return null
const encryptedAttachment: EncryptedAttachmentContent = downloadResponse.data
const encryptedFile: EncryptedFileContent = {
submissionPublicKey: encryptedAttachment.encryptedFile.submissionPublicKey,
nonce: encryptedAttachment.encryptedFile.nonce,
binary: decodeBase64(encryptedAttachment.encryptedFile.binary),
}

// Original name for the file is not found
if (filenames[fieldId] === undefined) return null
return this.decryptFile(formSecretKey, encryptedFile)
}).then((decryptedFile) => {
if (decryptedFile === null) throw new Error("Attachment decryption failed")
decryptedRecords[fieldId] = { filename: filenames[fieldId], content: decryptedFile }
}))
}

decryptedRecords[fieldId] = { filename: filenames[fieldId], content: decryptedFile }
try {
await Promise.all(downloadPromises)
} catch (e) {
return null
}

return {
Expand Down

0 comments on commit cbbe9ac

Please sign in to comment.