diff options
Diffstat (limited to 'browser/components/backup/resources/BackupResource.sys.mjs')
-rw-r--r-- | browser/components/backup/resources/BackupResource.sys.mjs | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/browser/components/backup/resources/BackupResource.sys.mjs b/browser/components/backup/resources/BackupResource.sys.mjs index bde3f0669c..d851eb5199 100644 --- a/browser/components/backup/resources/BackupResource.sys.mjs +++ b/browser/components/backup/resources/BackupResource.sys.mjs @@ -3,7 +3,19 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ // Convert from bytes to kilobytes (not kibibytes). -const BYTES_IN_KB = 1000; +export const BYTES_IN_KB = 1000; + +/** + * Convert bytes to the nearest 10th kilobyte to make the measurements fuzzier. + * + * @param {number} bytes - size in bytes. + * @returns {number} - size in kilobytes rounded to the nearest 10th kilobyte. + */ +export function bytesToFuzzyKilobytes(bytes) { + let sizeInKb = Math.ceil(bytes / BYTES_IN_KB); + let nearestTenthKb = Math.round(sizeInKb / 10) * 10; + return Math.max(nearestTenthKb, 1); +} /** * An abstract class representing a set of data within a user profile @@ -23,6 +35,21 @@ export class BackupResource { } /** + * This must be overridden to return a boolean indicating whether the + * resource requires encryption when being backed up. Encryption should be + * required for particularly sensitive data, such as passwords / credentials, + * cookies, or payment methods. If you're not sure, talk to someone from the + * Privacy team. + * + * @type {boolean} + */ + static get requiresEncryption() { + throw new Error( + "BackupResource::requiresEncryption needs to be overridden." + ); + } + + /** * Get the size of a file. * * @param {string} filePath - path to a file. @@ -40,21 +67,25 @@ export class BackupResource { return null; } - let sizeInKb = Math.ceil(size / BYTES_IN_KB); - // Make the measurement fuzzier by rounding to the nearest 10kb. - let nearestTenthKb = Math.round(sizeInKb / 10) * 10; + let nearestTenthKb = bytesToFuzzyKilobytes(size); - return Math.max(nearestTenthKb, 1); + return nearestTenthKb; } /** * Get the total size of a directory. * * @param {string} directoryPath - path to a directory. + * @param {object} options - A set of additional optional parameters. + * @param {Function} [options.shouldExclude] - an optional callback which based on file path and file type should return true + * if the file should be excluded from the computed directory size. * @returns {Promise<number|null>} - the size of all descendants of the directory in kilobytes, or null if the * directory does not exist, the path is not a directory or the size is unknown. */ - static async getDirectorySize(directoryPath) { + static async getDirectorySize( + directoryPath, + { shouldExclude = () => false } = {} + ) { if (!(await IOUtils.exists(directoryPath))) { return null; } @@ -75,15 +106,20 @@ export class BackupResource { childFilePath ); + if (shouldExclude(childFilePath, childType, directoryPath)) { + continue; + } + if (childSize >= 0) { - let sizeInKb = Math.ceil(childSize / BYTES_IN_KB); - // Make the measurement fuzzier by rounding to the nearest 10kb. - let nearestTenthKb = Math.round(sizeInKb / 10) * 10; - size += Math.max(nearestTenthKb, 1); + let nearestTenthKb = bytesToFuzzyKilobytes(childSize); + + size += nearestTenthKb; } if (childType == "directory") { - let childDirectorySize = await this.getDirectorySize(childFilePath); + let childDirectorySize = await this.getDirectorySize(childFilePath, { + shouldExclude, + }); if (Number.isInteger(childDirectorySize)) { size += childDirectorySize; } @@ -106,4 +142,29 @@ export class BackupResource { async measure(profilePath) { throw new Error("BackupResource::measure needs to be overridden."); } + + /** + * Perform a safe copy of the resource(s) and write them into the backup + * database. The Promise should resolve with an object that can be serialized + * to JSON, as it will be written to the manifest file. This same object will + * be deserialized and passed to restore() when restoring the backup. This + * object can be null if no additional information is needed to restore the + * backup. + * + * @param {string} stagingPath + * The path to the staging folder where copies of the datastores for this + * BackupResource should be written to. + * @param {string} [profilePath=null] + * This is null if the backup is being run on the currently running user + * profile. If, however, the backup is being run on a different user profile + * (for example, it's being run from a BackgroundTask on a user profile that + * just shut down, or during test), then this is a string set to that user + * profile path. + * + * @returns {Promise<object|null>} + */ + // eslint-disable-next-line no-unused-vars + async backup(stagingPath, profilePath = null) { + throw new Error("BackupResource::backup must be overridden"); + } } |