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