From 97cd00869fd3ec5018a417a388e92029a8680211 Mon Sep 17 00:00:00 2001
From: Xavier Jouslin de Noray <xavier.jouslindenoray@savoirfairelinux.com>
Date: Wed, 13 Sep 2023 16:27:47 -0400
Subject: [PATCH] Background Content type: add jpg content type

Change-Id: I720cba5ee97932524511efd01d1e1220e894af20
---
 src/controllers/plugins.controller.ts   | 10 ++++++++--
 src/services/file_manager.service.ts    | 16 ++++++++++++++++
 src/services/plugins_manager.service.ts | 21 +++++++++++++++------
 tests/plugins.controller.test.ts        |  2 +-
 tests/plugins.manager.test.ts           |  2 +-
 5 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/src/controllers/plugins.controller.ts b/src/controllers/plugins.controller.ts
index 1f0e5a0..6fa84cc 100644
--- a/src/controllers/plugins.controller.ts
+++ b/src/controllers/plugins.controller.ts
@@ -291,7 +291,10 @@ export class PluginsController {
           req.params.id,
           req.query.arch as string
         );
-        res.status(StatusCodes.OK).send(icon);
+        res
+          .setHeader('Content-Type', icon.type)
+          .status(StatusCodes.OK)
+          .send(icon.content);
       } catch (e) {
         if (e instanceof NotFoundException) {
           res.status(StatusCodes.NOT_FOUND).send();
@@ -394,7 +397,10 @@ export class PluginsController {
           req.params.id,
           req.query.arch as string
         );
-        res.status(StatusCodes.OK).send(background);
+        res
+          .setHeader('Content-Type', background.type)
+          .status(StatusCodes.OK)
+          .send(background.content);
         return;
       } catch (e) {
         if (e instanceof NotFoundException) {
diff --git a/src/services/file_manager.service.ts b/src/services/file_manager.service.ts
index 1563492..18f11bd 100644
--- a/src/services/file_manager.service.ts
+++ b/src/services/file_manager.service.ts
@@ -80,4 +80,20 @@ export class FileManagerService {
       return undefined;
     }
   }
+
+  getImageContentType(buffer: Buffer): string {
+    const fileSignature = buffer.toString('hex', 0, 4);
+    switch (fileSignature) {
+      case '89504e47':
+        return 'image/png';
+      case '47494638':
+        return 'image/gif';
+      case 'ffd8ffe0':
+      case 'ffd8ffe1':
+      case 'ffd8ffe2':
+        return 'image/jpeg';
+      default:
+        return 'application/octet-stream';
+    }
+  }
 }
diff --git a/src/services/plugins_manager.service.ts b/src/services/plugins_manager.service.ts
index e4e1afd..6569327 100644
--- a/src/services/plugins_manager.service.ts
+++ b/src/services/plugins_manager.service.ts
@@ -232,7 +232,7 @@ export class PluginsManager {
   async getIcon(
     id: string,
     arch: string | undefined = undefined
-  ): Promise<Buffer> {
+  ): Promise<{content: Buffer; type: string}> {
     if (this.plugins.length === 0) {
       await this.setPlugins();
     }
@@ -251,8 +251,7 @@ export class PluginsManager {
     ) {
       throw new NotFoundException('Plugin not found');
     }
-
-    return await this.fileManager.readArchive(
+    const content = await this.fileManager.readArchive(
       // eslint-disable-next-line
       __dirname +
         '/../..' +
@@ -266,6 +265,10 @@ export class PluginsManager {
         '.jpl',
       'data/' + plugin.icon
     );
+    return {
+      content,
+      type: this.fileManager.getImageContentType(content),
+    };
   }
 
   async getVersions(): Promise<Array<{id: string; version: string}>> {
@@ -331,7 +334,10 @@ export class PluginsManager {
     this.plugins = plugins;
   }
 
-  async getPluginBackground(id: string, arch: string): Promise<Buffer> {
+  async getPluginBackground(
+    id: string,
+    arch: string
+  ): Promise<{content: Buffer; type: string}> {
     if (this.plugins.length === 0) {
       await this.setPlugins();
     }
@@ -348,8 +354,7 @@ export class PluginsManager {
     ) {
       throw new NotFoundException('Plugin not found');
     }
-
-    return await this.fileManager.readArchive(
+    const content = await this.fileManager.readArchive(
       // eslint-disable-next-line
       __dirname +
         '/../..' +
@@ -363,6 +368,10 @@ export class PluginsManager {
         '.jpl',
       'data/' + plugin.background
     );
+    return {
+      content,
+      type: this.fileManager.getImageContentType(content),
+    };
   }
 
   private addPluginArch(platforms: string[], arches: string[]): void {
diff --git a/tests/plugins.controller.test.ts b/tests/plugins.controller.test.ts
index 1e20ad0..4e3c086 100644
--- a/tests/plugins.controller.test.ts
+++ b/tests/plugins.controller.test.ts
@@ -177,7 +177,7 @@ describe('Routes', function () {
 
   it("should get icon if the given id is valid", (done) => {
     const expectedIcon = 'test';
-    pluginsManagerServiceStub.getIcon.resolves(Buffer.from(expectedIcon));
+    pluginsManagerServiceStub.getIcon.resolves({content: Buffer.from(expectedIcon), type: 'image/png'});
 
     request(expressApp)
       .get("/icons/test?arch=test")
diff --git a/tests/plugins.manager.test.ts b/tests/plugins.manager.test.ts
index 8d2f54f..defc865 100644
--- a/tests/plugins.manager.test.ts
+++ b/tests/plugins.manager.test.ts
@@ -285,7 +285,7 @@ describe('Plugins manager service tests', function () {
         stub(Object.getPrototypeOf(pluginsManagerService), 'getPlatform').returns(['test']);
         const actual = await pluginsManagerService['getIcon']("test", "test");
 
-        expect(actual).toEqual(Buffer.from(expected));
+        expect(actual.content).toEqual(Buffer.from(expected));
     });
 
     it('should return an array of plugin versions', async () => {
-- 
GitLab