import { crypt, sha1, randomStr } from "../utils/CryptUtils"; import { APIClient } from "../entities/APIClient"; import { UserLoginTokens } from "../entities/UserLoginTokens"; import { DatabaseHelper } from "./DatabaseHelper"; import { UserHelper } from "./UserHelper"; /** * Account helper * * @author Pierre HUBERT */ const USER_TABLE = "utilisateurs"; const USERS_TOKENS_TABLE = "comunic_api_users_tokens"; export class AccountHelper { /** * Given email address and password, try to sign in user * * @param email The email of the user * @param password User password * @param client Information about associated client / null if none found */ static async LoginUser(email: string, password: string, client: APIClient) : Promise { // Perform a request on the database const row = await DatabaseHelper.QueryRow({ table: USER_TABLE, fields: ["ID"], where: { mail: email, password: this.CryptPassword(password) } }); // Check if user was found if(row == null) return null; const userID = row.ID; // Check for existing tokens let tokens = await this.GetClientTokens(userID, client); if(tokens != null) return tokens; const newTokens : UserLoginTokens = { userID: userID, clientID: client.id, token1: randomStr(150), token2: "dummy_data" } // Save new tokens await DatabaseHelper.InsertRow(USERS_TOKENS_TABLE, { user_id: newTokens.userID, service_id: newTokens.clientID, token1: newTokens.token1, token2: newTokens.token2 }); return newTokens; } /** * Get user client tokens (if it exists) * * @param userID Target user ID * @param client Information about associated client / null if none found */ private static async GetClientTokens(userID: number, client: APIClient): Promise { const row = await DatabaseHelper.QueryRow({ table: USERS_TOKENS_TABLE, where: { user_id: userID, service_id: client.id } }); return row == null ? null : this.DBToUserTokens(row); } /** * Find a user using its tokens * * @param client Information about the client * @param token1 First token * @param token2 Second token * @returns The ID of the target user / -1 if none found */ public static async GetUserIdFromTokens(client : APIClient, token1: string, token2: string) : Promise { const row = await DatabaseHelper.QueryRow({ table: USERS_TOKENS_TABLE, fields: ["user_id"], where: { service_id: client.id, token1: token1, token2: token2 } }); if(!row) return -1; return Number(row.user_id); } /** * Destroy user tokens * * @param client Information about the client * @param userID Target user ID */ public static async DestroyUserTokens(client: APIClient, userID: number) { return DatabaseHelper.DeleteRows(USERS_TOKENS_TABLE, { service_id: client.id, user_id: userID }); } /** * Check out whether the password of a user is valid * or not * * @param userID Target user ID * @param password Target password */ public static async CheckUserPassword(userID: number, password: string) : Promise { const crypt_pass = this.CryptPassword(password); return await DatabaseHelper.Count({ table: USER_TABLE, where: { ID: userID, password: crypt_pass } }) > 0; } /** * Crypt a password * * @param pass The password to crypt * @return Encrypted string */ private static CryptPassword(pass: string) : string { return crypt(sha1(pass), sha1(pass)); } private static DBToUserTokens(row : any) : UserLoginTokens { return { userID: row.user_id, clientID: row.service_id, token1: row.token1, token2: row.token2 }; } /** * Check out whether a virtual directory is available or not * * @param dir Virtual directory to check * @param userID Target user ID */ public static async CheckUserDirectoryAvailability(dir: string, userID: number = -1) : Promise { const foundUser = await UserHelper.FindByFolder(dir); return foundUser < 1 || userID == foundUser; } }