From bd22eb6ee69ad9f1fead797bd8c73476b6e96451 Mon Sep 17 00:00:00 2001 From: Loi Phan Date: Thu, 28 Sep 2023 17:34:06 +0700 Subject: [PATCH] Add user serice --- typescript-practice/src/ts/helpers/data.ts | 25 +++- typescript-practice/src/ts/models/user.ts | 12 ++ .../src/ts/services/commonService.ts | 29 ++++- .../src/ts/services/firebaseService.ts | 2 +- .../src/ts/services/userService.ts | 116 ++++++++++++++++++ 5 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 typescript-practice/src/ts/services/userService.ts diff --git a/typescript-practice/src/ts/helpers/data.ts b/typescript-practice/src/ts/helpers/data.ts index 2f0ac13..57a2db8 100644 --- a/typescript-practice/src/ts/helpers/data.ts +++ b/typescript-practice/src/ts/helpers/data.ts @@ -1,4 +1,4 @@ -import { DataObject } from '../global/types'; +import { DataObject, IDataObject } from '../global/types'; export const createIdUser = (): number => { return new Date().getTime(); @@ -10,10 +10,23 @@ export const convertDataObjectToModel = (dataObj: DataObject): T => { return { id, ...dataObj.data } as T; }; -export const convertModelToDataObject = >( - model: T, -): T => { - const { id, ...data } = model; +export const convertModelToDataObject = (model: T): DataObject => { + const { id, ...data } = model as IDataObject; - return { id, data } as T; + return { id, data } as DataObject; +}; + +/** + * A function create token for user + * @returns {string} Return token string + */ +export const createToken = (): string => { + const lengthToken: number = 36; + const chars: string = + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + let token: string = ''; + for (let i: number = 0; i < lengthToken; i += 1) { + token += chars[Math.floor(Math.random() * chars.length)]; + } + return token; }; diff --git a/typescript-practice/src/ts/models/user.ts b/typescript-practice/src/ts/models/user.ts index 03ff9b8..e5fb6e2 100644 --- a/typescript-practice/src/ts/models/user.ts +++ b/typescript-practice/src/ts/models/user.ts @@ -15,4 +15,16 @@ export default class User { this.password = password; this.accessToken = accessToken; } + + get getPassword() { + return this.password; + } + + set setAccessToken(accessToken: string) { + this.accessToken = accessToken; + } + + get getAccessToken() { + return this.accessToken; + } } diff --git a/typescript-practice/src/ts/services/commonService.ts b/typescript-practice/src/ts/services/commonService.ts index 92f39cd..579bb73 100644 --- a/typescript-practice/src/ts/services/commonService.ts +++ b/typescript-practice/src/ts/services/commonService.ts @@ -6,8 +6,8 @@ import { import { DataObject } from '../global/types'; import FirebaseService from './firebaseService'; -export default class CommonService> { - private defaultPath: string = '/'; +export default class CommonService { + public defaultPath: string = '/'; private firebaseService = FirebaseService; /** @@ -24,10 +24,11 @@ export default class CommonService> { */ async save(model: T): Promise { this.connectToDb(); - const results: T = convertModelToDataObject(model); + + const results: DataObject = convertModelToDataObject(model); const saveData = this.firebaseService.save( - results.data, + results.data as object, this.defaultPath + results.id, ); @@ -55,6 +56,22 @@ export default class CommonService> { return null; } + async getDataFromProp( + property: string, + value: string, + path = this.defaultPath, + ) { + this.connectToDb(); + const data = this.firebaseService.getDataFromProp(path, property, value); + const result = (await timeOutConnect(data)) as DataObject; + + if (result && typeof result === 'object') { + return convertDataObjectToModel(result); + } + + return null; + } + async getAllDataFromPath(path = this.defaultPath): Promise { this.connectToDb(); @@ -68,7 +85,7 @@ export default class CommonService> { const tempData = data as DataObject; return convertDataObjectToModel(tempData); - }); + }) as object[]; } return null; @@ -92,7 +109,7 @@ export default class CommonService> { const tempData = data as DataObject; return convertDataObjectToModel(tempData); - }); + }) as object[]; } return null; diff --git a/typescript-practice/src/ts/services/firebaseService.ts b/typescript-practice/src/ts/services/firebaseService.ts index 89ceac8..b4290c9 100644 --- a/typescript-practice/src/ts/services/firebaseService.ts +++ b/typescript-practice/src/ts/services/firebaseService.ts @@ -61,7 +61,7 @@ class FirebaseService { getDataFromProp( path: string, property: string, - value: object, + value: string, ): Promise { return new Promise((resolve) => { onValue( diff --git a/typescript-practice/src/ts/services/userService.ts b/typescript-practice/src/ts/services/userService.ts new file mode 100644 index 0000000..9809860 --- /dev/null +++ b/typescript-practice/src/ts/services/userService.ts @@ -0,0 +1,116 @@ +import { LOCAL_STORAGE } from '../constants/config'; +import { createToken } from '../helpers/data'; +import User from '../models/user'; +import CommonService from './commonService'; +import LocalStorageService from './localStorageService'; + +export default class UserService { + private _commonService: CommonService; + + constructor() { + this._commonService = new CommonService(); + } + + /** + * Save user into database + * @param {Object} user The user object need to be saved into databae + */ + saveUser(user: User): void { + this._commonService.save(user); + } + + /** + * Check user exist in database + * @param {string} email Email to find user + * @returns {boolean} Return true if find, otherwise return false + */ + async isValidUser(email: string): Promise { + const userExist = await this.getUserByEmail(email); + + return !!userExist; + } + + /** + * Get user data from email + * @param {string} email Email user + * @returns {Object || null} Return new User Object if find, otherwise return null. + */ + async getUserByEmail(email: string): Promise { + const result = await this._commonService.getDataFromProp('email', email); + + return result || null; + } + + /** + * Validate user info + * @param {string} email The email user input + * @param {*} password The password user input + * @returns {boolean} Return true if match info on database, otherwise return false + */ + async loginUser(email: string, password: string): Promise { + const user = await this.getUserByEmail(email); + + // Check password + if (user && user.getPassword === password) { + // Create token for user + await this.createTokenUser(email); + + return true; + } + + return false; + } + + /** + * Create token for user on database + * @param {string} email The email user need to be create token + */ + async createTokenUser(email: string): Promise { + const user = await this.getUserByEmail(email); + if (user) { + const newUserData = user; + + // Add token to user object + newUserData.setAccessToken = createToken(); + + this._commonService.save(newUserData); + + // Add access token to local storage + LocalStorageService.add( + LOCAL_STORAGE.ACCESS_TOKEN, + newUserData.getAccessToken, + ); + } + } + + async getInfoUserLogin(): Promise { + // Find access token + const accessToken = LocalStorageService.get(LOCAL_STORAGE.ACCESS_TOKEN); + + if (accessToken) { + const user = await this.getUserByToken(accessToken); + + return user; + } + + return null; + } + + /** + * Get user data from token access + * @param {string} accessToken Access token user + * @returns {Object || null} Return new User Object if find, otherwise return null. + */ + async getUserByToken(accessToken: string): Promise { + const result = await this._commonService.getDataFromProp( + 'accessToken', + accessToken, + ); + + return result || null; + } + + static clearAccessToken(): void { + LocalStorageService.remove(LOCAL_STORAGE.ACCESS_TOKEN); + } +}