-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/PB-33235_Convert-formData-file-into-a-json-seri…
…alisable-in-offscreen' into 'release' PB-33235 Convert formData file into a json serialisable in offscreen See merge request passbolt/passbolt-browser-extension!846
- Loading branch information
Showing
9 changed files
with
353 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,61 @@ | ||
/** | ||
* Transforms a base 64 encoded file content into a file object. | ||
* Useful when we need to transmit a file from the content code to the add-on code. | ||
* @param string b64Data | ||
* @param string contentType | ||
* @param integer sliceSize | ||
* @returns {*} | ||
* Passbolt ~ Open source password manager for teams | ||
* Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* | ||
* Licensed under GNU Affero General Public License version 3 of the or any later version. | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License | ||
* @link https://www.passbolt.com Passbolt(tm) | ||
* @since 4.8.0 | ||
*/ | ||
function b64ToBlob(b64Data, contentType, sliceSize) { | ||
contentType = contentType || ''; | ||
sliceSize = sliceSize || 512; | ||
|
||
const byteCharacters = atob(b64Data); | ||
const byteArrays = []; | ||
/** | ||
* The class that deals with Passbolt to convert base64. | ||
*/ | ||
class Base64Utils { | ||
/** | ||
* Transforms a base 64 encoded file content into a file object. | ||
* Useful when we need to transmit a file from the content code to the add-on code. | ||
* @param {string} b64Data The base64 data | ||
* @param {string} contentType The content type | ||
* @param {number} sliceSize The slice size | ||
* @returns {*} | ||
*/ | ||
static base64ToBlob(b64Data, contentType = "", sliceSize = 512) { | ||
const byteCharacters = atob(b64Data); | ||
const byteArrays = []; | ||
|
||
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { | ||
const slice = byteCharacters.slice(offset, offset + sliceSize); | ||
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { | ||
const slice = byteCharacters.slice(offset, offset + sliceSize); | ||
|
||
const byteNumbers = new Array(slice.length); | ||
for (let i = 0; i < slice.length; i++) { | ||
byteNumbers[i] = slice.charCodeAt(i); | ||
} | ||
const byteNumbers = new Array(slice.length); | ||
for (let i = 0; i < slice.length; i++) { | ||
byteNumbers[i] = slice.charCodeAt(i); | ||
} | ||
|
||
const byteArray = new Uint8Array(byteNumbers); | ||
const byteArray = new Uint8Array(byteNumbers); | ||
|
||
byteArrays.push(byteArray); | ||
byteArrays.push(byteArray); | ||
} | ||
|
||
return new Blob(byteArrays, {type: contentType}); | ||
} | ||
|
||
const blob = new Blob(byteArrays, {type: contentType}); | ||
return blob; | ||
/** | ||
* Transforms a file object into a base 64 encoded file content. | ||
* @param {Blob} blob | ||
* @returns {Promise<string>} | ||
*/ | ||
static blobToBase64(blob) { | ||
return new Promise(resolve => { | ||
const reader = new FileReader(); | ||
reader.onloadend = () => resolve(reader.result); | ||
reader.readAsDataURL(blob); | ||
}); | ||
} | ||
} | ||
|
||
export default b64ToBlob; | ||
export default Base64Utils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* Passbolt ~ Open source password manager for teams | ||
* Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* | ||
* Licensed under GNU Affero General Public License version 3 of the or any later version. | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License | ||
* @link https://www.passbolt.com Passbolt(tm) | ||
* @since 4.8.0 | ||
*/ | ||
|
||
import Base64Utils from "./base64"; | ||
|
||
/** | ||
* The class that deals with Passbolt to convert formData. | ||
*/ | ||
class FormDataUtils { | ||
/** | ||
* Transform a form data to an array of object | ||
* @param {FormData} formData The form data | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
static async formDataToArray(formData) { | ||
const formDataSerialized = []; | ||
for (const [key, value] of formData.entries()) { | ||
const formDataObject = { | ||
key: key | ||
}; | ||
// BLOB in FormData is transformed into a File | ||
if (value instanceof File) { | ||
formDataObject.value = await Base64Utils.blobToBase64(value); | ||
formDataObject.name = value.name; | ||
formDataObject.type = FormDataUtils.TYPE_FILE; | ||
} else { | ||
formDataObject.value = value; | ||
formDataObject.type = FormDataUtils.TYPE_SCALAR; | ||
} | ||
formDataSerialized.push(formDataObject); | ||
} | ||
return formDataSerialized; | ||
} | ||
|
||
/** | ||
* Transform an array of object to a form data | ||
* @param {Array<Object>} array | ||
* @return {FormData} | ||
*/ | ||
static arrayToFormData(array) { | ||
const formData = new FormData(); | ||
array.forEach(data => { | ||
if (data.type === FormDataUtils.TYPE_SCALAR) { | ||
formData.append(data.key, data.value); | ||
} else { | ||
const base64UrlSplit = data.value.split(','); | ||
const blobBase64 = base64UrlSplit[1]; | ||
const mimeType = base64UrlSplit[0].split(':')[1].split(';')[0]; | ||
const blob = Base64Utils.base64ToBlob(blobBase64, mimeType); | ||
formData.append(data.key, blob, data.name); | ||
} | ||
}); | ||
return formData; | ||
} | ||
|
||
/** | ||
* Get the type scalar | ||
* @return {string} | ||
*/ | ||
static get TYPE_SCALAR() { | ||
return "SCALAR"; | ||
} | ||
|
||
/** | ||
* Get the type file | ||
* @return {string} | ||
*/ | ||
static get TYPE_FILE() { | ||
return "FILE"; | ||
} | ||
|
||
/** | ||
* Get the type blob | ||
* @return {string} | ||
* @constructor | ||
*/ | ||
static get TYPE_BLOB() { | ||
return "FILE"; | ||
} | ||
} | ||
|
||
export default FormDataUtils; |
49 changes: 49 additions & 0 deletions
49
src/all/background_page/utils/format/formDataUtils.test.data.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* Passbolt ~ Open source password manager for teams | ||
* Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* | ||
* Licensed under GNU Affero General Public License version 3 of the or any later version. | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License | ||
* @link https://www.passbolt.com Passbolt(tm) | ||
* @since 4.8.0 | ||
*/ | ||
|
||
export const formDataString = () => { | ||
const formDataBody = new FormData(); | ||
formDataBody.append("prop1", "value 1"); | ||
formDataBody.append("prop1", "value 2"); | ||
return formDataBody; | ||
}; | ||
|
||
export const formDataFile = () => { | ||
const formDataBody = new FormData(); | ||
const file1 = new File(['test'], "file 1", {type: 'image/png'}); | ||
const file2 = new File(['test'], "file 2", {type: 'image/png'}); | ||
formDataBody.append("file", file1, "file 1"); | ||
formDataBody.append("file", file2, "file 2"); | ||
return formDataBody; | ||
}; | ||
|
||
export const formDataBlob = () => { | ||
const formDataBody = new FormData(); | ||
const blob1 = new Blob(['test'], {type: 'text/plain'}); | ||
const blob2 = new Blob(['test'], {type: 'text/plain'}); | ||
formDataBody.append("blob", blob1, "blob 1"); | ||
formDataBody.append("blob", blob2, "blob 2"); | ||
return formDataBody; | ||
}; | ||
|
||
export const formDataMixed = () => { | ||
const formDataBody = new FormData(); | ||
formDataBody.append("prop1", "value 1"); | ||
const file = new File(['test'], "file 1", {type: 'image/png'}); | ||
formDataBody.append("file", file, "file 1"); | ||
const blob = new Blob(['test'], {type: 'text/plain'}); | ||
formDataBody.append("blob", blob, "blob 1"); | ||
return formDataBody; | ||
}; | ||
|
105 changes: 105 additions & 0 deletions
105
src/all/background_page/utils/format/formDataUtils.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/** | ||
* Passbolt ~ Open source password manager for teams | ||
* Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* | ||
* Licensed under GNU Affero General Public License version 3 of the or any later version. | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) | ||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License | ||
* @link https://www.passbolt.com Passbolt(tm) | ||
* @since 4.8.0 | ||
*/ | ||
import {formDataMixed, formDataString} from "./formDataUtils.test.data"; | ||
import FormDataUtils from "./formDataUtils"; | ||
import {formDataBlob, formDataFile} from "./formDataUtils.test.data"; | ||
|
||
describe("FormDataUtils", () => { | ||
beforeEach(() => { | ||
jest.resetModules(); | ||
}); | ||
|
||
describe("FormDataUtils::formDataToArray", () => { | ||
it("Should create an array of scalar object", async() => { | ||
expect.assertions(1); | ||
// data mocked | ||
const formData = formDataString(); | ||
// process | ||
const arrayObject = await FormDataUtils.formDataToArray(formData); | ||
// expectations | ||
const expectedArray = [ | ||
{key: "prop1", value: "value 1", type: FormDataUtils.TYPE_SCALAR}, | ||
{key: "prop1", value: "value 2", type: FormDataUtils.TYPE_SCALAR} | ||
]; | ||
expect(arrayObject).toStrictEqual(expectedArray); | ||
}); | ||
|
||
it("Should create an array of file object", async() => { | ||
expect.assertions(1); | ||
// data mocked | ||
const formData = formDataFile(); | ||
// process | ||
const arrayObject = await FormDataUtils.formDataToArray(formData); | ||
// expectations | ||
const expectedArray = [ | ||
{key: "file", value: "data:image/png;base64,dGVzdA==", name: "file 1", type: FormDataUtils.TYPE_FILE}, | ||
{key: "file", value: "data:image/png;base64,dGVzdA==", name: "file 2", type: FormDataUtils.TYPE_FILE} | ||
]; | ||
expect(arrayObject).toStrictEqual(expectedArray); | ||
}); | ||
|
||
it("Should create an array of blob object", async() => { | ||
expect.assertions(1); | ||
// data mocked | ||
const formData = formDataBlob(); | ||
// process | ||
const arrayObject = await FormDataUtils.formDataToArray(formData); | ||
// expectations | ||
const expectedArray = [ | ||
{key: "blob", value: "data:text/plain;base64,dGVzdA==", name: "blob 1", type: FormDataUtils.TYPE_BLOB}, | ||
{key: "blob", value: "data:text/plain;base64,dGVzdA==", name: "blob 2", type: FormDataUtils.TYPE_BLOB} | ||
]; | ||
expect(arrayObject).toStrictEqual(expectedArray); | ||
}); | ||
|
||
it("Should create an array of mixed object", async() => { | ||
expect.assertions(1); | ||
// data mocked | ||
const formData = formDataMixed(); | ||
// process | ||
const arrayObject = await FormDataUtils.formDataToArray(formData); | ||
// expectations | ||
const expectedArray = [ | ||
{key: "prop1", value: "value 1", type: FormDataUtils.TYPE_SCALAR}, | ||
{key: "file", value: "data:image/png;base64,dGVzdA==", name: "file 1", type: FormDataUtils.TYPE_FILE}, | ||
{key: "blob", value: "data:text/plain;base64,dGVzdA==", name: "blob 1", type: FormDataUtils.TYPE_BLOB} | ||
]; | ||
expect(arrayObject).toStrictEqual(expectedArray); | ||
}); | ||
}); | ||
|
||
describe("FormDataUtils::arrayToFormData", () => { | ||
it("should form the same formData string from the origin", async() => { | ||
expect.assertions(1); | ||
// data mocked | ||
const formData = formDataString(); | ||
// process | ||
const arrayObject = await FormDataUtils.formDataToArray(formData); | ||
const formDataReceived = FormDataUtils.arrayToFormData(arrayObject); | ||
// expectations | ||
expect(formData).toStrictEqual(formDataReceived); | ||
}); | ||
|
||
it("should form the same formData mixed from the origin", async() => { | ||
expect.assertions(1); | ||
// data mocked | ||
const formData = formDataMixed(); | ||
// process | ||
const arrayObject = await FormDataUtils.formDataToArray(formData); | ||
const formDataReceived = FormDataUtils.arrayToFormData(arrayObject); | ||
// expectations | ||
expect(formData).toStrictEqual(formDataReceived); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.