Made validateUserToken avaible via get requests & updated the system so

that it now has a privacy policy & terms of service (TOS) And added a
add email & display current email logic.
This commit is contained in:
吳元皓 2025-06-03 11:42:30 +08:00
parent 45397675f5
commit aa355e03fd
4 changed files with 103 additions and 16 deletions

View File

@ -2,12 +2,19 @@
import { BadgeCheckIcon, OctagonAlertIcon } from "lucide-vue-next"; import { BadgeCheckIcon, OctagonAlertIcon } from "lucide-vue-next";
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
const { t, locale } = useI18n(); const { t, locale } = useI18n();
const user = ref(); const user = ref("");
const enterFirstName = ref();
const useremail = ref();
const enteruseremail = ref();
onMounted(async () => { onMounted(async () => {
const req = await fetch("/api/user/validateUserToken"); const req = await fetch("/api/user/validateUserToken");
const res = await req.json(); const res = await req.json();
user.value = res; user.value = res.firstName;
useremail.value = res;
}); });
const setFirstName = async () => {
const staticFirstName = "";
};
const logoutAction = () => {}; const logoutAction = () => {};
const groqApiKeyRegex = /^gsk_[a-zA-Z0-9]{52}$/; const groqApiKeyRegex = /^gsk_[a-zA-Z0-9]{52}$/;
@ -68,15 +75,77 @@ const confirmLogout = async () => {
showLogoutDialog.value = false; showLogoutDialog.value = false;
}; };
const deleteAccount = async () => { const deleteAccount = async () => {
const req = await fetch("/api/user/delete", { const req = await fetch("/api/user/action", {
method: "DELETE", method: "DELETE",
}); });
}; };
/**
*
* userAccount: fetchViaSQL[0].username,
requested_action: "CONTINUE",
email: fetchViaSQL[0].email,
avatarURL: fetchViaSQL[0].avatarurl,
firstName: fetchViaSQL[0].firstName,
*/
</script> </script>
<template> <template>
<div class="justify-center align-center text-center"> <div class="justify-center align-center text-center">
<div class="">Greetings, {{ user }}</div> <h1 class="text-3xl text-bold p-2">
<div class="flex flex-row text-center align-center justify-center"> {{ t("settings.greet") }}{{ user || t("settings.defaultname") }}
</h1>
<div class="flex flex-row text-center align-center justify-center p-1">
<span class="text-md p-1 text-nowrap">Change your name:&nbsp;</span>
<Input
type="text"
class="h-6 m-1 py-3 rounded"
v-model="enterFirstName"
placeholder="Ex: Howard ..."
/>
<!--If it is a valid api key or not.-->
<BadgeCheckIcon
v-if="enterFirstName"
class="w-8 h-8 p-1/2 mr-1 text-green-700"
/>
<OctagonAlertIcon
v-if="!enterFirstName"
class="w-8 h-8 p-1/2 mr-1 text-red-700"
/>
<button
class="p-1 text-sm bg-gray-400/60 rounded text-nowrap"
@click="setFirstName"
>
{{ t("settings.submit") }}
</button>
</div>
<div class="flex flex-row text-center align-center justify-center p-1">
<span class="text-md p-1 text-nowrap">Current email:&nbsp;</span>
<span>{{ useremail }}</span>
</div>
<div class="flex flex-row text-center align-center justify-center p-1">
<span class="text-md p-1 text-nowrap">Change your email:&nbsp;</span>
<Input
type="text"
class="h-6 m-1 py-3 rounded"
v-model="enterFirstName"
placeholder="Ex: example@gmail.com"
/>
<!--If it is a valid api key or not.-->
<BadgeCheckIcon
v-if="enterFirstName"
class="w-8 h-8 p-1/2 mr-1 text-green-700"
/>
<OctagonAlertIcon
v-if="!enterFirstName"
class="w-8 h-8 p-1/2 mr-1 text-red-700"
/>
<button
class="p-1 text-sm bg-gray-400/60 rounded text-nowrap"
@click="setFirstName"
>
{{ t("settings.submit") }}
</button>
</div>
<div class="flex flex-row text-center align-center justify-center p-1">
<span class="text-md p-1 text-nowrap" <span class="text-md p-1 text-nowrap"
>{{ t("settings.yourgroqapi") }}:&nbsp;</span >{{ t("settings.yourgroqapi") }}:&nbsp;</span
> >
@ -99,7 +168,7 @@ const deleteAccount = async () => {
class="w-8 h-8 p-1/2 mr-1 text-red-700" class="w-8 h-8 p-1/2 mr-1 text-red-700"
/> />
<button <button
class="p-1 text-sm bg-gray-400/60 rounded" class="p-1 text-sm bg-gray-400/60 rounded text-nowrap"
@click="submitCustomApiKey" @click="submitCustomApiKey"
> >
{{ t("settings.submit") }} {{ t("settings.submit") }}
@ -113,8 +182,8 @@ const deleteAccount = async () => {
<DialogContent class="!border-0 !bg-black !rounded"> <DialogContent class="!border-0 !bg-black !rounded">
<DialogHeader> <DialogHeader>
<DialogTitle>{{ t("settings.logout") }}</DialogTitle> <DialogTitle>{{ t("settings.logout") }}</DialogTitle>
<DialogDescription <DialogDescription>
>Are you sure you want to logout? {{ t("popuptext.logout") }}
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<DialogFooter> <DialogFooter>
@ -130,8 +199,9 @@ const deleteAccount = async () => {
</div> </div>
<div> <div>
<div class="p-2 m-2 w-full rounded">
<h3 class="text-red-600">{{ t("settings.dangerzone") }}</h3> <h3 class="text-red-600">{{ t("settings.dangerzone") }}</h3>
<div class="bg-gray-200/70 p-2 m-2 w-full rounded"> <div class="pt-1 pb-0"></div>
<Dialog v-model:open="showDeleteDialog"> <Dialog v-model:open="showDeleteDialog">
<DialogTrigger asChild> <DialogTrigger asChild>
<Button variant="destructive"> <Button variant="destructive">
@ -142,8 +212,7 @@ const deleteAccount = async () => {
<DialogHeader> <DialogHeader>
<DialogTitle>{{ t("settings.deleteaccount") }}</DialogTitle> <DialogTitle>{{ t("settings.deleteaccount") }}</DialogTitle>
<DialogDescription> <DialogDescription>
This action cannot be undone. This will permanently delete your {{ t("popuptext.delete") }}
account and remove your data from our servers.
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<DialogFooter> <DialogFooter>
@ -159,6 +228,21 @@ const deleteAccount = async () => {
</div> </div>
</div> </div>
<hr /> <hr />
<div
class="flex flex-row gap-2 m-1 p-2 justify-center align-center text-center"
>
<button
class="bg-sky-400 p-1 rounded hover:bg-sky-600 transition-all duration-200 w-32"
>
Privacy Policy
</button>
<button
class="bg-sky-400 p-1 rounded hover:bg-sky-600 transition-all duration-200 w-32"
>
Terms
</button>
</div>
<hr />
<div class="justiy-center align-center text-center"> <div class="justiy-center align-center text-center">
{{ t("app.settings") }} v0.0.2 {{ t("app.settings") }} v0.0.2
</div> </div>

View File

@ -82,7 +82,9 @@
"logout": "Logout", "logout": "Logout",
"deleteaccount": "Delete your account", "deleteaccount": "Delete your account",
"dangerzone": "DANGER ZONE", "dangerzone": "DANGER ZONE",
"submit": "Submit" "submit": "Submit",
"greet": "Greetings, ",
"defaultname": "User"
}, },
"popuptext": { "popuptext": {
"logout": "Are you sure you want to logout?", "logout": "Are you sure you want to logout?",

View File

@ -82,7 +82,9 @@
"logout": "登出", "logout": "登出",
"deleteaccount": "刪除你的帳號", "deleteaccount": "刪除你的帳號",
"dangerzone": "DANGER ZONE", "dangerzone": "DANGER ZONE",
"submit": "送出" "submit": "送出",
"greet": "嗨, ",
"defaultname": "使用者"
}, },
"popup": { "popup": {
"cancel": "取消", "cancel": "取消",

View File

@ -1,12 +1,11 @@
import sql from "~/server/components/postgres"; import sql from "~/server/components/postgres";
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
const body = await readBody(event);
const token = getCookie(event, "token"); const token = getCookie(event, "token");
if (!token) { if (!token) {
return { return {
error: "INVALID_TOKEN", error: "INVALID_TOKEN",
requested_action: "LOGOUT_USER", requested_action: "USE_DEFAULT_STATE",
}; };
} }
const checkIsUUIDRegex = const checkIsUUIDRegex =