diff --git a/src/lib/lang/en/game.json b/src/lib/lang/en/game.json
index 3fc534f..403f5fb 100644
--- a/src/lib/lang/en/game.json
+++ b/src/lib/lang/en/game.json
@@ -2,8 +2,21 @@
"Header": {
"user": "user {}"
},
+ "Label": {
+ "userCreationDate": "Account created at {}",
+ "newUsernamePlaceholder": "new username",
+ "newEmailPlaceholder": "new email",
+ "newPasswordPlaceholder": "new password",
+ "newPasswordVerifyPlaceholder": "verify",
+ "passwordPlaceholder": "password",
+ "oldPasswordPlaceholder": "old password"
+ },
"Link": {
- "logout": "Log out",
- "build": "[build]"
+ "build": "[build]",
+
+ "changeUsername": "Change username",
+ "changeEmail": "Change email",
+ "changePassword": "Change password",
+ "logout": "[log out]"
}
}
\ No newline at end of file
diff --git a/src/pages/api/auth/changeUserData/[...path].astro b/src/pages/api/auth/changeUserData/[...path].astro
new file mode 100644
index 0000000..c1fa1e6
--- /dev/null
+++ b/src/pages/api/auth/changeUserData/[...path].astro
@@ -0,0 +1,116 @@
+---
+import type { ObjectId } from "mongodb";
+import { Users } from "../../../../lib/db/mongodb";
+import { getUserById, getUserByNickOrEmail } from "../../../../lib/db/users";
+import validateAccessToken from "../../../../lib/utils/validateAccessToken";
+import { hash, compare } from "bcrypt";
+
+if(Astro.request.method === "PATCH") {
+ const response = await validateAccessToken(Astro.request);
+ if(response instanceof Response) return response;
+
+ const { path } = Astro.params;
+
+ const body = await Astro.request.json();
+
+ if(!body || !body['password']) return new Response(
+ JSON.stringify({
+ code: 400,
+ message: "Bad Request"
+ }), { status: 400 }
+ );
+
+ const user = await getUserById(response.user as ObjectId);
+ if(!user) return new Response(
+ JSON.stringify({
+ code: 404,
+ message: "Not Found"
+ }), { status: 404 }
+ );
+
+ if(!(await compare(body['password'], user.password))) return new Response(
+ JSON.stringify({
+ code: 401,
+ message: "Unauthorized"
+ }), { status: 401 }
+ );
+
+ switch(path) {
+ case 'username':
+ if(!body['newUsername']) return new Response(
+ JSON.stringify({
+ code: 400,
+ message: "Bad Request"
+ }), { status: 400 }
+ );
+
+ if(await getUserByNickOrEmail(body['newUsername'])) return new Response(
+ JSON.stringify({
+ code: 409,
+ message: "Conflict"
+ }), { status: 409 }
+ );
+
+ (await Users()).updateOne({ _id: user._id }, { $set: { username: body['newUsername'] } })
+ return new Response(
+ JSON.stringify({
+ code: 200,
+ message: "OK"
+ })
+ );
+ case 'email':
+ if(!body['newEmail']) return new Response(
+ JSON.stringify({
+ code: 400,
+ message: "Bad Request"
+ }), { status: 400 }
+ );
+
+ if(await getUserByNickOrEmail(body['newEmail'])) return new Response(
+ JSON.stringify({
+ code: 409,
+ message: "Conflict"
+ }), { status: 409 }
+ );
+
+ (await Users()).updateOne({ _id: user._id }, { $set: { email: body['newEmail'] } })
+ return new Response(
+ JSON.stringify({
+ code: 200,
+ message: "OK"
+ })
+ );
+ case 'password':
+ if(!body['newPassword']) return new Response(
+ JSON.stringify({
+ code: 400,
+ message: "Bad Request"
+ }), { status: 400 }
+ );
+
+ const newPassword = await hash(body['newPassword'], 10);
+
+ (await Users()).updateOne({ _id: user._id }, { $set: { password: newPassword } })
+ return new Response(
+ JSON.stringify({
+ code: 200,
+ message: "OK"
+ })
+ );
+ default:
+ return new Response(
+ JSON.stringify({
+ code: 400,
+ message: "Bad Request"
+ }), { status: 400 }
+ );
+ }
+} else {
+ return new Response(
+ JSON.stringify({
+ code: 405,
+ message: "Method Not Allowed"
+ }), { status: 405 }
+ );
+}
+---
\ No newline at end of file
diff --git a/src/pages/game/profile.astro b/src/pages/game/profile.astro
new file mode 100644
index 0000000..8eebe32
--- /dev/null
+++ b/src/pages/game/profile.astro
@@ -0,0 +1,230 @@
+---
+import Layout from '../../layouts/Layout.astro';
+import NavBar from '../../components/NavBar.astro';
+import { getUserByNickOrEmail, getUserResources, updateUserResources } from '../../lib/db/users';
+import { getHighestWeightedLanguage, getLocales } from '../../lib/lang/langDriver';
+import ResourceBar from '../../components/ResourceBar.astro';
+import format from '../../lib/utils/format';
+
+const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
+const username = Astro.cookies.get('username')?.value ?? "";
+
+if(loggedToken === null || username === "") return Astro.redirect('/');
+
+const locale = getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));
+
+const user = await getUserByNickOrEmail(username);
+
+const langGame = await getLocales(locale, 'game');
+---
+
+
+
+
+
+
+
{format(langGame['Label_userCreationDate'], user?.createdAt.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ").toString() ?? "")}
+
{langGame['Link_logout']}
+
+
+
+
+
+
+
+
\ No newline at end of file