From 9aff78b7a94d0ba568ccc04f5410b4cbeadc7ace Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Wed, 20 Mar 2019 13:23:46 +0500 Subject: [PATCH] Add ability to search users by email This might be a security concern, even though the user will have to provide an email to retrieve user information. This functionality is needed by Team management functionality because expecting users to add a user by id is hard. TODO: explore other options. Maybe add public profiles and request the user to go to the profile to invite a user to team? --- packages/server/src/routes/UserRoutes.test.ts | 27 +++++++++++++++++++ packages/server/src/routes/UserRoutes.ts | 4 +++ packages/server/src/services/IUserService.ts | 1 + packages/server/src/services/UserService.ts | 14 +++++++++- 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/server/src/routes/UserRoutes.test.ts b/packages/server/src/routes/UserRoutes.test.ts index f6552ec..f8b0d01 100644 --- a/packages/server/src/routes/UserRoutes.test.ts +++ b/packages/server/src/routes/UserRoutes.test.ts @@ -48,4 +48,31 @@ describe('user', () => { .expect(200) }) }) + + describe('GET /users/emails/:email', () => { + it('fetches user by email', async () => { + t.setHeaders({cookie}) + const response = await t + .get('/users/emails/:email', { + params: { + email: 'test@user.com', + }, + }) + .expect(200) + expect(response.body!.firstName).toEqual('test') + }) + it('returns an empty body when email is not found', async () => { + t.setHeaders({cookie}) + await t + .get('/users/emails/:email', { + params: { + email: 'non-existing@address.com', + } + }) + .expect(200) + .expect(/^$/g) + // TODO use status code 404 when an entity is not found + }) + }) + }) diff --git a/packages/server/src/routes/UserRoutes.ts b/packages/server/src/routes/UserRoutes.ts index 210f81b..6164f5a 100644 --- a/packages/server/src/routes/UserRoutes.ts +++ b/packages/server/src/routes/UserRoutes.ts @@ -23,6 +23,10 @@ export class UserRoutes extends BaseRoute { }) }) + t.get('/users/emails/:email', async req => { + return this.userService.findUserByEmail(req.params.email) + }) + t.get('/users/profile', async req => { return (await this.userService.findOne(req.user!.id))! }) diff --git a/packages/server/src/services/IUserService.ts b/packages/server/src/services/IUserService.ts index cc2e334..b4b2459 100644 --- a/packages/server/src/services/IUserService.ts +++ b/packages/server/src/services/IUserService.ts @@ -9,4 +9,5 @@ export interface IUserService { }): Promise validateCredentials(credentials: ICredentials): Promise findOne(id: number): Promise + findUserByEmail(email: string): Promise } diff --git a/packages/server/src/services/UserService.ts b/packages/server/src/services/UserService.ts index 22b09cc..e75d829 100644 --- a/packages/server/src/services/UserService.ts +++ b/packages/server/src/services/UserService.ts @@ -70,7 +70,19 @@ export class UserService extends BaseService implements IUserService { .findOne({ email }, { relations: ['user'], }) - return userEmail && userEmail.user + + if (!userEmail) { + return + } + + const user = userEmail.user! + + return { + id: userEmail.userId!, + username: userEmail.email, + firstName: user.firstName, + lastName: user.lastName, + } } async changePassword(params: {