Untitled

 avatar
unknown
plain_text
2 years ago
5.2 kB
2
Indexable
//Reactjs
import { useContext } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import * as yup from 'yup';
import { useAlert } from 'react-alert';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { Button, Typography, Avatar, Container } from '@mui/material';
import ControlledTextInput from 'src/components/mui-react-hook-form/ControlledTextInput';
import { Box } from '@mui/system';
import { LockOutlined } from '@mui/icons-material';
import ApiConfig from '../../api/api-config';
import { AuthContext } from '../../context/AuthContext';
import axiosHook from '../../api/axios-hook';


function Copyright(props) {
return (
<Typography
variant="body2"
color="text.secondary"
align="center"
{...props}
>
{'Copyright © '}
<Link color="inherit" to="https://nitti.in/">
NITTI
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
const schema = yup.object({
phone: yup
.string()
.matches(/^[6-9]{1}[0-9]{9}$/, 'Invalid phone number!')
.required('Field is required!'),
password: yup.string().min(8).max(20).required(),
});


const Login = () => {
const alert = useAlert();


const {
control,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
mode: 'all',
});


const navigate = useNavigate();
const { dispatch } = useContext(AuthContext);
const [, doLogin] = axiosHook(
{
...ApiConfig.AUTH.LOGIN,
},
{ manual: true }
);


const handleLogin = () => {
handleSubmit(async (data) => {
try {
const response = await doLogin({
data,
});
dispatch({ type: 'LOGIN', payload: response.data });
navigate('/dashboard');
alert.success('Logged in!');
} catch (error) {
console.log(error);
alert.error(error.response.data.message);
}
})();
};


return (
<Container component="main" maxWidth="xs">
{/* <CssBaseline /> */}
<Box
sx={{
marginTop: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
<LockOutlined />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Box
component="form"
noValidate
sx={{ mt: 1 }}
onSubmit={handleSubmit(handleLogin)}
>
<ControlledTextInput
name={'phone'}
control={control}
label="Phone"
variant="outlined"
margin="normal"
/>
<ControlledTextInput
name={'password'}
control={control}
label="Password"
variant="outlined"
margin="normal"
type="password"
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
disabled={Boolean(Object.keys(errors).length)}
>
Sign In
</Button>
</Box>
</Box>
<Copyright sx={{ mt: 8, mb: 4 }} />
</Container>
);
};


export default Login;



// typescript-nest.js


import {
BadRequestException,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { RoleService } from 'src/role/role.service';
import { Repository } from 'typeorm';
import { Auth } from './auth.entity';
import { CreateAuthDto } from './dto/create-auth.dto';
import { PasswordService } from './password.service';


@Injectable()
export class AuthService {
constructor(
@InjectRepository(Auth)
private readonly authRepository: Repository<Auth>,
private readonly roleService: RoleService,
private readonly passwordService: PasswordService,
private readonly jwtService: JwtService,
) {}


/**
*Finds an Auth entity based on the provided email or username.
*@param email - User email.
*@returns A Promise that resolves to an Auth entity if one is found.
* @throws BadRequestException if the user not found
*/
async findAuthDetailByEmail(email: string): Promise<Auth> {
const userAuth = await this.authRepository.findOne({
where: {
email,
},
relations: ['user'],
});


return userAuth;
}


/**
* Register a new user with the given credentials.
* @param createAuthDto - DTO containing the user's credentials.
* @returns The registered user's auth details.
* @throws BadRequestException if the user with the given email already exists.
* @throws BadRequestException if the user role is invalid
*/
async registerUser(createAuthDto: CreateAuthDto): Promise<Auth> {
// check if user already exists
const existingUser = await this.findAuthDetailByEmail(createAuthDto.email);
if (existingUser) {
throw new BadRequestException('User already registered, please login!');
}


// find the user's role
const role = await this.roleService.findByRoleName(createAuthDto.role.name);
if (!role) {
throw new BadRequestException('Invalid role passed.');
}


// set the user's role and create the Auth entity
createAuthDto.role = role;
const auth = this.authRepository.create(createAuthDto);


// save the Auth entity and return it
return this.authRepository.save(auth);
}


async validateUser(email: string, password: string): Promise<Auth> {
const existingUser = await this.findAuthDetailByEmail(email);
if (!existingUser) {
throw new NotFoundException('Account not found');
}
if (
!(await this.passwordService.comparePassword(
password,
existingUser.password,
))
) {
return null;
}
return existingUser;
}


async loginUser(userAuth: Auth) {
const payload = { email: userAuth.email, sub: userAuth.user.id };
return {
accessToken: this.jwtService.sign(payload),
};
}
}
Editor is loading...