2022-07-06 15:04:18 +03:00
|
|
|
/* eslint-disable no-unused-expressions */
|
|
|
|
/* eslint-disable no-undef */
|
2023-06-30 17:01:56 +03:00
|
|
|
import { BaseItemCounts } from './lib/BaseItemCounts.js'
|
2022-07-06 15:04:18 +03:00
|
|
|
import * as Factory from './lib/factory.js'
|
|
|
|
chai.use(chaiAsPromised)
|
|
|
|
const expect = chai.expect
|
|
|
|
|
|
|
|
describe('backups', function () {
|
|
|
|
before(function () {
|
|
|
|
localStorage.clear()
|
|
|
|
})
|
|
|
|
|
|
|
|
after(function () {
|
|
|
|
localStorage.clear()
|
|
|
|
})
|
|
|
|
|
|
|
|
beforeEach(async function () {
|
|
|
|
this.application = await Factory.createInitAppWithFakeCrypto()
|
|
|
|
this.email = UuidGenerator.GenerateUuid()
|
|
|
|
this.password = UuidGenerator.GenerateUuid()
|
|
|
|
})
|
|
|
|
|
|
|
|
afterEach(async function () {
|
|
|
|
await Factory.safeDeinit(this.application)
|
|
|
|
this.application = null
|
|
|
|
})
|
|
|
|
|
|
|
|
it('backup file should have a version number', async function () {
|
|
|
|
let data = await this.application.createDecryptedBackupFile()
|
2023-07-04 15:31:50 +03:00
|
|
|
expect(data.version).to.equal(this.application.encryptionService.getLatestVersion())
|
2022-07-06 15:04:18 +03:00
|
|
|
await this.application.addPasscode('passcode')
|
|
|
|
data = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
2023-07-04 15:31:50 +03:00
|
|
|
expect(data.version).to.equal(this.application.encryptionService.getLatestVersion())
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('no passcode + no account backup file should have correct number of items', async function () {
|
|
|
|
await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
|
|
|
|
const data = await this.application.createDecryptedBackupFile()
|
2023-06-30 17:01:56 +03:00
|
|
|
const offsetForNewItems = 2
|
|
|
|
const offsetForNoItemsKey = -1
|
|
|
|
expect(data.items.length).to.equal(BaseItemCounts.DefaultItems + offsetForNewItems + offsetForNoItemsKey)
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('passcode + no account backup file should have correct number of items', async function () {
|
|
|
|
const passcode = 'passcode'
|
|
|
|
await this.application.addPasscode(passcode)
|
|
|
|
await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
|
|
|
|
|
|
|
|
// Encrypted backup without authorization
|
|
|
|
const encryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(encryptedData.items.length).to.equal(BaseItemCounts.DefaultItems + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
// Encrypted backup with authorization
|
|
|
|
Factory.handlePasswordChallenges(this.application, passcode)
|
|
|
|
const authorizedEncryptedData = await this.application.createEncryptedBackupFile()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(authorizedEncryptedData.items.length).to.equal(BaseItemCounts.DefaultItems + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('no passcode + account backup file should have correct number of items', async function () {
|
|
|
|
await Factory.registerUserToApplication({
|
|
|
|
application: this.application,
|
|
|
|
email: this.email,
|
|
|
|
password: this.password,
|
|
|
|
})
|
|
|
|
|
|
|
|
await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
|
|
|
|
|
|
|
|
// Encrypted backup without authorization
|
|
|
|
const encryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(encryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
Factory.handlePasswordChallenges(this.application, this.password)
|
|
|
|
|
|
|
|
// Decrypted backup
|
|
|
|
const decryptedData = await this.application.createDecryptedBackupFile()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(decryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccountWithoutItemsKey + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
// Encrypted backup with authorization
|
|
|
|
const authorizedEncryptedData = await this.application.createEncryptedBackupFile()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(authorizedEncryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('passcode + account backup file should have correct number of items', async function () {
|
|
|
|
this.timeout(10000)
|
|
|
|
const passcode = 'passcode'
|
|
|
|
await this.application.register(this.email, this.password)
|
|
|
|
Factory.handlePasswordChallenges(this.application, this.password)
|
|
|
|
await this.application.addPasscode(passcode)
|
|
|
|
await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
|
|
|
|
|
|
|
|
// Encrypted backup without authorization
|
|
|
|
const encryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(encryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
Factory.handlePasswordChallenges(this.application, passcode)
|
|
|
|
|
|
|
|
// Decrypted backup
|
|
|
|
const decryptedData = await this.application.createDecryptedBackupFile()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(decryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccountWithoutItemsKey + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
// Encrypted backup with authorization
|
|
|
|
const authorizedEncryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(authorizedEncryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('backup file item should have correct fields', async function () {
|
|
|
|
await Factory.createSyncedNote(this.application)
|
|
|
|
let backupData = await this.application.createDecryptedBackupFile()
|
2023-07-12 14:53:29 +03:00
|
|
|
let rawItem = backupData.items.find((i) => i.content_type === ContentType.TYPES.Note)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
expect(rawItem.fields).to.not.be.ok
|
|
|
|
expect(rawItem.source).to.not.be.ok
|
|
|
|
expect(rawItem.dirtyIndex).to.not.be.ok
|
|
|
|
expect(rawItem.format).to.not.be.ok
|
|
|
|
expect(rawItem.uuid).to.be.ok
|
|
|
|
expect(rawItem.content_type).to.be.ok
|
|
|
|
expect(rawItem.content).to.be.ok
|
|
|
|
expect(rawItem.created_at).to.be.ok
|
|
|
|
expect(rawItem.updated_at).to.be.ok
|
|
|
|
|
|
|
|
await Factory.registerUserToApplication({
|
|
|
|
application: this.application,
|
|
|
|
email: this.email,
|
|
|
|
password: this.password,
|
|
|
|
})
|
|
|
|
|
|
|
|
backupData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
2023-07-12 14:53:29 +03:00
|
|
|
rawItem = backupData.items.find((i) => i.content_type === ContentType.TYPES.Note)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
expect(rawItem.fields).to.not.be.ok
|
|
|
|
expect(rawItem.source).to.not.be.ok
|
|
|
|
expect(rawItem.dirtyIndex).to.not.be.ok
|
|
|
|
expect(rawItem.format).to.not.be.ok
|
|
|
|
expect(rawItem.uuid).to.be.ok
|
|
|
|
expect(rawItem.content_type).to.be.ok
|
|
|
|
expect(rawItem.content).to.be.ok
|
|
|
|
expect(rawItem.created_at).to.be.ok
|
|
|
|
expect(rawItem.updated_at).to.be.ok
|
|
|
|
})
|
|
|
|
|
|
|
|
it('downloading backup if item is error decrypting should succeed', async function () {
|
|
|
|
await Factory.createSyncedNote(this.application)
|
|
|
|
|
|
|
|
const note = await Factory.createSyncedNote(this.application)
|
|
|
|
|
2023-07-04 15:31:50 +03:00
|
|
|
const encrypted = await this.application.encryptionService.encryptSplitSingle({
|
2022-07-06 15:04:18 +03:00
|
|
|
usesItemsKeyWithKeyLookup: {
|
|
|
|
items: [note.payload],
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
const errored = encrypted.copy({
|
|
|
|
errorDecrypting: true,
|
|
|
|
})
|
|
|
|
|
2023-06-30 17:01:56 +03:00
|
|
|
await this.application.payloadManager.emitPayload(errored)
|
2022-07-06 15:04:18 +03:00
|
|
|
|
|
|
|
const erroredItem = this.application.itemManager.findAnyItem(errored.uuid)
|
|
|
|
|
|
|
|
expect(erroredItem.errorDecrypting).to.equal(true)
|
|
|
|
|
|
|
|
const backupData = await this.application.createDecryptedBackupFile()
|
|
|
|
|
2023-06-30 17:01:56 +03:00
|
|
|
expect(backupData.items.length).to.equal(BaseItemCounts.DefaultItemsNoAccounNoItemsKey + 2)
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('decrypted backup file should not have keyParams', async function () {
|
|
|
|
const backup = await this.application.createDecryptedBackupFile()
|
|
|
|
expect(backup).to.not.haveOwnProperty('keyParams')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('decrypted backup file with account should not have keyParams', async function () {
|
|
|
|
const application = await Factory.createInitAppWithFakeCrypto()
|
|
|
|
const password = UuidGenerator.GenerateUuid()
|
|
|
|
await Factory.registerUserToApplication({
|
|
|
|
application: application,
|
|
|
|
email: UuidGenerator.GenerateUuid(),
|
|
|
|
password: password,
|
|
|
|
})
|
|
|
|
|
|
|
|
Factory.handlePasswordChallenges(application, password)
|
|
|
|
|
|
|
|
const backup = await application.createDecryptedBackupFile()
|
|
|
|
|
|
|
|
expect(backup).to.not.haveOwnProperty('keyParams')
|
|
|
|
|
|
|
|
await Factory.safeDeinit(application)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('encrypted backup file should have keyParams', async function () {
|
|
|
|
await this.application.addPasscode('passcode')
|
|
|
|
const backup = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
|
|
|
expect(backup).to.haveOwnProperty('keyParams')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('decrypted backup file should not have itemsKeys', async function () {
|
|
|
|
const backup = await this.application.createDecryptedBackupFile()
|
2023-07-12 14:53:29 +03:00
|
|
|
expect(backup.items.some((item) => item.content_type === ContentType.TYPES.ItemsKey)).to.be.false
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('encrypted backup file should have itemsKeys', async function () {
|
|
|
|
await this.application.addPasscode('passcode')
|
|
|
|
const backup = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
2023-07-12 14:53:29 +03:00
|
|
|
expect(backup.items.some((item) => item.content_type === ContentType.TYPES.ItemsKey)).to.be.true
|
2022-07-06 15:04:18 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
it('backup file with no account and no passcode should be decrypted', async function () {
|
|
|
|
const note = await Factory.createSyncedNote(this.application)
|
|
|
|
const backup = await this.application.createDecryptedBackupFile()
|
|
|
|
expect(backup).to.not.haveOwnProperty('keyParams')
|
2023-07-12 14:53:29 +03:00
|
|
|
expect(backup.items.some((item) => item.content_type === ContentType.TYPES.ItemsKey)).to.be.false
|
|
|
|
expect(backup.items.find((item) => item.content_type === ContentType.TYPES.Note).uuid).to.equal(note.uuid)
|
2022-07-06 15:04:18 +03:00
|
|
|
let error
|
|
|
|
try {
|
|
|
|
await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
|
|
|
|
} catch (e) {
|
|
|
|
error = e
|
|
|
|
}
|
|
|
|
expect(error).to.be.ok
|
|
|
|
})
|
|
|
|
})
|