diff --git a/frontend/public/locales/de-DE/translation.json b/frontend/public/locales/de-DE/translation.json
index 9f86746..0df6560 100644
--- a/frontend/public/locales/de-DE/translation.json
+++ b/frontend/public/locales/de-DE/translation.json
@@ -12,7 +12,10 @@
"current_password_error_message": "Darf nicht leer sein.",
"new_password": "Neues Passwort",
"new_password_error_message": "Muss mindestens 8 Zeichen lang sein und jeweils mindestens einen Klein- und Großbuchstaben sowie ein Sonderzeichen enthalten.",
- "close": "Schließen"
+ "close": "Schließen",
+ "delete_user": "Account löschen",
+ "password": "Passwort",
+ "password_invalid": "Passwort ist falsch"
},
"recovery": {
"recovery": "Passwort zurücksetzen",
diff --git a/frontend/public/locales/de/translation.json b/frontend/public/locales/de/translation.json
index 9f86746..0df6560 100644
--- a/frontend/public/locales/de/translation.json
+++ b/frontend/public/locales/de/translation.json
@@ -12,7 +12,10 @@
"current_password_error_message": "Darf nicht leer sein.",
"new_password": "Neues Passwort",
"new_password_error_message": "Muss mindestens 8 Zeichen lang sein und jeweils mindestens einen Klein- und Großbuchstaben sowie ein Sonderzeichen enthalten.",
- "close": "Schließen"
+ "close": "Schließen",
+ "delete_user": "Account löschen",
+ "password": "Passwort",
+ "password_invalid": "Passwort ist falsch"
},
"recovery": {
"recovery": "Passwort zurücksetzen",
diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json
index a7ebe90..e2ae299 100644
--- a/frontend/public/locales/en/translation.json
+++ b/frontend/public/locales/en/translation.json
@@ -12,7 +12,10 @@
"current_password_error_message": "Must not be empty.",
"new_password": "New password",
"new_password_error_message": "Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters",
- "close": "Close"
+ "close": "Close",
+ "delete_user": "Delete account",
+ "password": "Password",
+ "password_invalid": "Password is wrong"
},
"recovery": {
"recovery": "Password recovery",
diff --git a/frontend/src/components/login.tsx b/frontend/src/components/login.tsx
index d25d1a4..26061fb 100644
--- a/frontend/src/components/login.tsx
+++ b/frontend/src/components/login.tsx
@@ -49,6 +49,9 @@ export class Login extends Component<{}, LoginState> {
return;
}
+ const loginSaltBs64 = Base64.fromUint8Array(login_salt);
+ window.localStorage.setItem("LoginKey", loginSaltBs64);
+
const login_key = await generate_hash(this.state.password, login_salt);
const login_schema: LoginSchema = {
diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx
index 1198e2f..983532b 100644
--- a/frontend/src/index.tsx
+++ b/frontend/src/index.tsx
@@ -53,6 +53,10 @@ async function refresh_access_token() {
credentials: "include"
});
+ if (!localStorage.getItem("loginKey") || !localStorage.getItem("secret_key")) {
+ loggedIn.value = AppState.LoggedOut
+ }
+
if (resp.status == 200) {
loggedIn.value = AppState.LoggedIn;
} else {
diff --git a/frontend/src/pages/user.tsx b/frontend/src/pages/user.tsx
index cef2071..6803e85 100644
--- a/frontend/src/pages/user.tsx
+++ b/frontend/src/pages/user.tsx
@@ -30,6 +30,9 @@ import { useTranslation } from "react-i18next";
import { Card, Container } from "react-bootstrap";
import { signal } from "@preact/signals";
import { PasswordComponent } from "../components/password_component";
+import i18n from "../i18n";
+import { showAlert } from "../components/Alert";
+import { Base64 } from "js-base64";
interface UserState {
@@ -116,15 +119,18 @@ class UserComponent extends Component<{}, State> {
}
export function User() {
- const [show, setShow] = useState(false);
+ const [showPasswordReset, setShowPasswordReset] = useState(false);
+ const [deleteUser, setDeleteUser] = useState({show: false, password: "", password_valid: true});
const [currentPassword, setCurrentPassword] = useState("");
const [currentPasswordIsValid, setCurrentPasswordIsValid] = useState(true);
const [newPassword, setNewPassword] = useState("");
const [newPasswordIsValid, setNewPasswordIsValid] = useState(true);
const validated = signal(false);
- const handleClose = () => setShow(false);
- const handleShow = () => setShow(true);
+ const handleUpdatePasswordClose = () => setShowPasswordReset(false);
+ const handleUpdatePasswordShow = () => setShowPasswordReset(true);
+ const handleDelteUserClose = () => setDeleteUser({...deleteUser, show: false});
+ const handleDeleteUserShow = () => setDeleteUser({...deleteUser, show: true});
const checkPasswords = () => {
let ret = true;
@@ -147,7 +153,7 @@ export function User() {
return ret;
}
- const submit = async (e: SubmitEvent) => {
+ const submitUpdatePassword = async (e: SubmitEvent) => {
e.preventDefault();
if (!checkPasswords()) {
@@ -202,24 +208,81 @@ export function User() {
});
if (resp.status === 200) {
logout(true);
- handleClose();
+ handleUpdatePasswordClose();
}
};
+ const submitDeleteUser = async (e: SubmitEvent) => {
+ e.preventDefault();
+
+ const t = i18n.t;
+
+ const loginSaltBs64 = window.localStorage.getItem("LoginKey");
+ const loginSalt = Base64.toUint8Array(loginSaltBs64);
+ const loginKey = await generate_hash(deleteUser.password, loginSalt)
+
+ const resp = await fetch(BACKEND + "/user/delete", {
+ credentials: "include",
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify({login_key: [].slice.call(loginKey)})
+ });
+
+ if (resp.status === 200) {
+ location.reload();
+ } else if (resp.status === 400) {
+ setDeleteUser({...deleteUser, password_valid: false})
+ } else {
+ showAlert(`${t("alert_default_text")}: ${resp.status} ${await resp.text()}`, "danger")
+ handleDelteUserClose();
+ }
+ }
+
const {t} = useTranslation("", {useSuspense: false, keyPrefix: "user"});
return (<>
-
-
-