From 5fe934110e5386790942a7bb084ff495161d3f83 Mon Sep 17 00:00:00 2001 From: Balu Babu Date: Fri, 13 Jan 2023 01:46:34 +0530 Subject: [PATCH] fix: fixed the timestamp comparison login in verifyPasswordlessTokens route --- .../src/auth/auth.service.ts | 31 +++++++++++++++++-- .../src/auth/strategies/google.strategy.ts | 18 ++++++++++- .../hoppscotch-backend/src/types/AuthUser.ts | 5 +++ .../src/user/user.service.ts | 7 ++++- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/packages/hoppscotch-backend/src/auth/auth.service.ts b/packages/hoppscotch-backend/src/auth/auth.service.ts index 42c8b33b5..d95a0fc1f 100644 --- a/packages/hoppscotch-backend/src/auth/auth.service.ts +++ b/packages/hoppscotch-backend/src/auth/auth.service.ts @@ -215,8 +215,35 @@ export class AuthService { statusCode: HttpStatus.NOT_FOUND, }); - const currentTime = DateTime.now().toISOTime(); - //TODO: new to check this datetime checking logic + const user = await this.usersService.findUserById( + passwordlessTokens.value.userUid, + ); + if (O.isNone(user)) + return E.left({ + message: USER_NOT_FOUND, + statusCode: HttpStatus.NOT_FOUND, + }); + + // Check to see if entry for magic-link is present in the Account table for this user + const profile = { + provider: 'email', + id: user.value.email, + }; + const providerAccountExists = await this.checkIfProviderAccountExists( + user.value, + profile, + ); + + if (O.isNone(providerAccountExists)) { + await this.usersService.createProviderAccount( + user.value, + null, + null, + profile, + ); + } + + const currentTime = DateTime.now().toISO(); if (currentTime > passwordlessTokens.value.expiresOn.toISOString()) return E.left({ message: MAGIC_LINK_EXPIRED, diff --git a/packages/hoppscotch-backend/src/auth/strategies/google.strategy.ts b/packages/hoppscotch-backend/src/auth/strategies/google.strategy.ts index f47ce8464..d4247b7ed 100644 --- a/packages/hoppscotch-backend/src/auth/strategies/google.strategy.ts +++ b/packages/hoppscotch-backend/src/auth/strategies/google.strategy.ts @@ -3,10 +3,14 @@ import { PassportStrategy } from '@nestjs/passport'; import { Injectable } from '@nestjs/common'; import { UserService } from 'src/user/user.service'; import * as O from 'fp-ts/Option'; +import { AuthService } from '../auth.service'; @Injectable() export class GoogleStrategy extends PassportStrategy(Strategy) { - constructor(private usersService: UserService) { + constructor( + private usersService: UserService, + private authService: AuthService, + ) { super({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, @@ -30,6 +34,18 @@ export class GoogleStrategy extends PassportStrategy(Strategy) { return createdUser; } + // Check to see if entry for google is present in the Account table for this user + const providerAccountExists = + await this.authService.checkIfProviderAccountExists(user.value, profile); + + if (O.isNone(providerAccountExists)) + await this.usersService.createProviderAccount( + user.value, + accessToken, + refreshToken, + profile, + ); + return user.value; } } diff --git a/packages/hoppscotch-backend/src/types/AuthUser.ts b/packages/hoppscotch-backend/src/types/AuthUser.ts index 18e450a5b..ee67c4fb8 100644 --- a/packages/hoppscotch-backend/src/types/AuthUser.ts +++ b/packages/hoppscotch-backend/src/types/AuthUser.ts @@ -1,3 +1,8 @@ import { User } from '@prisma/client'; export type AuthUser = User; + +export interface SSOProviderProfile { + provider: string; + id: string; +} diff --git a/packages/hoppscotch-backend/src/user/user.service.ts b/packages/hoppscotch-backend/src/user/user.service.ts index c502629d2..cf0f374a4 100644 --- a/packages/hoppscotch-backend/src/user/user.service.ts +++ b/packages/hoppscotch-backend/src/user/user.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { PrismaService } from 'src/prisma/prisma.service'; import * as O from 'fp-ts/Option'; +import { AuthUser, SSOProviderProfile } from 'src/types/AuthUser'; @Injectable() export class UserService { @@ -71,11 +72,15 @@ export class UserService { async createProviderAccount(user, accessToken, refreshToken, profile) { const createdProvider = await this.prisma.account.create({ data: { - userId: user.id, provider: profile.provider, providerAccountId: profile.id, providerRefreshToken: refreshToken ? refreshToken : null, providerAccessToken: accessToken ? accessToken : null, + user: { + connect: { + id: user.id, + }, + }, }, });