import { jwtDecode, JwtPayload } from "jwt-decode"; import { ReactNode, useEffect, useState } from "react"; import { apiAuth, baseUrl, User } from "./api"; import { useNavigate } from "react-router"; import { Eye, EyeSlash } from "./Icons"; import { useSession } from "./Session"; import { relative } from "path"; import Header from "./Header"; interface PassToken extends JwtPayload { username: string; name: string; team_id: number; } enum Mode { register = "register", set = "set password", change = "change password", } export const SetPassword = () => { const [mode, setMode] = useState(); const [name, setName] = useState("after getting your token."); const [username, setUsername] = useState(""); const [teamID, setTeamID] = useState(); const [currentPassword, setCurrentPassword] = useState(""); const [password, setPassword] = useState(""); const [passwordr, setPasswordr] = useState(""); const [token, setToken] = useState(""); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const [visible, setVisible] = useState(false); const newPlayerTemplate = { username: "", display_name: "", number: "", email: "", } as User; const [player, setPlayer] = useState(newPlayerTemplate); const navigate = useNavigate(); const { user } = useSession(); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (password === passwordr) { setLoading(true); if (mode === Mode.change) { //====CHANGING PASSWORD==== const resp = await apiAuth( "player/change_password", { current_password: currentPassword, new_password: password }, "POST" ); setLoading(false); if (resp.detail) setError(resp.detail); else { setError(resp); setTimeout(() => navigate("/"), 2000); } } else if (mode === Mode.set) { //====SETTING PASSWORD==== const req = new Request(`${baseUrl}api/set_password`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ token: token, password: password }), }); let resp: Response; try { resp = await fetch(req); } catch (e) { throw new Error(`request failed: ${e}`); } setLoading(false); if (resp.ok) { console.log(resp); navigate("/", { replace: true, state: { username: username, password: password }, }); } if (!resp.ok) { if (resp.status === 401) { const { detail } = await resp.json(); if (detail) setError(detail); else setError("unauthorized"); throw new Error("Unauthorized"); } } } else if (mode === Mode.register) { //====REGISTER NEW USER==== const req = new Request(`${baseUrl}api/register`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ...player, team_id: teamID, token: token, password: password, }), }); let resp: Response; try { resp = await fetch(req); } catch (e) { throw new Error(`request failed: ${e}`); } setLoading(false); if (resp.ok) { console.log(resp); navigate("/", { replace: true, state: { username: player.username, password: password }, }); } if (!resp.ok) { const { detail } = await resp.json(); if (detail) setError(detail); else setError("unauthorized"); throw new Error("Unauthorized"); } } } else setError("passwords are not the same"); } useEffect(() => { if (user) { setUsername(user.username); setName(user.display_name); setMode(Mode.change); } else { const params = new URLSearchParams(window.location.search); const token = params.get("token"); if (token) { setToken(token); try { const payload = jwtDecode(token); console.log(payload); switch (payload.sub) { case "register": setMode(Mode.register); if (payload.team_id) setTeamID(payload.team_id); break; case "set password": setMode(Mode.set); if (payload.username) setUsername(payload.username); break; } if (payload.name) setName(payload.name); } catch (InvalidTokenError) { setName("Mr. I-have-no-valid Token"); } } } }, []); let header: ReactNode; switch (mode) { case Mode.change: header =

change your password, {name}

; break; case Mode.set: header = ( <>

set your password, {name}

); break; case Mode.register: header = ( <>

register as a member of {name}

); } let textInputs: ReactNode; switch (mode) { case Mode.change: textInputs = (
{ setError(""); setCurrentPassword(evt.target.value); }} />
); break; case Mode.register: textInputs = (
{ setPlayer({ ...player, display_name: e.target.value, username: e.target.value.toLowerCase().replace(/\W/g, ""), }); }} />
{ setPlayer({ ...player, username: e.target.value }); }} />
{ setPlayer({ ...player, number: e.target.value }); }} />
{ setPlayer({ ...player, email: e.target.value }); }} />

); break; } let passwordInputs = ( <>
{ setError(""); setPassword(evt.target.value); }} />
{ setError(""); setPasswordr(evt.target.value); }} />
); return mode ? ( <> {header}
{textInputs} {passwordInputs}
setVisible(!visible)} > {visible ? : } show passwords
{error && {error}}
{loading && } ) : ( ); };