<!DOCTYPE html>
<html>
	<head>
		<script src="./assets/js/jsencrypt.js"></script>
		<script src="./assets/js/crypto-js.js"></script>
		<script src="./assets/js/login.js" class="js-file"></script>
		<meta http-equiv=”Cache-Control” content=”no-cache”/>
		<meta http-equiv=”Cache-Control” content=”no-store”/>
		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
		<link rel="apple-touch-icon" sizes="57x57" href="./assets/img/favicon/apple-icon-57x57.png">
		<link rel="apple-touch-icon" sizes="60x60" href="./assets/img/favicon/apple-icon-60x60.png">
		<link rel="apple-touch-icon" sizes="72x72" href="./assets/img/favicon/apple-icon-72x72.png">
		<link rel="apple-touch-icon" sizes="76x76" href="./assets/img/favicon/apple-icon-76x76.png">
		<link rel="apple-touch-icon" sizes="114x114" href="./assets/img/favicon/apple-icon-114x114.png">
		<link rel="apple-touch-icon" sizes="120x120" href="./assets/img/favicon/apple-icon-120x120.png">
		<link rel="apple-touch-icon" sizes="144x144" href="./assets/img/favicon/apple-icon-144x144.png">
		<link rel="apple-touch-icon" sizes="152x152" href="./assets/img/favicon/apple-icon-152x152.png">
		<link rel="apple-touch-icon" sizes="180x180" href="./assets/img/favicon/apple-icon-180x180.png">
		<link rel="icon" type="image/png" sizes="192x192"  href="./assets/img/favicon/android-icon-192x192.png">
		<link rel="icon" type="image/png" sizes="32x32" href="./assets/img/favicon/favicon-32x32.png">
		<link rel="icon" type="image/png" sizes="96x96" href="./assets/img/favicon/favicon-96x96.png">
		<link rel="icon" type="image/png" sizes="16x16" href="./assets/img/favicon/favicon-16x16.png">
		<meta name="msapplication-TileColor" content="#141414">
		<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
		<meta name="theme-color" content="#141414">
		<link rel="stylesheet" href="./assets/css/login-dark.css" class="theme-css" data-color="dark">
		<title>X:/Chat</title>
	</head>
	<body>
		<svg class="info-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><path d="M20 424.229h20V279.771H20c-11.046 0-20-8.954-20-20V212c0-11.046 8.954-20 20-20h112c11.046 0 20 8.954 20 20v212.229h20c11.046 0 20 8.954 20 20V492c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20v-47.771c0-11.046 8.954-20 20-20zM96 0C56.235 0 24 32.235 24 72s32.235 72 72 72 72-32.235 72-72S135.764 0 96 0z"/></svg>
		<div class="info-wrapper">
			<svg class="close-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352 512"><path d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"/></svg>
			<a href="https://www.github.com/Xtrendence/X-Chat" target="_blank"><svg class="github-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg></a>
			<div class="info-text-wrapper">
				<span>X:/Chat is a web application that uses HTML, CSS, and JavaScript on the front-end, and Node.js on the back-end. It allows users to communicate with one another in a secure manner (although I'm new to Node.js, and cannot guarantee said security).</span>
				<span>JavaScript and local storage are absolutely <b>mandatory</b> for the web app to function. Local storage is used to store public keys, private keys, settings, and a whole lot more.</span>
				<span>If you use the "Anonymous Chat" feature, absolutely nothing is stored on the server. I wanted to make the most secure form of communication I could think of, and I ended up choosing not to even store conversations through the anonymous chat. When you click on the "anonymous chat" button, you get redirected to "/anonymous", where an ID is generated for you, along with a public key and a private key. These are solely saved on your browser (in the local storage). The server does not store any of this information. The only thing the server stores is the conversation ID, and the creation time. This is done so that conversations can be set to expire after an hour. After the loading is complete, you can send your URL to anyone you want, and have them connect to you. Once they do, they also get a public/private key pair generated for them, as well as an ID. You are then provided with their public key and their ID. When you send a message, you encrypt it using their RSA-2048 public key, which they then decrypt on their side (locally) using their private key. Since the message is encrypted on the client side, the server never knows what is being said. Refreshing the page deletes the messages for whoever refreshed, as the messages aren't stored <b>anywhere</b>. Because of the fact that nothing is stored on the server though, it means users can easily change their IDs and such, which is why this project was made to be used by small groups, rather than the general public. Having the server store anonymous conversations would provide the benefit of the conversations being immutable by users, but it would mean that the server can modify them, and that logs would exist. So would you rather trust your friend, or some random server?</span>
				<span>The normal chat is more like your generic chat application. Messages are still encrypted on the client side with RSA-2048, and users' private keys are encrypted with AES-256-CTR, which uses the SHA512 hash of the user's password as decryption key. The user's password is stored using BCrypt with 10 salt rounds. In short, unless the server code is modified or something to capture the user's private key, there's absolutely no way to get the content of a conversation. The user's settings, contacts, and other data are stored in JSON format in text files for easy access. These are stored in plaintext, but it'd be easy to encrypt them with the user's password and AES.</span>
				<span>There might be some bugs or some unexpected behavior, but this is to be expected, this is my first Node.js project. If you try to break the app, you'll very likely succeed. There aren't as many validation checks and such as I'd like, but there are enough to protect user's accounts and conversations. I apologize in advance if anything does go wrong though.</span>
			</div>
		</div>
		<span class="login-text noselect"></span>
		<div class="login-border"></div>
		<button class="login-anonymous">Anonymous Chat</button>
		<div class="login-wrapper" style="display:block;">
			<input type="text" class="login-input username" placeholder="Username..." name="username">
			<input type="password" class="login-input password" placeholder="Password..." name="password">
			<button class="register-switch">Register</button>
			<button class="login-button">Login</button>
		</div>
		<div class="register-border"></div>
		<div class="register-wrapper">
			<input type="text" class="register-input username" placeholder="Username..." name="username">
			<input type="password" class="register-input password" placeholder="Password..." name="password">
			<input type="password" class="register-input repeat-password" placeholder="Repeat Password..." name="repeat-password">
			<button class="login-switch">Login</button>
			<button class="register-button">Register</button>
		</div>
		<noscript>
			<div class="error-overlay noselect"></div>
			<div class="error-wrapper" style="width:300px;height:180px;left:calc(50% - 150px);top:calc(50% - 90px);">
				<div class="error-top">
					<span class="error-title">Error - JavaScript Required</span>
				</div>
				<div class="error-bottom">
					<span class="error-text">To use this web application, you need to enable JavaScript.</span>
					<a href="./"><button class="error-button">Refresh</button></a>
				</div>
			</div>
		</noscript>
	</body>
</html>