Implement login method

This commit is contained in:
2023-09-04 17:00:57 +07:00
parent ff394c13b4
commit b5c94bb35b
10 changed files with 143 additions and 3 deletions
+1
View File
@@ -11,5 +11,6 @@ export default class App {
start() {
this.controller.registerController.init();
this.controller.loginController.init();
}
}
@@ -4,6 +4,7 @@ export const MESSAGE = {
'Password must at least one uppercase, one lowercase letter, one number and one special character!',
ERROR_MESSAGE_DEFAULT: 'Something went wrong!',
TIME_OUT_ERROR: 'Connection time out! Please try again!',
ERROR_CREDENTIAL: 'Email or password not match! Please try again!',
};
export const TYPE_POPUP = { success: 'success', error: 'error' };
export const MARK_ICON = { success: 'check', error: 'error' };
@@ -1,7 +1,9 @@
import LoginController from './loginController';
import RegisterController from './registerController';
export default class Controller {
constructor(service, view) {
this.registerController = new RegisterController(service, view);
this.loginController = new LoginController(service, view);
}
}
@@ -0,0 +1,23 @@
export default class LoginController {
constructor(service, view) {
this.service = service;
this.loginView = view.loginView;
}
handlerGetUserByEmail(email) {
return this.service.userService.getUserByEmail(email);
}
handlerCreateTokenUser(user) {
return this.service.userService.createTokenUser(user);
}
init() {
if (this.loginView.isLoginPage()) {
this.loginView.addHandlerForm(
this.handlerGetUserByEmail.bind(this),
this.handlerCreateTokenUser.bind(this),
);
}
}
}
@@ -35,3 +35,18 @@ export const timeOutConnect = async (action) => {
return result;
};
/**
* A function create token for user
* @returns {string} Return token string
*/
export const createToken = () => {
const lengthToken = 36;
const chars =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let token = '';
for (let i = 0; i < lengthToken; i += 1) {
token += chars[Math.floor(Math.random() * chars.length)];
}
return token;
};
@@ -22,13 +22,13 @@ export default class CommonService {
return result;
}
async save(data, path = this.path) {
async save(data, path = this.defaultPath) {
this.connectToDb();
const saveUser = this.firebaseService.save(data, path);
await timeOutConnect(saveUser);
}
async getDataFromId(id, path = this.path) {
async getDataFromId(id, path = this.defaultPath) {
this.connectToDb();
const data = await this.firebaseService.getDataFromId(id, path);
if (data) return data;
@@ -1,3 +1,4 @@
import { createToken } from '../helpers/helpers';
import User from '../models/user';
import CommonService from './commonService';
@@ -52,4 +53,14 @@ export default class UserService extends CommonService {
}
return null;
}
async createTokenUser(user) {
const id = await this.getUserIdByEmail(user.email);
// Add token to user object
const newUserData = new User(user);
newUserData.accessToken = createToken();
this.save(newUserData, this.defaultPath + id);
}
}
@@ -0,0 +1,84 @@
import CommonLoginRegisterView from './commonLoginRegisterView';
import * as CONSTANT from '../constants/constant';
export default class LoginView extends CommonLoginRegisterView {
constructor() {
super();
this.parentElement = document.querySelector('.form');
this.loginPage = document.getElementById('loginPage');
}
/**
* Get data from user input
* @returns {Object || null} Return object or null
*/
getDataFromForm() {
const { loginForm } = document.forms;
const formData = new FormData(loginForm);
const email = formData.get('email');
const password = formData.get('password');
this.account = { email, password };
return this.account;
}
/**
* Implement error popup in site
* @param {string} content The content will show in error popup
*/
initErrorPopup(content) {
const typePopup = CONSTANT.TYPE_POPUP.error;
const title = 'Error Credential!';
const btnContent = 'Got it!';
this.initPopupContent(typePopup, title, content, btnContent);
// Show popup
this.tooglePopupForm();
}
/**
* Add event listener for form input
* @param {Function} handler The function need to be set event
*/
addHandlerForm(getUserByEmail, createTokenUser) {
this.parentElement.addEventListener('submit', (e) => {
e.preventDefault();
this.clearErrorMessage();
this.submitForm(getUserByEmail, createTokenUser);
});
}
async submitForm(getUserByEmail, createTokenUser) {
try {
// Load spinner
this.toogleLoaderSpinner();
// Get data from form
const userInput = this.getDataFromForm();
// Check user exist
const user = await getUserByEmail(userInput.email);
if (user) {
// If user exist, compare password
if (userInput.password === user.password) {
await createTokenUser(user);
window.location.replace('/');
return;
}
}
throw Error(CONSTANT.MESSAGE.ERROR_CREDENTIAL);
} catch (error) {
// Show popup error
this.initErrorPopup(error);
}
// Close spinner
this.toogleLoaderSpinner();
}
isLoginPage() {
return this.loginPage !== null;
}
}
+2
View File
@@ -1,7 +1,9 @@
import RegisterView from './registerView';
import LoginView from './loginView';
export default class View {
constructor() {
this.registerView = new RegisterView();
this.loginView = new LoginView();
}
}
+2 -1
View File
@@ -16,7 +16,7 @@
alt="Logo web"
/>
<!-- Log in form -->
<form action="#" class="form" method="post">
<form action="#" class="form" method="post" id="loginForm">
<div class="form__container">
<h1 class="form__title">Log In</h1>
<p class="form__description">Using Money Lover account</p>
@@ -45,5 +45,6 @@
</div>
</div>
</main>
<script type="module" src="../js/main.js"></script>
</body>
</html>