1
0
mirror of https://gitlab.com/comunic/comunicapiv2 synced 2024-11-23 22:09:23 +00:00
comunicapiv2/src/controllers/AccountController.ts

326 lines
8.6 KiB
TypeScript
Raw Normal View History

2019-11-22 07:50:15 +00:00
import { RequestHandler } from "../entities/RequestHandler";
2019-11-23 12:16:28 +00:00
import { AccountHelper } from "../helpers/AccountHelper";
import { UserHelper } from "../helpers/UserHelper";
2019-12-30 12:44:54 +00:00
import { NewAccount } from "../entities/NewAccount";
import { removeHTMLNodes } from "../utils/StringUtils";
2020-03-25 08:04:04 +00:00
import { limit_query } from "./APILimitsController";
import { Action } from "../helpers/APILimitsHelper";
2020-03-25 17:24:46 +00:00
import { UserController } from "./UserController";
2020-03-25 17:44:51 +00:00
import { PostsController } from "./PostsController";
2020-03-25 17:55:25 +00:00
import { CommentsController } from "./CommentsController";
2020-03-25 18:08:43 +00:00
import { LikesController } from "./LikesController";
import { SurveyController } from "./SurveyController";
2020-03-26 11:13:53 +00:00
import { MoviesController } from "./MoviesController";
2020-03-26 12:05:14 +00:00
import { ConversationsController } from "./ConversationsController";
2020-03-26 12:29:39 +00:00
import { FriendsController } from "./FriendsController";
2020-03-26 12:59:30 +00:00
import { GroupsHelper } from "../helpers/GroupsHelper";
import { GroupsController } from "./GroupsController";
2019-11-22 07:50:15 +00:00
/**
* Account controller
*
* @author Pierre HUBERT
*/
export class AccountController {
2019-12-30 12:44:54 +00:00
/**
* Create a new account
*
* @param h Request handler
*/
public static async Create(h: RequestHandler) {
2020-03-25 17:06:42 +00:00
// Limit request
await limit_query(h, Action.CREATE_ACCOUNT, false);
2019-12-30 12:44:54 +00:00
// Get & check email address
const email = h.postEmail("emailAddress");
if(await AccountHelper.ExistsEmail(email))
h.error(409, "This email address already belongs to an account!");
const newAccount = <NewAccount>{
firstName: removeHTMLNodes(h.postString("firstName")),
lastName: removeHTMLNodes(h.postString("lastName")),
email: email,
password: h.postString("password", 3)
};
// Try to create the account
await AccountHelper.Create(newAccount);
2020-03-25 17:06:42 +00:00
// Trigger the API limit
await limit_query(h, Action.CREATE_ACCOUNT, true);
2019-12-30 12:44:54 +00:00
// Success
h.success("The account has been created!");
}
2019-11-22 07:50:15 +00:00
/**
* Attempt to login user
*
2020-03-25 08:04:04 +00:00
* @param h Request handler
2019-11-22 07:50:15 +00:00
*/
2020-03-25 08:04:04 +00:00
public static async LoginUser(h: RequestHandler) {
2019-11-22 07:50:15 +00:00
2019-11-23 12:16:28 +00:00
// Get post data
2020-03-25 08:04:04 +00:00
const email = h.postEmail("userMail");
const password = h.postString("userPassword");
2019-11-23 12:16:28 +00:00
2020-03-25 08:04:04 +00:00
// Limit request
await limit_query(h, Action.LOGIN_FAILED, false);
2019-11-23 12:16:28 +00:00
// Authenticate user
2020-03-25 08:04:04 +00:00
const tokens = await AccountHelper.LoginUser(email, password, h.getClientInfo());
2019-11-23 12:16:28 +00:00
if(tokens == null) {
2020-03-25 08:04:04 +00:00
// Trigger limit
await limit_query(h, Action.LOGIN_FAILED, true);
2019-11-23 12:16:28 +00:00
2020-03-25 08:04:04 +00:00
h.error(401, "Invalid e-mail address / password !");
2019-11-23 12:16:28 +00:00
}
// Success
2020-03-25 08:04:04 +00:00
h.send({
2019-11-23 12:16:28 +00:00
success: "User signed in!",
tokens: {
token1: tokens.token1,
token2: tokens.token2
}
});
2019-11-22 07:50:15 +00:00
}
2019-11-23 13:03:14 +00:00
/**
* Disconnect user
*
* @param handler
*/
public static async LogoutUser(handler: RequestHandler) {
await AccountHelper.DestroyUserTokens(handler.getClientInfo(),
handler.getUserId());
handler.success("User has been disconnected!");
}
2019-11-23 12:48:16 +00:00
/**
* Get current user ID
*
2020-03-28 14:21:06 +00:00
* @param h Request handler
2019-11-23 12:48:16 +00:00
*/
2020-03-28 14:21:06 +00:00
public static async CurrentUserID(h: RequestHandler) {
// Update user activity (if allowed)
if(!h.postBool("incognito", false))
await AccountHelper.UpdateLastActivity(h.getUserId())
h.send({
userID: h.getUserId()
2019-11-23 12:48:16 +00:00
});
}
/**
* Check out whether an email is associated to an account
* or not
*
* @param h Request handler
*/
public static async ExistsMail(h: RequestHandler) {
const email = h.postEmail("email");
h.send({
exists: await AccountHelper.ExistsEmail(email)
})
}
/**
* Check if an account associated with an email address has
* setup security questions or not
*
* @param h Request handler
*/
public static async HasSecurityQuestions(h: RequestHandler) {
const userID = await h.postUserIdFromEmail("email");
const settings = await UserHelper.GetUserInfo(userID);
h.send({
defined: settings.hasSecurityQuestions
})
}
2019-12-30 07:16:10 +00:00
/**
* Get the security questions of a user, in order to reset its
* password
*
* @param h Request handler
*/
public static async GetSecurityQuestions(h: RequestHandler) {
const userID = await h.postUserIdFromEmail("email");
const settings = await UserHelper.GetUserInfo(userID);
if(!settings.hasSecurityQuestions)
h.error(401, "Specified user has not setup security questions !");
h.send({
questions: [
settings.security_question_1,
settings.security_question_2
]
})
}
2019-12-30 07:36:55 +00:00
/**
* Check the answer given by the user
*
* @param h Request handler
*/
public static async CheckSecurityAnswers(h: RequestHandler) {
const userID = await h.postUserIdFromEmail("email");
const settings = await UserHelper.GetUserInfo(userID);
if(!settings.hasSecurityQuestions)
h.error(401, "Specified user has not setup security questions !");
// Get the answers of the user
const answers = h.postString("answers", 3).split("&")
.map((e) => decodeURIComponent(e).toLowerCase().trim());
if(answers.length != 2)
h.error(401, "Please specify two security answers !");
// Check the answers
if(answers[0] != settings.security_answer_1.toLowerCase().trim() ||
answers[1] != settings.security_answer_2.toLowerCase().trim())
h.error(401, "Specified ecurity answers are invalid!");
// If we get there, security answers are valid, we can create a password reset token
h.send({
reset_token: await AccountHelper.GenerateNewPasswordResetToken(userID)
});
}
2019-12-30 11:11:33 +00:00
/**
* Check the validity of a password reset Token
*
* @param h Request handler
*/
public static async CheckPasswordResetToken(h: RequestHandler) {
2019-12-30 12:20:24 +00:00
// We just get user ID to check the validity of the token
2019-12-30 11:11:33 +00:00
await this.GetUserIDFromPasswordResetToken(h, "token");
h.success("The token is valid.");
}
2019-12-30 12:20:24 +00:00
/**
* Reset user password
*
* @param h Request handler
*/
public static async ResetUserPassword(h: RequestHandler) {
const userID = await this.GetUserIDFromPasswordResetToken(h, "token");
const newPassword = h.postString("password", 3);
// Set new password
await AccountHelper.ChangePassword(userID, newPassword);
// Destroy reset token
await AccountHelper.DestroyPasswordResetTokenForUser(userID);
h.success("Password changed!");
}
/**
* Export the data of the user
*
* @param h Request handler
*/
public static async ExportData(h: RequestHandler) {
await h.needUserPostPassword("password");
2020-03-25 17:24:46 +00:00
// Query the database
2020-03-25 17:20:43 +00:00
const data = await AccountHelper.Export(h.getUserId());
2020-03-26 12:44:57 +00:00
const out = {
2020-03-25 17:24:46 +00:00
userID: data.userID,
// General account information
2020-03-25 17:44:51 +00:00
advanced_info: await UserController.UserToAPI(data.userInfo, h, true),
// User posts
2020-03-25 17:55:25 +00:00
posts: await Promise.all(data.postsList.map((p) => PostsController.PostToAPI(h, p))),
// User comments
comments: await CommentsController.CommentsToAPI(h, data.comments),
2020-03-25 18:08:43 +00:00
// User likes
likes: data.likes.map(LikesController.UserLikeToAPI),
// Responses to surveys
2020-03-26 11:13:53 +00:00
survey_responses: data.surveyResponses.map(SurveyController.SurveyResponseToAPI),
// User movies
movies: data.movies.map(MoviesController.MovieToAPI),
2020-03-26 12:05:14 +00:00
2020-03-26 12:26:05 +00:00
// All conversations messages
all_conversation_messages: data.allConversationMessages.map(ConversationsController.ConversationMessageToAPI),
2020-03-26 12:09:15 +00:00
// Conversations list
conversations_list: data.conversations.map(ConversationsController.ConversationToAPI),
2020-03-26 12:26:05 +00:00
// Conversation messages
2020-03-26 12:47:31 +00:00
conversations_messages: {},
2020-03-26 12:29:39 +00:00
// Friends list
2020-03-26 12:44:57 +00:00
friends_list: data.friendsList.map(f => FriendsController.FriendToAPI(f, false)),
2020-03-26 12:59:30 +00:00
// Groups membership
groups: await Promise.all((await Promise.all(data.groups.map(id => GroupsHelper.GetInfo(id))))
.map(info => GroupsController.GroupInfoToAPI(info, h, false))),
2020-03-26 12:44:57 +00:00
// Related users info
users_info: new Map<number, any>(),
2020-03-25 17:20:43 +00:00
};
2020-03-26 12:26:05 +00:00
// Fill conversation messages entry
for(const conv of data.conversations) {
2020-03-26 12:47:31 +00:00
out.conversations_messages[conv.id] =
2020-03-26 12:26:05 +00:00
data.conversationsMessages[conv.id].map(ConversationsController.ConversationMessageToAPI)
}
2020-03-25 17:20:43 +00:00
2020-03-26 12:44:57 +00:00
// Load related users info
for(const id of await data.getRelatedUsersID()) {
out.users_info[id] = await UserController.UserToAPI(await UserHelper.GetUserInfo(id), h, false);
}
2020-03-25 17:20:43 +00:00
h.send(out);
}
/**
* Delete a user account
*
* @param h Request handler
*/
public static async DeleteAccount(h: RequestHandler) {
await h.needUserPostPassword("password");
2020-03-26 16:08:56 +00:00
await AccountHelper.Delete(h.getUserId());
h.error(500, "Method not completely implemented yet.");
}
2019-12-30 11:11:33 +00:00
/**
* Get the user ID associated to a password reset token
*
* @param h Request handler
* @param name The name of the POST field containing the token
*/
private static async GetUserIDFromPasswordResetToken(h: RequestHandler, name: string) : Promise<number> {
const token = h.postString(name, 10);
const userID = await AccountHelper.GetUserIDFromPasswordResetToken(token);
if(userID < 1)
h.error(401, "Invalid password reset token!");
return userID;
}
2019-11-22 07:50:15 +00:00
}