This is my first question on here.
I have created login/register mutations that are working, However, I want to set up error handling so that when the user enters an incorrect username, it returns an error message "username incorrect", and the same with the password.
Currently, the error message returns when a user enters an incorrect username, but not when the user enters an incorrect password. Entering an incorrect password returns an object displaying a null user like so:
{
"data": {
"login": {
"user": null
}
}
}
I also have a register mutation that is working, however, the errors are not returning when an error condition is met, again, it returns a null user.
I have pasted the code below, the login mutation is the last one at the bottom. The register mutation is above this.
Thank you
import { User } from '../entities/User';
import { MyContext } from 'src/types';
import argon2 from 'argon2';
import {
Resolver,
Mutation,
Arg,
InputType,
Field,
Ctx,
ObjectType,
Query,
} from 'type-graphql';
@InputType()
class UsernamePasswordInput {
@Field()
username: string;
@Field()
password: string;
}
@ObjectType()
class FieldError {
@Field()
field: string;
message: string;
}
@ObjectType()
class UserResponse {
@Field(() => [FieldError], { nullable: true })
errors?: FieldError[];
@Field(() => User, { nullable: true })
user?: User;
}
// SAVE USER TO DATABASE
@Resolver()
export class UserResolver {
// GET ALL USERS
@Query(() => [User])
getAllUsers(@Ctx() { em }: MyContext): Promise<User[]> {
return em.find(User, {});
}
@Mutation(() => UserResponse)
async register(
@Arg('options') options: UsernamePasswordInput,
@Ctx() { em }: MyContext
): Promise<UserResponse> {
// username
if (options.username.length <= 2) {
return {
errors: [
{
field: 'username',
message: 'length must be greater than 2',
},
],
};
}
// password
if (options.password.length <= 3) {
return {
errors: [
{
field: 'password',
message: 'length must be greater than 3',
},
],
};
}
// hash password
const hashedPassword = await argon2.hash(options.password);
const user = em.create(User, {
username: options.username,
password: hashedPassword,
});
await em.persistAndFlush(user);
return {
user,
};
}
@Mutation(() => UserResponse)
async login(
@Arg('options') options: UsernamePasswordInput,
@Ctx() { em }: MyContext
): Promise<UserResponse> {
const user = await em.findOneOrFail(User, {
username: options.username,
});
if (!user) {
return {
errors: [
{
field: 'username',
message: ' incorrect username',
},
],
};
}
// verify the user password
const valid = await argon2.verify(user.password, options.password);
// if password is not valid, return errors
if (!valid) {
return {
errors: [
{
field: 'password',
message: 'incorrect password',
},
],
};
}
// return user
return {
user,
};
}
}