feat: onboarding & profile edition (#507)
* feat: wip onboarding * fix: generate graphql front * wip: onboarding * feat: login/register and edit profile * fix: unused import * fix: test * Use DEBUG_MODE instead of STAGE and mute typescript depth exceed errors * Fix seeds * Fix onboarding when coming from google * Fix * Fix lint * Fix ci * Fix tests --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { Args, Mutation, Resolver, Query} from '@nestjs/graphql';
|
||||
import { AuthTokens, ClientConfig} from './dto/token.entity';
|
||||
import { Args, Mutation, Resolver, Query } from '@nestjs/graphql';
|
||||
import { AuthTokens, ClientConfig } from './dto/token.entity';
|
||||
import { TokenService } from './services/token.service';
|
||||
import { RefreshTokenInput } from './dto/refresh-token.input';
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
@ -74,4 +74,4 @@ export class AuthResolver {
|
||||
|
||||
return Promise.resolve(clientConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
import { ArgsType, Field } from '@nestjs/graphql';
|
||||
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
||||
import {
|
||||
IsEmail,
|
||||
IsNotEmpty,
|
||||
IsString,
|
||||
Matches,
|
||||
MinLength,
|
||||
} from 'class-validator';
|
||||
import { PASSWORD_REGEX } from '../auth.util';
|
||||
|
||||
@ArgsType()
|
||||
export class ChallengeInput {
|
||||
@ -11,5 +18,7 @@ export class ChallengeInput {
|
||||
@Field(() => String)
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@MinLength(8)
|
||||
@Matches(PASSWORD_REGEX, { message: 'password too weak' })
|
||||
password: string;
|
||||
}
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
import {
|
||||
IsEmail,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Matches,
|
||||
MinLength,
|
||||
} from 'class-validator';
|
||||
import { PASSWORD_REGEX } from '../auth.util';
|
||||
import { ArgsType, Field } from '@nestjs/graphql';
|
||||
|
||||
@ArgsType()
|
||||
export class RegisterInput {
|
||||
@Field(() => String)
|
||||
@IsNotEmpty()
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@Field(() => String)
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@MinLength(8)
|
||||
@Matches(PASSWORD_REGEX, { message: 'password too weak' })
|
||||
password: string;
|
||||
|
||||
@Field(() => String, {
|
||||
deprecationReason: 'Deprecated, please use firstName and lastName instead',
|
||||
nullable: true,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
displayName?: string;
|
||||
|
||||
@Field(() => String)
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
firstName: string;
|
||||
|
||||
@Field(() => String)
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
lastName: string;
|
||||
}
|
||||
@ -31,4 +31,4 @@ export class ClientConfig {
|
||||
|
||||
@Field(() => Boolean)
|
||||
prefill_login_with_seed: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import {
|
||||
import { ChallengeInput } from '../dto/challenge.input';
|
||||
import { UserService } from 'src/core/user/user.service';
|
||||
import { assert } from 'src/utils/assert';
|
||||
import { RegisterInput } from '../dto/register.input';
|
||||
import { PASSWORD_REGEX, compareHash, hashPassword } from '../auth.util';
|
||||
import { Verify } from '../dto/verify.entity';
|
||||
import { TokenService } from './token.service';
|
||||
@ -26,42 +25,31 @@ export class AuthService {
|
||||
private readonly userService: UserService,
|
||||
) {}
|
||||
|
||||
async register(registerInput: RegisterInput) {
|
||||
const existingUser = await this.userService.findUnique({
|
||||
where: {
|
||||
email: registerInput.email,
|
||||
},
|
||||
});
|
||||
|
||||
assert(!existingUser, 'This user already exist', NotFoundException);
|
||||
async challenge(challengeInput: ChallengeInput) {
|
||||
assert(
|
||||
PASSWORD_REGEX.test(registerInput.password),
|
||||
PASSWORD_REGEX.test(challengeInput.password),
|
||||
'Password too weak',
|
||||
BadRequestException,
|
||||
);
|
||||
|
||||
const passwordHash = await hashPassword(registerInput.password);
|
||||
|
||||
const user = await this.userService.createUser({
|
||||
data: {
|
||||
firstName: registerInput.firstName,
|
||||
lastName: registerInput.lastName,
|
||||
email: registerInput.email,
|
||||
passwordHash,
|
||||
locale: 'en',
|
||||
},
|
||||
});
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
async challenge(challengeInput: ChallengeInput) {
|
||||
const user = await this.userService.findUnique({
|
||||
let user = await this.userService.findUnique({
|
||||
where: {
|
||||
email: challengeInput.email,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
const passwordHash = await hashPassword(challengeInput.password);
|
||||
|
||||
user = await this.userService.createUser({
|
||||
data: {
|
||||
email: challengeInput.email,
|
||||
passwordHash,
|
||||
locale: 'en',
|
||||
},
|
||||
} as Prisma.UserCreateArgs);
|
||||
}
|
||||
|
||||
assert(user, "This user doesn't exist", NotFoundException);
|
||||
assert(user.passwordHash, 'Incorrect login method', ForbiddenException);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user