Site/Django

- Moving forward on the settings
This commit is contained in:
Kum1ta
2024-09-26 01:04:24 +02:00
parent c20110e7c1
commit e375c65c2f
9 changed files with 218 additions and 13 deletions

View File

@ -6,7 +6,7 @@
<input type="text" id="username" placeholder="Username"> <input type="text" id="username" placeholder="Username">
<div class="form-footer"> <div class="form-footer">
<small>Your username allows other players to find you.</small> <small>Your username allows other players to find you.</small>
<button class="save-btn-settings">SAVE</button> <button class="save-btn-settings" id="usernameButtonSave">SAVE</button>
</div> </div>
</div> </div>
@ -24,7 +24,7 @@
<input type="text" id="discord" placeholder="Discord"> <input type="text" id="discord" placeholder="Discord">
<div class="form-footer"> <div class="form-footer">
<small>Share your discord for more fun!</small> <small>Share your discord for more fun!</small>
<button class="save-btn-settings">SAVE</button> <button class="save-btn-settings" id="discordButtonSave">SAVE</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,86 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# changePrivateInfo.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/09/25 23:28:49 by edbernar #+# #+# #
# Updated: 2024/09/26 00:41:16 by edbernar ### ########.fr #
# #
# **************************************************************************** #
from asgiref.sync import sync_to_async
from ..models import User
import hashlib
import json
import re
mail_pattern = "^((?!\\.)[\\w\\-_.]*[^.])(@\\w+)(\\.\\w+(\\.\\w+)?[^.\\W])$"
password_pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"
discord_pattern = "^[a-zA-Z0-9_.]{0,32}$"
@sync_to_async
def changePrivateInfo(socket, content):
try:
data = []
if (content.get("username")):
data.append("username")
if (content.get("password")):
data.append("password")
if (content.get("discord")):
data.append("discord")
if (len(data) != 1):
socket.sendError("You must provide exactly one field to update", 9028)
return
if (content.get("username")):
if (content["username"].find(' ') != -1):
socket.sendError("Username must not contain spaces", 9015)
return
if (len(content["username"]) < 3):
socket.sendError("Username must be at least 3 characters long", 9016)
return
if (len(content["username"]) > 20):
socket.sendError("Username must be at most 20 characters long", 9017)
return
if (not all(c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" for c in content["username"])):
socket.sendError("Username must contain only letters and numbers", 9018)
return
if (User.objects.filter(username=content["username"]).exists()):
socket.sendError("Username already used", 9023)
return
if (content.get("password")):
if (len(content["password"]) < 8):
socket.sendError("Password must be at least 8 characters long", 9019)
return
if (content["password"].find(content["username"]) != -1):
socket.sendError("Password must not contain the username", 9021)
return
if (not bool(re.match(password_pattern, content["password"]))):
socket.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9020)
return
if (content.get("discord")):
if (len(content["discord"]) > 32):
socket.sendError("Discord must be at most 32 characters long", 9024)
return
if (not bool(re.match(discord_pattern, content["discord"]))):
socket.sendError("Discord must contain only letters, numbers and underscores or points", 9025)
return
user = User.objects.get(id=socket.id)
if (content.get("username")):
user.username = content["username"]
socket.username = content["username"]
socket.scope["session"]['username'] = content["username"]
if (content.get("password")):
user.password = hashlib.sha256(user['mail' + content["password"]].encode()).hexdigest()
if (content.get("discord")):
if (content["discord"] != ""):
user.discord_username = content["discord"]
else:
user.discord_username = None
user.save()
socket.scope["session"].save()
socket.sync_send(json.dumps({"type": "change_private_info", "content": "Successfully updated."}))
except Exception as e:
socket.sendError("An unknown error occured", 9027, e)

View File

@ -0,0 +1,28 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# getPrivateInfo.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/09/25 22:51:55 by edbernar #+# #+# #
# Updated: 2024/09/25 23:04:18 by edbernar ### ########.fr #
# #
# **************************************************************************** #
from asgiref.sync import sync_to_async
from ..models import User
import json
@sync_to_async
def getPrivateInfo(socket, content):
response = {}
user = User.objects.filter(id=socket.id).values().first()
if (user.get('id42') == None):
response["is42Account"] = False
else:
response["is42Account"] = True
response["username"] = user.get('username')
response["mail"] = user.get('mail')
response["discord_username"] = user.get('discord_username')
socket.sync_send({"type":"private_info", "content": response})

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ # # By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2024/09/09 14:31:30 by tomoron #+# #+# # # Created: 2024/09/09 14:31:30 by tomoron #+# #+# #
# Updated: 2024/09/24 17:25:54 by edbernar ### ########.fr # # Updated: 2024/09/26 00:17:17 by edbernar ### ########.fr #
# # # #
# **************************************************************************** # # **************************************************************************** #
@ -29,15 +29,19 @@ from .typeRequests.getAllListUser import getAllListUser
from .typeRequests.changeBanner import changeBanner from .typeRequests.changeBanner import changeBanner
from .typeRequests.gameRequest import gameRequest from .typeRequests.gameRequest import gameRequest
from .typeRequests.getUserInfo import getUserInfo from .typeRequests.getUserInfo import getUserInfo
from .typeRequests.getPrivateInfo import getPrivateInfo
from .typeRequests.changePrivateInfo import changePrivateInfo
from .typeRequests.changePfp import changePfp from .typeRequests.changePfp import changePfp
typeRequest = ["login", "get_private_list_user", "get_private_list_message", typeRequest = ["login", "get_private_list_user", "get_private_list_message",
"send_private_message", "create_account", "get_all_list_user", "game", "send_private_message", "create_account", "get_all_list_user", "game",
"search_user", "get_user_info", "change_pfp", "change_banner" "search_user", "get_user_info", "change_pfp", "change_banner",
"get_private_info", "change_private_info"
] ]
functionRequest = [login, getPrivateListUser, getPrivateListMessage, functionRequest = [login, getPrivateListUser, getPrivateListMessage,
sendPrivateMessage, createAccount, getAllListUser, gameRequest, sendPrivateMessage, createAccount, getAllListUser, gameRequest,
searchUser, getUserInfo, changePfp, changeBanner searchUser, getUserInfo, changePfp, changeBanner,
getPrivateInfo, changePrivateInfo
] ]
from random import randint from random import randint

View File

@ -3,10 +3,10 @@
/* ::: :::::::: */ /* ::: :::::::: */
/* Map.js :+: :+: :+: */ /* Map.js :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: hubourge <hubourge@student.42.fr> +#+ +:+ +#+ */ /* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/20 14:52:55 by hubourge #+# #+# */ /* Created: 2024/08/20 14:52:55 by hubourge #+# #+# */
/* Updated: 2024/09/25 18:28:18 by hubourge ### ########.fr */ /* Updated: 2024/09/25 22:19:13 by edbernar ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -998,7 +998,7 @@ class Map
this.updateScore(name, this.score); this.updateScore(name, this.score);
player.reserCameraPlayer(); player.reserCameraPlayer();
ball.resetScaleBall(); ball.resetPosBall();
// player.resetPosPlayer(); // player.resetPosPlayer();
// opponent.resetPosOpponent(); // opponent.resetPosOpponent();
}; };

View File

@ -6,14 +6,57 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */ /* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/25 17:00:35 by edbernar #+# #+# */ /* Created: 2024/09/25 17:00:35 by edbernar #+# #+# */
/* Updated: 2024/09/25 17:01:06 by edbernar ### ########.fr */ /* Updated: 2024/09/26 01:02:31 by edbernar ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
import { waitForPrivateInfo } from "/static/javascript/typeResponse/typePrivateInfo.js"
import { sendRequest, status } from "/static/javascript/websocket.js";
class settingsPage class settingsPage
{ {
static create() static create()
{ {
const emailInput = document.getElementById('email');
const discordInput = document.getElementById('discord');
const usernameInput = document.getElementById('username');
const passwordInput = document.getElementById('password');
const newPasswordInput = document.getElementById('new-password');
const confirmOasswordInput = document.getElementById('confirm-password');
const usernameSaveButton = document.getElementById('usernameButtonSave');
const discordSaveButton = document.getElementById('discordButtonSave');
let interval = null;
emailInput.disabled = true;
emailInput.style.backgroundColor = "#bbbbbb";
interval = setInterval(() => {
if (status)
{
sendRequest("get_private_info", {});
clearInterval(interval);
}
}, 200);
waitForPrivateInfo().then(data => {
console.log(data);
emailInput.value = data.mail ? data.mail : "Disabled because you have a 42 account."
passwordInput.value = newPasswordInput.value = confirmOasswordInput.value = data.is42Account ? "Disabled because you have a 42 account." : null;
if (data.is42Account)
{
passwordInput.style.backgroundColor = newPasswordInput.style.backgroundColor = confirmOasswordInput.style.backgroundColor = "#bbbbbb";
passwordInput.type = newPasswordInput.type = confirmOasswordInput.type = 'text';
}
discordInput.value = data.discord_username;
usernameInput.value = data.username;
usernameSaveButton.addEventListener('click', () => {
sendRequest("change_private_info", {username: usernameInput.value});
});
discordSaveButton.addEventListener('click', () => {
sendRequest("change_private_info", {discord: discordInput.value});
});
});
} }

View File

@ -0,0 +1,42 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* typePrivateInfo.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/25 22:34:46 by edbernar #+# #+# */
/* Updated: 2024/09/25 23:07:41 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
let PrivateInfo = {};
let PrivateInfoAvailable = false;
let PrivateInfoResolve = null;
function waitForPrivateInfo()
{
return new Promise((resolve) => {
if (PrivateInfoAvailable)
{
PrivateInfoAvailable = false;
resolve(PrivateInfo);
}
else
PrivateInfoResolve = resolve;
});
}
function typePrivateInfo(data)
{
PrivateInfo = data;
PrivateInfoAvailable = true;
if (PrivateInfoResolve)
{
PrivateInfoResolve(PrivateInfo);
PrivateInfoResolve = null;
PrivateInfoAvailable = false;
}
}
export { typePrivateInfo, waitForPrivateInfo };

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */ /* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/31 22:17:24 by edbernar #+# #+# */ /* Created: 2024/07/31 22:17:24 by edbernar #+# #+# */
/* Updated: 2024/09/24 15:55:37 by edbernar ### ########.fr */ /* Updated: 2024/09/26 00:59:46 by edbernar ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -19,6 +19,7 @@ import { typeNewPrivateMessage } from "/static/javascript/typeResponse/typeNewPr
import { typePrivateListUser } from "/static/javascript/typeResponse/typePrivateListUser.js"; import { typePrivateListUser } from "/static/javascript/typeResponse/typePrivateListUser.js";
import { typeCreateAccount } from "/static/javascript/typeResponse/typeCreateAccount.js"; import { typeCreateAccount } from "/static/javascript/typeResponse/typeCreateAccount.js";
import { typeAllListUser }from "/static/javascript/typeResponse/typeAllListUser.js"; import { typeAllListUser }from "/static/javascript/typeResponse/typeAllListUser.js";
import { typePrivateInfo } from "/static/javascript/typeResponse/typePrivateInfo.js"
import { createNotification as CN } from "/static/javascript/notification/main.js"; import { createNotification as CN } from "/static/javascript/notification/main.js";
import { typeSearchUser } from "/static/javascript/typeResponse/typeSearchUser.js"; import { typeSearchUser } from "/static/javascript/typeResponse/typeSearchUser.js";
import { typeChangePfp } from "/static/javascript/typeResponse/typeChangePfp.js"; import { typeChangePfp } from "/static/javascript/typeResponse/typeChangePfp.js";
@ -36,8 +37,8 @@ function launchSocket()
socket = new WebSocket('/ws'); socket = new WebSocket('/ws');
const typeResponse = ["logged_in", "login", "private_list_user", "private_list_message", "new_private_message", "all_list_user", "create_account", "game", "search_user", "user_info", "change_pfp"]; const typeResponse = ["logged_in", "login", "private_list_user", "private_list_message", "new_private_message", "all_list_user", "create_account", "game", "search_user", "user_info", "change_pfp", "private_info"];
const functionResponse = [typeLogin, typeLogin, typePrivateListUser, typePrivateListMessage, typeNewPrivateMessage, typeAllListUser, typeCreateAccount, typeGame, typeSearchUser, typeUserInfo, typeChangePfp]; const functionResponse = [typeLogin, typeLogin, typePrivateListUser, typePrivateListMessage, typeNewPrivateMessage, typeAllListUser, typeCreateAccount, typeGame, typeSearchUser, typeUserInfo, typeChangePfp, typePrivateInfo];
const errorCode = [9007, 9010, 9011, 9013]; const errorCode = [9007, 9010, 9011, 9013];
const errorFunction = [typeErrorInvalidPassword, typeErrorInvalidToken42, typeErrorUnknown42Account, typeErrorConnectedElsewhere]; const errorFunction = [typeErrorInvalidPassword, typeErrorInvalidToken42, typeErrorUnknown42Account, typeErrorConnectedElsewhere];
@ -116,4 +117,4 @@ function sendRequest(type, content) {
})); }));
} }
export { socket, sendRequest, launchSocket }; export { socket, sendRequest, launchSocket, status };

View File

@ -29,6 +29,7 @@
- 9025 : Account not verified, please verify your account before logging in - 9025 : Account not verified, please verify your account before logging in
- 9026 : An error occured while sending the email, glhf - 9026 : An error occured while sending the email, glhf
- 9027 : An unknown error occured - 9027 : An unknown error occured
- 9028 : You must provide exactly one field to update"
- 9100 : Action out of range - 9100 : Action out of range
- 9101 : No game started - 9101 : No game started