From 5d4002dd3d8b1f1557fc42dac8d4283723821399 Mon Sep 17 00:00:00 2001
From: Etienne LOUPIAS <eloupias@grandlyon.com>
Date: Fri, 16 Sep 2022 08:00:02 +0000
Subject: [PATCH] feat(profile): add structure owners screen

---
 .../mail-templates/tempUserRegistration.ejs   |  4 +--
 src/structures/structures.controller.spec.ts  |  5 ++++
 src/structures/structures.controller.ts       | 24 ++++++++++++++++-
 src/temp-user/temp-user.controller.spec.ts    |  2 +-
 src/temp-user/temp-user.controller.ts         |  2 +-
 src/temp-user/temp-user.service.ts            | 27 +++++++++++++++++--
 src/users/services/users.service.ts           | 20 +++++++-------
 7 files changed, 67 insertions(+), 17 deletions(-)

diff --git a/src/mailer/mail-templates/tempUserRegistration.ejs b/src/mailer/mail-templates/tempUserRegistration.ejs
index 59e46a0b6..0b318c499 100644
--- a/src/mailer/mail-templates/tempUserRegistration.ejs
+++ b/src/mailer/mail-templates/tempUserRegistration.ejs
@@ -2,7 +2,7 @@ Bonjour,<br />
 <br />
 Vous recevez ce message car vous avez été relié à la stucture <strong><%= name %></strong> sur RES'in, le réseau des
 acteurs de l'inclusion numérique de la Métropole de Lyon. Vous pouvez dès maitenant vous créer un compte sur la
-plateforme pour accéder a votre structure en
-<a href="<%= config.protocol %>://<%= config.host %><%= config.port ? ':' + config.port : '' %>/register?id=<%= id %>"
+plateforme pour accéder à votre structure en
+<a href="<%= config.protocol %>://<%= config.host %><%= config.port ? ':' + config.port : '' %>/form/register/<%= id %>"
   >cliquant ici</a
 >.
diff --git a/src/structures/structures.controller.spec.ts b/src/structures/structures.controller.spec.ts
index d11767f41..2e77f0918 100644
--- a/src/structures/structures.controller.spec.ts
+++ b/src/structures/structures.controller.spec.ts
@@ -195,6 +195,11 @@ describe('AuthController', () => {
     expect(res).toBeTruthy();
   });
 
