From 3348303568712cb6a21959b493e5024f2c190c2b Mon Sep 17 00:00:00 2001 From: Eric BREHAULT Date: Tue, 12 Dec 2023 16:39:26 +0100 Subject: [PATCH 1/7] support CORS + fix status endpoint --- electron-app/package-lock.json | 31 +++++++++++++++++++++++++++++++ electron-app/package.json | 2 ++ electron-app/src/server.ts | 13 ++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/electron-app/package-lock.json b/electron-app/package-lock.json index 05bc694..372a70e 100644 --- a/electron-app/package-lock.json +++ b/electron-app/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "compression": "^1.7.4", + "cors": "^2.8.5", "electron-squirrel-startup": "^1.0.0", "express": "^4.18.2", "rxjs": "^7.8.1", @@ -26,6 +27,7 @@ "@electron-forge/plugin-auto-unpack-natives": "^6.4.2", "@electron-forge/publisher-github": "^6.4.2", "@types/compression": "^1.7.5", + "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/uuid": "^9.0.7", "@typescript-eslint/eslint-plugin": "^6.12.0", @@ -1561,6 +1563,15 @@ "@types/node": "*" } }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -2973,6 +2984,18 @@ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6262,6 +6285,14 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", diff --git a/electron-app/package.json b/electron-app/package.json index b2a4824..4f94191 100644 --- a/electron-app/package.json +++ b/electron-app/package.json @@ -25,6 +25,7 @@ "license": "MIT", "dependencies": { "compression": "^1.7.4", + "cors": "^2.8.5", "electron-squirrel-startup": "^1.0.0", "express": "^4.18.2", "rxjs": "^7.8.1", @@ -41,6 +42,7 @@ "@electron-forge/plugin-auto-unpack-natives": "^6.4.2", "@electron-forge/publisher-github": "^6.4.2", "@types/compression": "^1.7.5", + "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/uuid": "^9.0.7", "@typescript-eslint/eslint-plugin": "^6.12.0", diff --git a/electron-app/src/server.ts b/electron-app/src/server.ts index 712be61..368095c 100644 --- a/electron-app/src/server.ts +++ b/electron-app/src/server.ts @@ -1,5 +1,6 @@ import compression from 'compression'; import express, { Router } from 'express'; +import cors from 'cors'; import http from 'http'; import { EVENTS, EventEmitter } from './events/events'; @@ -46,10 +47,20 @@ export class Server { } async start() { + //* CORS + this.app.use( + cors({ + origin: '*', + }), + ); //* Middlewares this.app.use(express.json()); // raw this.app.use(express.urlencoded({ extended: true })); // x-www-form-urlencoded this.app.use(compression()); + this.app.use((req, res, next) => { + res.setHeader('Content-Type', 'application/json'); + next(); + }); //* Routes this.app.use(this.routes); @@ -59,7 +70,7 @@ export class Server { }); this.app.get('/status', async (_req, res) => { - res.status(200).send('Server is running'); + res.status(200).send(JSON.stringify({ running: true })); }); this.app.post('/stop', async (_req, res) => { From f73086e8ad97b21a759288277d61bac4d8814192 Mon Sep 17 00:00:00 2001 From: Eric BREHAULT Date: Tue, 12 Dec 2023 16:40:42 +0100 Subject: [PATCH 2/7] fix path --- .../infrastructure/connectors/folder.connector.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/electron-app/src/logic/connector/infrastructure/connectors/folder.connector.ts b/electron-app/src/logic/connector/infrastructure/connectors/folder.connector.ts index b6d2c64..8ae1d2d 100644 --- a/electron-app/src/logic/connector/infrastructure/connectors/folder.connector.ts +++ b/electron-app/src/logic/connector/infrastructure/connectors/folder.connector.ts @@ -2,14 +2,7 @@ import { Blob as FSBlob } from 'buffer'; import * as fs from 'fs'; import path from 'path'; import { Observable, forkJoin, map, of, switchMap } from 'rxjs'; -import { - ConnectorParameters, - FileStatus, - IConnector, - Link, - SearchResults, - SyncItem, -} from 'src/logic/connector/domain/connector'; +import { ConnectorParameters, FileStatus, IConnector, Link, SearchResults, SyncItem } from '../../domain/connector'; import { SourceConnectorDefinition } from '../factory'; const FILES_TO_IGNORE = ['.DS_Store', 'Thumbs.db']; From 384f048a11e364dcb3853e97946c010a6afb7f76 Mon Sep 17 00:00:00 2001 From: Eric BREHAULT Date: Tue, 12 Dec 2023 16:41:21 +0100 Subject: [PATCH 3/7] fix refresh param --- .../connector/infrastructure/connectors/gdrive.connector.ts | 2 +- .../infrastructure/connectors/tests/gdrive.connector.spec.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/electron-app/src/logic/connector/infrastructure/connectors/gdrive.connector.ts b/electron-app/src/logic/connector/infrastructure/connectors/gdrive.connector.ts index b26f130..d2dc7f5 100644 --- a/electron-app/src/logic/connector/infrastructure/connectors/gdrive.connector.ts +++ b/electron-app/src/logic/connector/infrastructure/connectors/gdrive.connector.ts @@ -29,7 +29,7 @@ export class GDriveImpl extends OAuthBaseConnector implements IConnector { if (!params?.token) { return false; } - if (!params?.refresh_token) { + if (!params?.refresh) { return false; } return true; diff --git a/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js b/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js index a8b7d90..c574b2d 100644 --- a/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js +++ b/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js @@ -79,7 +79,7 @@ describe('Test validate gdrive params', () => { expect( sourceConnector.areParametersValid({ incorrect: 'test', - refresh_token: 'test', + refresh: 'test', }), ).toBe(false); }); @@ -88,7 +88,7 @@ describe('Test validate gdrive params', () => { expect( sourceConnector.areParametersValid({ token: '', - refresh_token: '', + refresh: '', }), ).toBe(false); }); From c4f997d9b445f0f019f222593d132ba26f6d2b17 Mon Sep 17 00:00:00 2001 From: Eric BREHAULT Date: Tue, 12 Dec 2023 16:41:49 +0100 Subject: [PATCH 4/7] at creation time, the parameters are usually incomplete --- electron-app/src/logic/sync/domain/dto/create-sync.dto.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/electron-app/src/logic/sync/domain/dto/create-sync.dto.ts b/electron-app/src/logic/sync/domain/dto/create-sync.dto.ts index f359acf..8b6e425 100644 --- a/electron-app/src/logic/sync/domain/dto/create-sync.dto.ts +++ b/electron-app/src/logic/sync/domain/dto/create-sync.dto.ts @@ -28,10 +28,6 @@ export class CreateSyncDto { if (!connectorDefinition) { return ['Connector definition is not defined']; } - const sourceConnector = connectorDefinition.factory(); - if (!sourceConnector.areParametersValid(props.connector.parameters)) { - return [`Connector ${props.connector.name} parameters are not valid`]; - } if (!props.kb) { return ['The Knowledge Box info is mandatory']; From 50e386633859bc7bceec083cc50d33ceaa582633 Mon Sep 17 00:00:00 2001 From: Eric BREHAULT Date: Tue, 12 Dec 2023 16:46:21 +0100 Subject: [PATCH 5/7] add /auth endpoint --- .../src/logic/sync/domain/sync.entity.ts | 2 +- .../use-cases/get-sync-auth.use-case.ts | 26 +++++++++++++++++++ .../src/logic/sync/presentation/routes.ts | 11 ++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts diff --git a/electron-app/src/logic/sync/domain/sync.entity.ts b/electron-app/src/logic/sync/domain/sync.entity.ts index 0e8679e..31c8cc3 100644 --- a/electron-app/src/logic/sync/domain/sync.entity.ts +++ b/electron-app/src/logic/sync/domain/sync.entity.ts @@ -5,7 +5,7 @@ import { getConnector } from '../../connector/infrastructure/factory'; export type Connector = { name: 'gdrive' | 'folder'; - logo: string; + // logo: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any parameters: { [key: string]: any }; }; diff --git a/electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts b/electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts new file mode 100644 index 0000000..dc1e6fc --- /dev/null +++ b/electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts @@ -0,0 +1,26 @@ +import { CustomError } from '../../../errors'; +import { ISyncEntity } from '../sync.entity'; +import { ISyncRepository } from '../sync.repository'; +import { getConnector } from '../../../connector/infrastructure/factory'; + +export interface GetSyncAuthUseCase { + execute(id: string): Promise; +} + +export class GetSyncAuth implements GetSyncAuthUseCase { + constructor(private readonly repository: ISyncRepository) {} + + async execute(id: string) { + const data = await this.repository.getSync(id); + if (data === null) { + throw new CustomError(`Sync with id ${id} not found`, 404); + } + const connectorDefinition = getConnector(data.connector?.name || ''); + if (!connectorDefinition) { + return false; + } + const sourceConnector = connectorDefinition.factory(); + sourceConnector.setParameters(data.connector?.parameters ?? {}); + return sourceConnector.hasAuthData(); + } +} diff --git a/electron-app/src/logic/sync/presentation/routes.ts b/electron-app/src/logic/sync/presentation/routes.ts index 48735a2..5bd374b 100644 --- a/electron-app/src/logic/sync/presentation/routes.ts +++ b/electron-app/src/logic/sync/presentation/routes.ts @@ -11,6 +11,7 @@ import { GetSync } from '../domain/use-cases/get-sync.use-case'; import { UpdateSync } from '../domain/use-cases/update-sync.use-case'; import { FileSystemSyncDatasource } from '../infrastructure/file-system.sync.datasource'; import { SyncRepository } from '../infrastructure/sync.repository'; +import { GetSyncAuth } from '../domain/use-cases/get-sync-auth.use-case'; export class SyncFileSystemRoutes { private readonly basePath: string; @@ -73,6 +74,16 @@ export class SyncFileSystemRoutes { } }); + router.get('/:id/auth', async (req, res) => { + const { id } = req.params; + try { + const data = await new GetSyncAuth(syncRepository).execute(id); + res.status(200).send({ hasAuth: data }); + } catch (error) { + this.handleError(res, error); + } + }); + router.get('/:id/folders', async (req, res) => { const { id } = req.params; try { From 8d4c58023032313deb9e8831ff4df53d61d3c73b Mon Sep 17 00:00:00 2001 From: Eric BREHAULT Date: Tue, 12 Dec 2023 16:48:13 +0100 Subject: [PATCH 6/7] lint --- .../src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts b/electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts index dc1e6fc..0925f70 100644 --- a/electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts +++ b/electron-app/src/logic/sync/domain/use-cases/get-sync-auth.use-case.ts @@ -1,5 +1,4 @@ import { CustomError } from '../../../errors'; -import { ISyncEntity } from '../sync.entity'; import { ISyncRepository } from '../sync.repository'; import { getConnector } from '../../../connector/infrastructure/factory'; From e65ef1742923e17713ebcee4282f6ec0cd4ba0d2 Mon Sep 17 00:00:00 2001 From: Eric BREHAULT Date: Wed, 13 Dec 2023 10:55:04 +0100 Subject: [PATCH 7/7] fix tests --- .../connectors/tests/gdrive.connector.spec.js | 2 +- .../src/logic/sync/domain/dto/tests/create-sync.dto.spec.ts | 6 +++--- electron-app/src/server.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js b/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js index c574b2d..f6c31df 100644 --- a/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js +++ b/electron-app/src/logic/connector/infrastructure/connectors/tests/gdrive.connector.spec.js @@ -97,7 +97,7 @@ describe('Test validate gdrive params', () => { expect( sourceConnector.areParametersValid({ token: 'test', - refresh_token: 'test', + refresh: 'test', }), ).toBe(true); }); diff --git a/electron-app/src/logic/sync/domain/dto/tests/create-sync.dto.spec.ts b/electron-app/src/logic/sync/domain/dto/tests/create-sync.dto.spec.ts index 94d7e8d..35fb7f8 100644 --- a/electron-app/src/logic/sync/domain/dto/tests/create-sync.dto.spec.ts +++ b/electron-app/src/logic/sync/domain/dto/tests/create-sync.dto.spec.ts @@ -42,7 +42,7 @@ describe('Create Sync dto tests', () => { expect(dto).toBeUndefined(); }); - test('should not create a valid dto - connector params are not valid', () => { + test('should not create a valid dto - connector params are incomplete', () => { const [error, dto] = CreateSyncDto.create({ ...props, id: undefined, @@ -52,8 +52,8 @@ describe('Create Sync dto tests', () => { }, }); - expect(error).toEqual('Connector folder parameters are not valid'); - expect(dto).toBeUndefined(); + expect(error).toBeUndefined(); + expect(dto).toBeDefined(); }); test('should not create a valid dto - kb params are not valid', () => { diff --git a/electron-app/src/server.ts b/electron-app/src/server.ts index 368095c..4de1ca6 100644 --- a/electron-app/src/server.ts +++ b/electron-app/src/server.ts @@ -66,7 +66,7 @@ export class Server { this.app.use(this.routes); this.app.get('/', async (_req, res) => { - res.status(200).send('Server is running'); + res.status(200).send(JSON.stringify('Server is running')); }); this.app.get('/status', async (_req, res) => {