From a25027bc9000cc55f5d893da8c6c8297eeb94587 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Fri, 4 Apr 2025 23:15:05 +0100 Subject: [PATCH] Send device id to server --- frontend/sync-client/src/services/sync-service.ts | 6 +++++- frontend/sync-client/src/services/types.ts | 5 +++++ frontend/sync-client/src/sync-client.ts | 10 +++++++++- frontend/sync-client/src/sync-operations/syncer.ts | 9 ++++++++- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/frontend/sync-client/src/services/sync-service.ts b/frontend/sync-client/src/services/sync-service.ts index 4af744e..7251ef7 100644 --- a/frontend/sync-client/src/services/sync-service.ts +++ b/frontend/sync-client/src/services/sync-service.ts @@ -24,6 +24,7 @@ export class SyncService { private _fetchImplementation: typeof globalThis.fetch = globalThis.fetch; public constructor( + private readonly deviceId: string, private readonly connectionStatus: ConnectionStatus, private readonly settings: Settings, private readonly logger: Logger @@ -79,6 +80,7 @@ export class SyncService { formData.append("document_id", documentId); } formData.append("relative_path", relativePath); + formData.append("device_id", this.deviceId); formData.append("content", new Blob([contentBytes])); const response = await this.client.POST( @@ -130,6 +132,7 @@ export class SyncService { const formData = new FormData(); formData.append("parent_version_id", parentVersionId.toString()); formData.append("relative_path", relativePath); + formData.append("device_id", this.deviceId); formData.append("content", new Blob([contentBytes])); const response = await this.client.PUT( @@ -182,7 +185,8 @@ export class SyncService { } }, body: { - relativePath + relativePath, + deviceId: this.deviceId } } ); diff --git a/frontend/sync-client/src/services/types.ts b/frontend/sync-client/src/services/types.ts index 55f7231..7ecb7fe 100644 --- a/frontend/sync-client/src/services/types.ts +++ b/frontend/sync-client/src/services/types.ts @@ -439,6 +439,7 @@ export interface components { }; CreateDocumentVersion: { contentBase64: string; + deviceId?: string | null; /** * Format: uuid * @description The client can decide the document id (if it wishes to) in order to help with syncing. If the client does not provide a document id, the server will generate one. If the client provides a document id it must not already exist in the database. @@ -448,6 +449,7 @@ export interface components { }; CreateDocumentVersionMultipart: { content: components["schemas"]["Array_of_uint8"]; + device_id?: string | null; /** Format: uuid */ document_id?: string | null; relative_path: string; @@ -458,6 +460,7 @@ export interface components { vault_id: string; }; DeleteDocumentVersion: { + deviceId?: string | null; relativePath: string; }; /** @description Response to an update document request. */ @@ -568,12 +571,14 @@ export interface components { }; UpdateDocumentVersion: { contentBase64: string; + deviceId?: string | null; /** Format: int64 */ parentVersionId: number; relativePath: string; }; UpdateDocumentVersionMultipart: { content: components["schemas"]["Array_of_uint8"]; + deviceId?: string | null; /** Format: int64 */ parentVersionId: number; relativePath: string; diff --git a/frontend/sync-client/src/sync-client.ts b/frontend/sync-client/src/sync-client.ts index 0153148..228b29e 100644 --- a/frontend/sync-client/src/sync-client.ts +++ b/frontend/sync-client/src/sync-client.ts @@ -15,6 +15,7 @@ import { FileOperations } from "./file-operations/file-operations"; import { ConnectionStatus } from "./services/connection-status"; import { UnrestrictedSyncer } from "./sync-operations/unrestricted-syncer"; import { rateLimit } from "./utils/rate-limit"; +import { v4 as uuidv4 } from "uuid"; export interface NetworkConnectionStatus { isSuccessful: boolean; @@ -105,9 +106,15 @@ export class SyncClient { await rateLimitedSave(state); } ); + const deviceId = uuidv4(); const connectionStatus = new ConnectionStatus(settings, logger); - const syncService = new SyncService(connectionStatus, settings, logger); + const syncService = new SyncService( + deviceId, + connectionStatus, + settings, + logger + ); syncService.fetchImplementation = fetch; const fileOperations = new FileOperations( logger, @@ -124,6 +131,7 @@ export class SyncClient { history ); const syncer = new Syncer( + deviceId, logger, database, settings, diff --git a/frontend/sync-client/src/sync-operations/syncer.ts b/frontend/sync-client/src/sync-operations/syncer.ts index ec6b228..ef35d10 100644 --- a/frontend/sync-client/src/sync-operations/syncer.ts +++ b/frontend/sync-client/src/sync-operations/syncer.ts @@ -31,7 +31,9 @@ export class Syncer { | undefined; private applyRemoteChangesWebSocket: WebSocket | undefined; + // eslint-disable-next-line @typescript-eslint/max-params public constructor( + private readonly deviceId: string, private readonly logger: Logger, private readonly database: Database, private readonly settings: Settings, @@ -291,7 +293,12 @@ export class Syncer { // The JS WebSocket API doesn't support setting headers, so we have to send the token as a message this.applyRemoteChangesWebSocket.onopen = (): void => { this.logger.info("WebSocket connection opened"); - this.applyRemoteChangesWebSocket?.send(settings.token); + this.applyRemoteChangesWebSocket?.send( + JSON.stringify({ + deviceId: this.deviceId, + token: settings.token + }) + ); this.webSocketStatusChangeListeners.forEach((listener) => { listener(); });