+  it('should remove Owner', async () => {
+    const res = controller.removeTempUser('6093ba0e2ab5775cfc01ed3e', 'tsfsf6296');
+    expect(res).toBeTruthy();
+  });
+
   it('should join user', async () => {
     const userMock = new UsersServiceMock();
     const user = userMock.findOne('pauline.dupont@mii.com');
diff --git a/src/structures/structures.controller.ts b/src/structures/structures.controller.ts
index 5cf6f71ce..d62bf74ab 100644
--- a/src/structures/structures.controller.ts
+++ b/src/structures/structures.controller.ts
@@ -152,6 +152,11 @@ export class StructuresController {
     return this.structureService.findWithOwners(id, data.emailUser);
   }
 
+  @Get(':id/tempUsers')
+  public async getTempUsers(@Param('id') id: string) {
+    return this.tempUserService.getStructureTempUsers(id);
+  }
+
   @Delete(':id')
   @UseGuards(JwtAuthGuard, IsStructureOwnerGuard)
   @Roles('admin')
@@ -203,7 +208,6 @@ export class StructuresController {
 
   @Delete(':id/owner/:userId')
   @UseGuards(JwtAuthGuard, IsStructureOwnerGuard)
-  @Roles('admin')
   @ApiParam({ name: 'id', type: String, required: true })
   @ApiParam({ name: 'userId', type: String, required: true })
   public async removeOwner(@Param('id') id: string, @Param('userId') userId: string): Promise<void> {
@@ -220,6 +224,24 @@ export class StructuresController {
     this.userService.removeFromStructureLinked(userFromDb.email, id);
   }
 
+  @Delete(':id/tempUser/:userId')
+  @UseGuards(JwtAuthGuard, IsStructureOwnerGuard)
+  @ApiParam({ name: 'id', type: String, required: true })
+  @ApiParam({ name: 'userId', type: String, required: true })
+  public async removeTempUser(@Param('id') id: string, @Param('userId') userId: string): Promise<void> {
+    // Get structure
+    const structure = await this.structureService.findOne(id);
+    if (!structure) {
+      throw new HttpException('Invalid Structure', HttpStatus.NOT_FOUND);
+    }
+    // Get temp user
+    const userFromDb = await this.tempUserService.findById(userId);
+    if (!userFromDb || !userFromDb.pendingStructuresLink.includes(Types.ObjectId(id))) {
+      throw new HttpException('Invalid temp user', HttpStatus.NOT_FOUND);
+    }
+    this.tempUserService.removeFromStructureLinked(userFromDb.email, id);
+  }
+
   @Post('reportStructureError')
   public async reportStructureError(@Body() data: { structureId: string; content: string }): Promise<void> {
     return this.structureService.reportStructureError(data.structureId, data.content);
diff --git a/src/temp-user/temp-user.controller.spec.ts b/src/temp-user/temp-user.controller.spec.ts
index 37e355b97..ca61b3452 100644
--- a/src/temp-user/temp-user.controller.spec.ts
+++ b/src/temp-user/temp-user.controller.spec.ts
@@ -40,7 +40,7 @@ describe('TempUserService', () => {
         // Fail test if above expression doesn't throw anything.
         expect(true).toBe(false);
       } catch (e) {
-        expect(e.message).toEqual('User does not exists');
+        expect(e.message).toEqual('Temp user does not exists');
         expect(e.status).toEqual(HttpStatus.BAD_REQUEST);
       }
     });
diff --git a/src/temp-user/temp-user.controller.ts b/src/temp-user/temp-user.controller.ts
index 9dc21a559..bfdc230bf 100644
--- a/src/temp-user/temp-user.controller.ts
+++ b/src/temp-user/temp-user.controller.ts
@@ -12,7 +12,7 @@ export class TempUserController {
   public async getTempUser(@Param('id') id: string): Promise<TempUser> {
     const user = await this.tempUserSercice.findById(id);
     if (!user) {
-      throw new HttpException('User does not exists', HttpStatus.BAD_REQUEST);
+      throw new HttpException('Temp user does not exists', HttpStatus.BAD_REQUEST);
     }
     return user;
   }
diff --git a/src/temp-user/temp-user.service.ts b/src/temp-user/temp-user.service.ts
index 8a4383223..da41551c5 100644
--- a/src/temp-user/temp-user.service.ts
+++ b/src/temp-user/temp-user.service.ts
@@ -25,7 +25,7 @@ export class TempUserService {
     return this.findOne(createTempUser.email);
   }
 
-  public async findOne(mail: string): Promise<TempUser> {
+  public async findOne(mail: string): Promise<ITempUser> {
     return this.tempUserModel.findOne({ email: mail });
   }
 
@@ -38,7 +38,7 @@ export class TempUserService {
     if (!userInDb) {
       throw new HttpException('User does not exists', HttpStatus.BAD_REQUEST);
     }
-    this.tempUserModel.deleteOne({ email: mail });
+    await this.tempUserModel.deleteOne({ email: mail });
     return userInDb;
   }
 
@@ -82,4 +82,27 @@ export class TempUserService {
     });
     this.mailerService.send(user.email, jsonConfig.subject, html);
   }
+
+  public async getStructureTempUsers(structureId: string): Promise<ITempUser[]> {
+    const tempUsers = await this.tempUserModel
+      .find({ pendingStructuresLink: Types.ObjectId(structureId) })
+      .select('email updatedAt')
+      .exec();
+    return tempUsers;
+  }
+
+  public async removeFromStructureLinked(userEmail: string, idStructure: string): Promise<Types.ObjectId[]> {
+    const user = await this.findOne(userEmail);
+    if (!user) {
+      throw new HttpException('Invalid temp user', HttpStatus.NOT_FOUND);
+    }
+    if (!user.pendingStructuresLink.includes(Types.ObjectId(idStructure))) {
+      throw new HttpException("Temp user doesn't belong to this structure", HttpStatus.NOT_FOUND);
+    }
+    user.pendingStructuresLink = user.pendingStructuresLink.filter((structureId) => {
+      return !structureId.equals(idStructure);
+    });
+    await user.save();
+    return user.pendingStructuresLink;
+  }
 }
diff --git a/src/users/services/users.service.ts b/src/users/services/users.service.ts
index 19c9d58b6..3c763e054 100644
--- a/src/users/services/users.service.ts
+++ b/src/users/services/users.service.ts
@@ -550,17 +550,17 @@ export class UsersService {
 
   public async removeFromStructureLinked(userEmail: string, idStructure: string): Promise<Types.ObjectId[]> {
     const user = await this.findOne(userEmail, true);
-    if (user) {
-      if (user.structuresLink.includes(Types.ObjectId(idStructure))) {
-        user.structuresLink = user.structuresLink.filter((structureId) => {
-          return !structureId.equals(idStructure);
-        });
-        await user.save();
-        return user.structuresLink;
-      }
-      throw new HttpException('User already belong to this structure', HttpStatus.NOT_FOUND);
+    if (!user) {
+      throw new HttpException('Invalid user', HttpStatus.NOT_FOUND);
     }
-    throw new HttpException('Invalid user', HttpStatus.NOT_FOUND);
+    if (!user.structuresLink.includes(Types.ObjectId(idStructure))) {
+      throw new HttpException("User doesn't belong to this structure", HttpStatus.NOT_FOUND);
+    }
+    user.structuresLink = user.structuresLink.filter((structureId) => {
+      return !structureId.equals(idStructure);
+    });
+    await user.save();
+    return user.structuresLink;
   }
 
   /**
-- 
GitLab