Feat/navigate to signup if email does not exist (#540)

* Add userExists route

* Fix demo mode for login

* Improve sign in/up flow

* Remove redundant password length constraint

* Fix test
This commit is contained in:
Emilien Chauvet
2023-07-08 15:02:39 -07:00
committed by GitHub
parent 36ace6cc03
commit 9cd5f7c057
10 changed files with 123 additions and 20 deletions

View File

@ -1,4 +1,4 @@
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { AuthTokens } from './dto/token.entity';
import { TokenService } from './services/token.service';
import { RefreshTokenInput } from './dto/refresh-token.input';
@ -13,6 +13,8 @@ import {
PrismaSelector,
} from 'src/decorators/prisma-select.decorator';
import { Prisma } from '@prisma/client';
import { UserExists } from './dto/user-exists.entity';
import { CheckUserExistsInput } from './dto/user-exists.input';
@Resolver()
export class AuthResolver {
@ -21,6 +23,16 @@ export class AuthResolver {
private tokenService: TokenService,
) {}
@Query(() => UserExists)
async checkUserExists(
@Args() checkUserExistsInput: CheckUserExistsInput,
): Promise<UserExists> {
const { exists } = await this.authService.checkUserExists(
checkUserExistsInput.email,
);
return { exists };
}
@Mutation(() => LoginToken)
async challenge(@Args() challengeInput: ChallengeInput): Promise<LoginToken> {
const user = await this.authService.challenge(challengeInput);

View File

@ -1,12 +1,5 @@
import { ArgsType, Field } from '@nestjs/graphql';
import {
IsEmail,
IsNotEmpty,
IsString,
Matches,
MinLength,
} from 'class-validator';
import { PASSWORD_REGEX } from '../auth.util';
import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator';
@ArgsType()
export class ChallengeInput {
@ -18,7 +11,5 @@ export class ChallengeInput {
@Field(() => String)
@IsNotEmpty()
@IsString()
@MinLength(8)
@Matches(PASSWORD_REGEX, { message: 'password too weak' })
password: string;
}

View File

@ -0,0 +1,7 @@
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType()
export class UserExists {
@Field(() => Boolean)
exists: boolean;
}

View File

@ -0,0 +1,10 @@
import { ArgsType, Field } from '@nestjs/graphql';
import { IsNotEmpty, IsString } from 'class-validator';
@ArgsType()
export class CheckUserExistsInput {
@Field(() => String)
@IsString()
@IsNotEmpty()
email: string;
}

View File

@ -11,6 +11,7 @@ import { PASSWORD_REGEX, compareHash, hashPassword } from '../auth.util';
import { Verify } from '../dto/verify.entity';
import { TokenService } from './token.service';
import { Prisma } from '@prisma/client';
import { UserExists } from '../dto/user-exists.entity';
export type UserPayload = {
firstName: string;
@ -26,18 +27,16 @@ export class AuthService {
) {}
async challenge(challengeInput: ChallengeInput) {
assert(
PASSWORD_REGEX.test(challengeInput.password),
'Password too weak',
BadRequestException,
);
let user = await this.userService.findUnique({
where: {
email: challengeInput.email,
},
});
const isPasswordValid = PASSWORD_REGEX.test(challengeInput.password);
assert(!!user || isPasswordValid, 'Password too weak', BadRequestException);
if (!user) {
const passwordHash = await hashPassword(challengeInput.password);
@ -92,4 +91,14 @@ export class AuthService {
},
};
}
async checkUserExists(email: string): Promise<UserExists> {
const user = await this.userService.findUnique({
where: {
email,
},
});
return { exists: !!user };
}
}