Skip to content

Commit

Permalink
Update sync logic
Browse files Browse the repository at this point in the history
  • Loading branch information
alchaplinsky committed Nov 1, 2022
1 parent f934b82 commit 73c664e
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 94 deletions.
12 changes: 4 additions & 8 deletions src/main/application/events/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ export const onVaultSyncImport = function () {

export const onVaultSyncConnect = function () {
if (!this.sync.isConfigured()) {
this.sync.setup().then(() => {
this.sync.perform().then(() => {
this.window.send('vault:sync:connected')
//return this.pullVaultData()
})
}
}
Expand All @@ -47,16 +46,13 @@ export const onVaultSyncStart = function () {
this.sync
.perform()
.then(() => {
this.window.send('vault:sync:stopped', {
success: true
})
this.window.send('vault:sync:stopped', { success: true })
})
.catch(error => {
this.window.send('vault:sync:stopped', {
success: false
success: false,
error
})
/* eslint-disable-next-line no-console */
console.log(error)
})
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/application/sync/gdrive/__mocks__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const _import = jest.fn()
const push = jest.fn(() => {
return Promise.resolve()
})
const fileExists = jest.fn(() => Promise.resolve(true))

const pull = jest.fn(() => {
return Promise.resolve({
entries: [{ id: '1', password: 'password' }],
Expand All @@ -21,6 +23,7 @@ module.exports = jest.fn(() => {
return {
isConfigured: isConfigured,
setup: setup,
fileExists: fileExists,
disconnect: disconnect,
import: _import,
pull: pull,
Expand Down
21 changes: 19 additions & 2 deletions src/main/application/sync/gdrive/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,32 @@ export default class GDrive {
return await this.drive.readFile(fileId)
}

async fileExists() {
this.auth.loadCredentials()
const folderId = await this.drive.folderExists(this.folderName)
if (!folderId) return false

const fileId = await this.drive.fileExists(this.fileName, folderId)
return !!fileId
}

async createRemoteVault(data) {
const folderId = await this.drive.createFolder(this.folderName)
let folderId = await this.drive.folderExists(this.folderName)
if (!folderId) {
folderId = await this.drive.createFolder(this.folderName)
}

if (!folderId) throw Error('Failed to create Swifty folder on GDrive')

return await this.createRemoteVaultFile(folderId, data)
}

async createRemoteVaultFile(folderId, data) {
const fileId = await this.drive.createFile(this.fileName, folderId, data)
let fileId = await this.drive.fileExists(this.fileName, folderId)
if (!fileId) {
fileId = await this.drive.createFile(this.fileName, folderId, data)
}

if (!fileId) throw Error('Failed to create vault file on GDrive')

return fileId
Expand Down
97 changes: 66 additions & 31 deletions src/main/application/sync/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
import GDrive from './gdrive'
import { mergeData } from './base/merge'

const NO_INTERNET_CONNECTION = 'Swifty seems to be offline'
const NOT_CONFIGURED = 'Sync is not configured'
const FAILED_TO_FIND_REMOTE_VAULT = 'Failed to find remote vault file'
const FAILED_TO_CREATE_REMOTE_VAULT = 'Failed to create remote vault file'
const FAILED_TO_READ_REMOTE_VAULT = 'Failed to read remote vault file'
const FAILED_TO_WRITE_REMOTE_VAULT = 'Failed to write remote vault file'
const FAILED_TO_DECRYPT_REMOTE_VAULT = 'Failed to decrypt remote vault file'

const OFFLINE_CODE = 'ENOTFOUND'

export default class Sync {
initialize(cryptor, vault) {
this.cryptor = cryptor
this.vault = vault
this.provider = new GDrive(cryptor)
}

isConfigured() {
return this.provider.isConfigured()
async perform() {
if (!this.isConfigured()) throw Error(NOT_CONFIGURED)

if (!(await this.remoteVaultExists())) {
await this.createRemoteVault()
return this.pushRemoteVault()
} else {
const data = await this.pullRemoteVault()
const merged = await this.mergeData(data)
return this.pushRemoteVault(merged)
}
}

setup() {
return this.provider.setup().then(() => {
return this.provider
.pull()
.then(data => {
this.mergeAndPush(data)
})
.catch(() => this.provider.push(this.vault.read()))
})
isConfigured() {
return this.provider.isConfigured()
}

disconnect() {
Expand All @@ -31,25 +43,48 @@ export default class Sync {
return this.provider.import()
}

async perform() {
return this.provider
.pull()
.then(data => this.mergeAndPush(data))
.catch(error => {
if (error.message === 'Vault file was not found on GDrive') {
return this.provider.push(this.vault.read())
}
throw error
})
}

async mergeAndPush(data) {
if (this.vault.isDecryptable(data, this.cryptor)) {
const merged = mergeData(this.vault.read(), data, this.cryptor)
this.vault.write(merged)
await this.provider.push(merged)
return merged
}
throw Error('Remote vault file is invalid')
// ***
// Methods below are private and should not be used directly
// ***

remoteVaultExists() {
return this.provider.fileExists().catch(error => {
if (error.code === OFFLINE_CODE) throw Error(NO_INTERNET_CONNECTION)

throw Error(FAILED_TO_FIND_REMOTE_VAULT)
})
}

createRemoteVault() {
return this.provider.createRemoteVault(this.vault.read()).catch(error => {
if (error.code === OFFLINE_CODE) throw Error(NO_INTERNET_CONNECTION)

throw Error(FAILED_TO_CREATE_REMOTE_VAULT)
})
}

mergeData(data) {
if (!this.vault.isDecryptable(data, this.cryptor))
throw Error(FAILED_TO_DECRYPT_REMOTE_VAULT)

const merged = mergeData(this.vault.read(), data, this.cryptor)
this.vault.write(merged)
return merged
}

pullRemoteVault() {
return this.provider.pull().catch(error => {
if (error.code === OFFLINE_CODE) throw Error(NO_INTERNET_CONNECTION)

throw Error(FAILED_TO_READ_REMOTE_VAULT)
})
}

pushRemoteVault() {
return this.provider.push(this.vault.read()).catch(error => {
if (error.code === OFFLINE_CODE) throw Error(NO_INTERNET_CONNECTION)

throw Error(FAILED_TO_WRITE_REMOTE_VAULT)
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const SyncIndicator = () => {
)
}
}
const getMessage = () => {
if (sync.inProgress) return 'Syncing...'
if (sync.success) return 'Sync Successful'

return (sync.error && sync.error.message) || 'Something went wrong'
}

return (
<div
Expand All @@ -39,7 +45,7 @@ const SyncIndicator = () => {
failure: sync.enabled && !sync.success
})}
>
<Tooltip content={sync.error && sync.error.message}>
<Tooltip content={getMessage()}>
<div className="spinner" />
{getStatusIcon()}
{getIcon()}
Expand Down
1 change: 1 addition & 0 deletions test/units/main/sync/gdrive/index/push.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('#push', () => {
describe('folder is creatable', () => {
beforeEach(async () => {
drive.__setFolderExists(false)
drive.__setFileExists(false)
result = await sync.push('DATA')
})

Expand Down
52 changes: 0 additions & 52 deletions test/units/main/sync/index/setup.test.js

This file was deleted.

0 comments on commit 73c664e

Please sign in to comment.