diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/main.connector.ts index ead97ba40b90fc7c2db8225748057009bc4641d1..3c34f0f23ad0f27347ae6b9de3c538c0d5e2d180 100644 --- a/api/src/engine/connectors/datashield/main.connector.ts +++ b/api/src/engine/connectors/datashield/main.connector.ts @@ -1,5 +1,11 @@ import { HttpService } from '@nestjs/axios'; -import { Inject, Logger, NotImplementedException } from '@nestjs/common'; +import { + Inject, + InternalServerErrorException, + Logger, + NotImplementedException, + UnauthorizedException, +} from '@nestjs/common'; import { Request } from 'express'; import { catchError, firstValueFrom } from 'rxjs'; import { MIME_TYPES } from 'src/common/interfaces/utilities.interface'; @@ -207,6 +213,13 @@ export default class DataShieldService implements IEngineService { async getDomains(ids: string[], request: Request): Promise<Domain[]> { const user = request.user as User; + const sid = user && user.extraFields && user.extraFields['sid']; + + if (!sid) + throw new InternalServerErrorException( + 'Datashield sid is missing from the user', + ); + const cookies = [`sid=${user.extraFields['sid']}`, `user=${user.id}`]; const path = this.options.baseurl + 'getvars'; diff --git a/api/src/users/users.resolver.ts b/api/src/users/users.resolver.ts index 1a48578ef66b1ddcddd2b98089621f49a50f073f..46c77cc1fb0260c9f0f7b6776a0661592ed2b912 100644 --- a/api/src/users/users.resolver.ts +++ b/api/src/users/users.resolver.ts @@ -1,6 +1,7 @@ import { Inject, InternalServerErrorException, + Logger, UseGuards, } from '@nestjs/common'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; @@ -17,43 +18,66 @@ import { Request } from 'express'; @UseGuards(JwtAuthGuard) @Resolver() export class UsersResolver { + private readonly logger = new Logger(UsersResolver.name); + constructor( private readonly usersService: UsersService, @Inject(ENGINE_SERVICE) private readonly engineService: IEngineService, ) {} @Query(() => User, { name: 'user' }) - getUser(@GQLRequest() request: Request, @CurrentUser() reqUser: User): User { + /** + * It returns the user from the engine, if it exists. Same from the internal database + * merge internal object over engine one to have a final user. + * @param {Request} request - Request + * @param {User} reqUser - The user that is currently logged in. + * @returns A user object. + */ + async getUser(@GQLRequest() request: Request, @CurrentUser() reqUser: User) { const user: Partial<User> = {}; if (this.engineService.getActiveUser) { - const engineUser = this.engineService.getActiveUser(request); + const engineUser = await this.engineService.getActiveUser(request); if (engineUser) Object.assign(user, engineUser); } - const internalUser = this.usersService.getUser(reqUser.id); + // Checking if the user exists in the internal database. If it does, it will assign the user to the `user` object. + try { + const internalUser = await this.usersService.findOne(reqUser.id); - if (internalUser) { - Object.assign(user, internalUser); + if (internalUser && (!user.id || internalUser.id === user.id)) { + Object.assign(user, internalUser); + } + } catch (e) { + this.logger.verbose(e); } if (!user.id || !user.username) throw new InternalServerErrorException( - 'The user cannot be construct from the engine ', + 'The user cannot be construct from the engine', ); return user as User; } + /** + * Update a user + * @param {Request} request - The incoming request object. + * @param {UpdateUserInput} updateUserInput - The input object that was passed to the mutation. + * @param {User} user - The user that is currently logged in. + * @returns The updated user. + */ @Mutation(() => User) - updateUser( + async updateUser( @GQLRequest() request: Request, @Args('updateUserInput') updateUserInput: UpdateUserInput, @CurrentUser() user: User, ) { if (this.engineService.updateUser) - return this.engineService.updateUser(request, updateUserInput); + return this.engineService.updateUser(request, user.id, updateUserInput); + + await this.usersService.update(user.id, updateUserInput); - return this.usersService.updateUser(user.id, updateUserInput); + return await this.getUser(request, user); } } diff --git a/api/src/users/users.service.ts b/api/src/users/users.service.ts index a97a8c7970fdbbac01e8a924c1e3c21a484440a9..273abf6de249a4f618f1039d4f00bc6cc29cfcd4 100644 --- a/api/src/users/users.service.ts +++ b/api/src/users/users.service.ts @@ -1,10 +1,10 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { UpdateUserInput } from './inputs/update-user.input'; import { User } from './models/user.model'; -type InternalUser = Pick<User, 'id' | 'agreeNDA'>; +export type InternalUser = Pick<User, 'id' | 'agreeNDA'>; @Injectable() export class UsersService { @@ -13,20 +13,31 @@ export class UsersService { private readonly userRepository: Repository<InternalUser>, ) {} - getUser(id: string): InternalUser { - //return local informations NDA + /** + * Get a user by id + * @param {string} id - The id of the user to be retrieved. + * @returns The user object. + */ + async findOne(id: string): Promise<InternalUser> { + const user = await this.userRepository.findOne(id); - return { - id, - }; + if (!user) throw new NotFoundException(`User cannot be found in database.`); + + return user; } - async updateUser(id: string, data: UpdateUserInput): Promise<InternalUser> { - const user = await this.userRepository.preload({ + /** + * Update a user + * @param {string} id - The id of the user to update. + * @param {UpdateUserInput} data - update params + * @returns The updated user. + */ + async update(id: string, data: UpdateUserInput): Promise<InternalUser> { + const test = { id, ...data, - }); + }; - return this.userRepository.save(user); + return await this.userRepository.save(test); } }