backup added
This commit is contained in:
@@ -65,7 +65,7 @@ async function restoreBackup() {
|
||||
}
|
||||
|
||||
// Call the IPC method to initiate the backup retrieval process
|
||||
window.electronAPI.startBackupRetrieval(destinationPath);
|
||||
window.uiAPI.startBackupRetrieval(destinationPath);
|
||||
|
||||
// Switch the content to the 'backup_retrieve' page
|
||||
fadeOut('backup_retrieve');
|
||||
@@ -133,6 +133,8 @@ async function loadReceivedFiles() {
|
||||
// Read the shareDirectory from applicationInfo
|
||||
const shareDirData = await window.databaseAPI.getDirectoryInfo(shareDirId);
|
||||
|
||||
console.log('Loading received files:', shareDirData);
|
||||
|
||||
const notificationsDiv = document.getElementById('notifications');
|
||||
const existingButtons = Array.from(notificationsDiv.children).map(button => button.getAttribute('data-filepath'));
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@ export class BackupRetrievalWorker {
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
if (!this.stopRequested) return
|
||||
if (this.stopRequested) return
|
||||
this.isBusy = true
|
||||
try {
|
||||
this.log('Start successfully. Retrieving backup.')
|
||||
const data = await this.db.read()
|
||||
const userInfo = data.app_config.user_info
|
||||
const encryptionKey = data.app_config.encryption_key
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TcpCommunicator } from './tcp_communicator'
|
||||
import { operationCodes } from '../network/operation_codes'
|
||||
import { ParsedMessage } from '../network/message_handler'
|
||||
import { Database } from '../database/database'
|
||||
import {NetworkUserScheme} from "../database/schemes/network_scheme";
|
||||
|
||||
export class DepartmentSharer {
|
||||
private readonly db: Database
|
||||
@@ -46,9 +47,13 @@ export class DepartmentSharer {
|
||||
const activeUsers = data.network.usersInLan
|
||||
this.departmentDirectory = departmentStructure.path
|
||||
|
||||
if(departmentStructure.path === ''){
|
||||
throw new Error('Department directory not set.')
|
||||
}
|
||||
|
||||
// Filter users who belong to the same department
|
||||
const departmentUsers = activeUsers.filter(
|
||||
(user: any) => user.user_info.departmentId === departmentId,
|
||||
(user: NetworkUserScheme) => user.departmentId === departmentId,
|
||||
)
|
||||
if (departmentUsers.length === 0) {
|
||||
throw new Error('No users found in the same department.')
|
||||
@@ -101,8 +106,6 @@ export class DepartmentSharer {
|
||||
if (!this.tcpCommunicator) return
|
||||
const unsentFiles = Object.keys(files)
|
||||
|
||||
console.log(`\n\n${unsentFiles}\n\n`)
|
||||
|
||||
for (const fileName of unsentFiles) {
|
||||
const filePath = files[fileName]
|
||||
|
||||
@@ -135,8 +138,6 @@ export class DepartmentSharer {
|
||||
)
|
||||
return
|
||||
|
||||
console.log(`\n\nSending file: ${fileName} to ${userName}\n\n`)
|
||||
|
||||
const response = await this.waitForResponse()
|
||||
if (!response || response.operationCode !== operationCodes.OK) {
|
||||
this.log(`Failed to send file: ${fileName}`, 'error')
|
||||
@@ -162,8 +163,6 @@ export class DepartmentSharer {
|
||||
while (this.isBusy) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
}
|
||||
|
||||
console.log('[BackupManager] Stopped successfully.')
|
||||
}
|
||||
|
||||
private async waitForResponse(): Promise<ParsedMessage | null> {
|
||||
|
||||
@@ -60,6 +60,7 @@ export class FileSharer {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.log('Queue processed successfully.')
|
||||
this.isBusy = false // Reset busy flag after the queue is processed
|
||||
}
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
export class JsonManager {
|
||||
private readonly filePath: string
|
||||
private readonly lockFilePath: string
|
||||
|
||||
constructor(filePath: string) {
|
||||
const dir = path.dirname(filePath)
|
||||
|
||||
// Check if the directory exists, throw error if it doesn't
|
||||
if (!fs.existsSync(dir)) {
|
||||
throw new Error(`The directory does not exist: ${dir}`)
|
||||
}
|
||||
|
||||
this.filePath = filePath
|
||||
this.lockFilePath = `${filePath}.lock` // Define the lock file path
|
||||
|
||||
// If the file doesn't exist, create it
|
||||
if (!fs.existsSync(filePath)) {
|
||||
fs.writeFileSync(filePath, JSON.stringify({}, null, 2), 'utf8')
|
||||
}
|
||||
}
|
||||
|
||||
// Method to acquire a lock (create .lock file)
|
||||
private async acquireLock(): Promise<void> {
|
||||
while (fs.existsSync(this.lockFilePath)) {
|
||||
// Wait until the lock file is released
|
||||
await new Promise((resolve) => setTimeout(resolve, 100)) // 100ms delay before retrying
|
||||
}
|
||||
// Create the lock file
|
||||
fs.writeFileSync(this.lockFilePath, '')
|
||||
}
|
||||
|
||||
// Method to release the lock (delete .lock file)
|
||||
private releaseLock(): void {
|
||||
if (fs.existsSync(this.lockFilePath)) {
|
||||
fs.unlinkSync(this.lockFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
// Read a value by key from the JSON file with a lock
|
||||
public async readValue(key: string): Promise<any | null> {
|
||||
await this.acquireLock() // Acquire the lock
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(this.filePath)) return null
|
||||
|
||||
const data = JSON.parse(fs.readFileSync(this.filePath, 'utf8'))
|
||||
return data[key] !== undefined ? data[key] : null
|
||||
} catch (err: any) {
|
||||
console.error(`Error reading from JSON file: ${err.message}`)
|
||||
return null
|
||||
} finally {
|
||||
this.releaseLock() // Always release the lock after the operation
|
||||
}
|
||||
}
|
||||
|
||||
// Write a key-value pair to the JSON file with a lock
|
||||
public async writeValue(key: string, value: any): Promise<boolean> {
|
||||
await this.acquireLock() // Acquire the lock
|
||||
|
||||
try {
|
||||
let data: { [key: string]: any } = {}
|
||||
|
||||
if (fs.existsSync(this.filePath)) {
|
||||
data = JSON.parse(fs.readFileSync(this.filePath, 'utf8'))
|
||||
}
|
||||
|
||||
// Update the key with the new value
|
||||
data[key] = value
|
||||
|
||||
fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2), 'utf8')
|
||||
return true
|
||||
} catch (err: any) {
|
||||
console.error(`Error writing to JSON file: ${err.message}`)
|
||||
return false
|
||||
} finally {
|
||||
this.releaseLock() // Always release the lock after the operation
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a key-value pair from the JSON file with a lock
|
||||
public async removeValue(key: string): Promise<boolean> {
|
||||
await this.acquireLock() // Acquire the lock
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(this.filePath)) return false
|
||||
|
||||
const data = JSON.parse(fs.readFileSync(this.filePath, 'utf8'))
|
||||
if (data[key] !== undefined) {
|
||||
delete data[key]
|
||||
fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2), 'utf8')
|
||||
return true
|
||||
}
|
||||
return false
|
||||
} catch (err: any) {
|
||||
console.error(`Error removing key from JSON file: ${err.message}`)
|
||||
return false
|
||||
} finally {
|
||||
this.releaseLock() // Always release the lock after the operation
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the JSON file by clearing all data with a lock
|
||||
public async resetFile(): Promise<boolean> {
|
||||
await this.acquireLock() // Acquire the lock
|
||||
|
||||
try {
|
||||
fs.writeFileSync(this.filePath, JSON.stringify({}, null, 2), 'utf8')
|
||||
return true
|
||||
} catch (err: any) {
|
||||
console.error(`Error resetting JSON file: ${err.message}`)
|
||||
return false
|
||||
} finally {
|
||||
this.releaseLock() // Always release the lock after the operation
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,6 @@ export class NetworkScanner {
|
||||
this.log('UC Check running...', 'log', 'startUCCheck')
|
||||
const udpClient = new UdpClient(this.udpPort)
|
||||
const aliveClients = await udpClient.getTargetClients(operationCodes.ARE_YOU_UC)
|
||||
console.log(aliveClients)
|
||||
const data = await this.db.read()
|
||||
const foundClient = aliveClients.length > 0
|
||||
const serverFound = data.app_config.server_found
|
||||
@@ -108,7 +107,6 @@ export class NetworkScanner {
|
||||
|
||||
try {
|
||||
this.log('IP Lookup running...', 'log', 'startUserIPLookup')
|
||||
const data = await this.db.read()
|
||||
const udpClient = new UdpClient(this.udpPort)
|
||||
const activeClients = await udpClient.getTargetClients(operationCodes.ARE_YOU_HUMAN)
|
||||
|
||||
|
||||
@@ -51,10 +51,6 @@ contextBridge.exposeInMainWorld('uiAPI', {
|
||||
ipcRenderer.invoke('show-file-in-explorer', path),
|
||||
readAnnouncement: (): Promise<string> => ipcRenderer.invoke('read-announcement'),
|
||||
closeAnnouncementWindow: (): Promise<void> => ipcRenderer.invoke('close-announcement-window'),
|
||||
})
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
// Workers
|
||||
startBackupRetrieval: (destinationPath: string): Promise<void> =>
|
||||
ipcRenderer.invoke('start-backup-retrieval', destinationPath),
|
||||
ipcRenderer.invoke('start-backup-retrieval', destinationPath),
|
||||
})
|
||||
|
||||
@@ -158,12 +158,6 @@ export class UserToUserOperations implements OperationPlugin {
|
||||
const fullFilePath = path.join(shareDirectory, userName, relativeFilePath)
|
||||
await fs.mkdir(path.dirname(fullFilePath), { recursive: true })
|
||||
await fs.writeFile(fullFilePath, parsedMessage.fileContent as Buffer)
|
||||
await database.pushToReceiveQueue({
|
||||
ip: '',
|
||||
path: fullFilePath,
|
||||
userName,
|
||||
})
|
||||
console.log(`File shared: ${fullFilePath}`)
|
||||
|
||||
return {
|
||||
operationCode: operationCodes.OK,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import dgram from 'dgram'
|
||||
import ping from 'ping'
|
||||
import { OperationHandler } from '../operations_base/operation_handler'
|
||||
import { MessageHandler } from '../message_handler'
|
||||
import { GeneralOperations } from '../operations_custom/general_operations'
|
||||
import { operationCodes } from '../operation_codes'
|
||||
import {OperationHandler} from '../operations_base/operation_handler'
|
||||
import {MessageHandler} from '../message_handler'
|
||||
import {GeneralOperations} from '../operations_custom/general_operations'
|
||||
import {operationCodes} from '../operation_codes'
|
||||
import os from 'os'
|
||||
|
||||
export class UdpClient {
|
||||
@@ -35,11 +35,9 @@ export class UdpClient {
|
||||
|
||||
// Get local machine's IP addresses to exclude
|
||||
const localIPs = this.getLocalIPs()
|
||||
this.log(`Local IPs to exclude from scan: ${localIPs.join(', ')}`)
|
||||
|
||||
// First, filter active IPs that respond to ping
|
||||
const activeIps = await this.filterActiveIps(ipRange)
|
||||
this.log(`Active IPs in subnet ${subnet}: ${activeIps.join(', ')}`)
|
||||
|
||||
// Send heartbeat to each active IP and keep only those that respond with ALIVE
|
||||
const aliveClients: any[] = []
|
||||
@@ -80,10 +78,8 @@ export class UdpClient {
|
||||
return new Promise((resolve) => {
|
||||
const heartbeatMessage = MessageHandler.formatMessage(heartbeatCode)
|
||||
|
||||
this.log(`Sending heartbeat to ${ip}`)
|
||||
this.udpSocket.send(heartbeatMessage, this.port, ip, (err) => {
|
||||
if (err) {
|
||||
this.log(`Failed to send heartbeat to ${ip}: ${err.message}`, 'error')
|
||||
resolve({ found: false })
|
||||
} else {
|
||||
const timeout = setTimeout(() => {
|
||||
@@ -96,10 +92,8 @@ export class UdpClient {
|
||||
clearTimeout(timeout)
|
||||
const parsedMessage = MessageHandler.parseMessage(msg.toString())
|
||||
if (parsedMessage?.operationCode === operationCodes.ALIVE) {
|
||||
this.log(`Received ALIVE response from ${ip}`)
|
||||
resolve({ found: true, data: parsedMessage.metaInfo })
|
||||
} else {
|
||||
this.log(`Unexpected response from ${ip}`)
|
||||
resolve({ found: false })
|
||||
}
|
||||
}
|
||||
@@ -113,9 +107,7 @@ export class UdpClient {
|
||||
private dropConnection(ip: string): void {
|
||||
try {
|
||||
this.udpSocket.removeAllListeners('message')
|
||||
this.log(`Dropped connection listeners for ${ip}`)
|
||||
} catch (err: any) {
|
||||
this.log(`Error dropping connection to ${ip}: ${err.message}`, 'error')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,9 +117,7 @@ export class UdpClient {
|
||||
for (const iface of Object.values(interfaces)) {
|
||||
for (const address of iface || []) {
|
||||
if (address.family === 'IPv4' && !address.internal) {
|
||||
const subnet = address.address.split('.').slice(0, 3).join('.')
|
||||
this.log(`Detected subnet: ${subnet}`)
|
||||
return subnet
|
||||
return address.address.split('.').slice(0, 3).join('.')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,7 +130,6 @@ export class UdpClient {
|
||||
for (let i = 1; i < 255; i++) {
|
||||
ipRange.push(`${subnet}.${i}`)
|
||||
}
|
||||
this.log(`Generated IP range for subnet ${subnet}`)
|
||||
return ipRange
|
||||
}
|
||||
|
||||
@@ -158,7 +147,6 @@ export class UdpClient {
|
||||
}
|
||||
}
|
||||
|
||||
this.log(`Active IPs after pinging: ${activeIps.join(', ')}`)
|
||||
return activeIps
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user