Added necessary changes to client-side code for HTTPS transport

This commit is contained in:
Zhongheng Liu 2024-02-18 16:36:52 +02:00
commit e205d6e149
No known key found for this signature in database
5 changed files with 17885 additions and 17862 deletions

35443
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@
"@types/node": "^16.18.68", "@types/node": "^16.18.68",
"@types/react": "^18.2.45", "@types/react": "^18.2.45",
"@types/react-dom": "^18.2.18", "@types/react-dom": "^18.2.18",
"ed25519": "^0.0.5",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
@ -41,5 +42,8 @@
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
},
"devDependencies": {
"@types/ed25519": "^0.0.3"
} }
} }

View file

@ -52,7 +52,7 @@ const Wrapper = (): React.ReactElement => {
}; };
const setNameOnServer = async (name: string) => { const setNameOnServer = async (name: string) => {
const responseRaw = await fetch( const responseRaw = await fetch(
`http://${domain}:${port}${endpoints.user}`, `https://${domain}:${port}${endpoints.user}`,
{ {
method: "POST", method: "POST",
mode: "cors", mode: "cors",

View file

@ -4,168 +4,146 @@ import { LangContext, LoginType } from "../context";
import { User } from "../type/userTypes"; import { User } from "../type/userTypes";
import "./Login.css"; import "./Login.css";
import strings from "../Intl/strings.json"; import strings from "../Intl/strings.json";
import { ECDH } from "crypto";
const encrypt = (rawPasswordString: string) => { const encrypt = (rawPasswordString: string) => {
// TODO Encryption method stub // TODO Encryption method stub
return rawPasswordString; return rawPasswordString;
}; };
export const Login = ({ export const Login = ({
setLogin, setLogin,
}: { }: {
setLogin: (newLogin: LoginType | undefined) => void; setLogin: (newLogin: LoginType | undefined) => void;
}): React.ReactElement => { }): React.ReactElement => {
const [valid, setValid] = useState<boolean | undefined>(undefined); const [valid, setValid] = useState<boolean | undefined>(undefined);
const [validText, setValidText] = useState<string | undefined>(); const [validText, setValidText] = useState<string | undefined>();
const lang = useContext(LangContext); const lang = useContext(LangContext);
const loginPage = strings[lang].login; const loginPage = strings[lang].login;
const registrationHandler = () => { const registrationHandler = () => {
const uname = ( const uname = (document.getElementById("username") as HTMLInputElement)
document.getElementById("username") as HTMLInputElement .value;
).value; const passwd = encrypt(
const passwd = encrypt( (document.getElementById("passwd") as HTMLInputElement).value
(document.getElementById("passwd") as HTMLInputElement) );
.value fetch(`https://${domain}:${port}${endpoints.user}`, {
); method: "POST",
fetch(`http://${domain}:${port}${endpoints.user}`, { mode: "cors",
method: "POST", headers: contentTypes.json,
mode: "cors", body: JSON.stringify({
headers: contentTypes.json, userName: uname,
body: JSON.stringify({ dateJoined: Date.now(),
userName: uname, passwordHash: passwd,
dateJoined: Date.now(), }),
passwordHash: passwd, }).then((response) => {
}), if (response.status === 400) {
}).then((response) => { // 400 Bad request
if (response.status === 400) { console.log("Username is taken or invalid!");
// 400 Bad request setValid(false);
console.log("Username is taken or invalid!"); setValidText(loginPage.error.unameTakenOrInvalid);
setValid(false); } else if (response.status === 200) {
setValidText( // 200 OK
loginPage.error.unameTakenOrInvalid const futureDate = new Date();
); futureDate.setHours(futureDate.getHours() + 2);
} else if (response.status === 200) { setLogin({
// 200 OK username: uname,
const futureDate = new Date(); lastSeen: Date.now(),
futureDate.setHours(futureDate.getHours() + 2); validUntil: futureDate.getUTCMilliseconds(),
setLogin({ });
username: uname, document.title = `IRC User ${uname}`;
lastSeen: Date.now(), }
validUntil: futureDate.getUTCMilliseconds(), });
}); };
document.title = `IRC User ${uname}`; // login button press handler
} const loginHandler = () => {
}); const uname = (document.getElementById("username") as HTMLInputElement)
}; .value;
// login button press handler const passwd = encrypt(
const loginHandler = () => { (document.getElementById("passwd") as HTMLInputElement).value
const uname = ( );
document.getElementById("username") as HTMLInputElement // async invocation of Fetch API
).value; fetch(`https://${domain}:${port}${endpoints.user}?name=${uname}`, {
const passwd = encrypt( method: "GET",
(document.getElementById("passwd") as HTMLInputElement) mode: "cors",
.value })
); .then((res) => {
// async invocation of Fetch API if (res.status === 404) {
fetch( console.log("404 not found encountered");
`http://${domain}:${port}${endpoints.user}?name=${uname}`, throw new Error(loginPage.error.unameNotExists);
{ } else if (res.status === 200) {
method: "GET", console.log("200 OK");
mode: "cors", }
} return res.json();
) })
.then((res) => { .then((userObject) => {
if (res.status === 404) { if (!userObject) {
console.log( return;
"404 not found encountered" }
); const user = userObject as User;
throw new Error( const validLogin = passwd === user.passwordHash;
loginPage.error.unameNotExists if (!validLogin) {
); // login invalid
} else if (res.status === 200) { throw new Error(loginPage.error.passwdInvalid);
console.log("200 OK"); } else {
} // login valid
return res.json(); setValid(true);
}) const validUntilDate: Date = new Date();
.then((userObject) => { validUntilDate.setHours(validUntilDate.getHours() + 2);
if (!userObject) { setLogin({
return; username: user.userName,
} lastSeen: user.lastSeen,
const user = userObject as User; validUntil: validUntilDate.getUTCMilliseconds(),
const validLogin = passwd === user.passwordHash; });
if (!validLogin) { document.title = `IRC User ${uname}`;
// login invalid }
throw new Error( })
loginPage.error.passwdInvalid .catch((reason: Error) => {
); setValid(false);
} else { setValidText(reason.message);
// login valid });
setValid(true); };
const validUntilDate: Date = new Date(); return (
validUntilDate.setHours( <div className="login">
validUntilDate.getHours() + 2 <fieldset>
); <legend>{loginPage.window.title}</legend>
setLogin({ <p className="uname-error-text">
username: user.userName, {!valid && valid !== undefined ? validText : ""}
lastSeen: user.lastSeen, </p>
validUntil: validUntilDate.getUTCMilliseconds(), <label htmlFor="username">{loginPage.window.uname}</label>
}); <br />
document.title = `IRC User ${uname}`; <input id="username" type="text"></input>
} <br />
}) <label htmlFor="passwd">{loginPage.window.passwd}</label>
.catch((reason: Error) => { <br />
setValid(false); <input id="passwd" type="password"></input>
setValidText(reason.message); <br />
}); <button
}; disabled={valid}
return ( type="submit"
<div className="login"> onClick={() => {
<fieldset> loginHandler();
<legend>{loginPage.window.title}</legend> }}
<p className="uname-error-text"> >
{!valid && valid !== undefined {loginPage.window.login}
? validText </button>
: ""} <button
</p> disabled={valid}
<label htmlFor="username"> type="submit"
{loginPage.window.uname} onClick={() => {
</label> registrationHandler();
<br /> }}
<input id="username" type="text"></input> >
<br /> {loginPage.window.register}
<label htmlFor="passwd"> </button>
{loginPage.window.passwd} <button
</label> disabled={!valid}
<br /> type="submit"
<input id="passwd" type="password"></input> onClick={() => {
<br /> setLogin(undefined);
<button setValid(undefined);
disabled={valid} }}
type="submit" >
onClick={() => { {loginPage.window.logout}
loginHandler(); </button>
}} </fieldset>
> </div>
{loginPage.window.login} );
</button>
<button
disabled={valid}
type="submit"
onClick={() => {
registrationHandler();
}}
>
{loginPage.window.register}
</button>
<button
disabled={!valid}
type="submit"
onClick={() => {
setLogin(undefined);
setValid(undefined);
}}
>
{loginPage.window.logout}
</button>
</fieldset>
</div>
);
}; };

View file

@ -1,6 +1,6 @@
export const domain = window.location.hostname; export const domain = window.location.hostname;
export const port = "8080"; export const port = "8080";
export const connectionAddress = `ws://${domain}:${port}/ws`; export const connectionAddress = `wss://${domain}:${port}/ws`;
export const endpoints = { export const endpoints = {
destination: "/app/chat", destination: "/app/chat",
subscription: "/sub/chat", subscription: "/sub/chat",