handle enter keypress register/login
This commit is contained in:
		| @@ -21,6 +21,9 @@ const mainController = { | ||||
|     }, | ||||
|     chat : (req, res) => { | ||||
|         res.sendFile(path.resolve(__dirname + '/../public/chat.js')); | ||||
|     }, | ||||
|     register : (req, res) => { | ||||
|         res.sendFile(path.resolve(__dirname + '/../public/register.js')); | ||||
|     } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,14 +1,19 @@ | ||||
| const currentUrl = window.location.href; | ||||
| import { ab2str, exportedKeyToPem, pemToKey, genKey } from "./ecc.js"; | ||||
| import { loginConfirm, registerConfirm } from "./register.js"; | ||||
|  | ||||
| // close popups with escape key | ||||
| document.addEventListener("keydown", (event) => { | ||||
|   if (event.isComposing || event.key === 'Escape') { | ||||
|     Array.from(document.getElementsByClassName("popup")).forEach(function(x) { | ||||
|         x.style.display = 'none'; | ||||
|     }); | ||||
|     document.getElementById("registerPopupText").innerText = ""; | ||||
|   } | ||||
| // handle key presses (close/confirm) | ||||
| document.addEventListener("keydown", async function(event) { | ||||
|         if (event.isComposing || event.key === 'Escape') { | ||||
|             Array.from(document.getElementsByClassName("popup")).forEach(function(x) { | ||||
|                 x.style.display = 'none'; | ||||
|             }); | ||||
|             document.getElementById("registerPopupText").innerText = ""; | ||||
|         } else if (event.key === 'Enter') { | ||||
|             if (registerPopup.style.display == 'flex') { | ||||
|                 await registerConfirm(); | ||||
|             } else if (loginPopup.style.display == 'flex') { | ||||
|                 await loginConfirm(); | ||||
|             } | ||||
|         } | ||||
| }); | ||||
|  | ||||
| // register popup | ||||
| @@ -21,43 +26,8 @@ document.getElementById("registercancel").addEventListener("click", function () | ||||
|     document.getElementById("registerPopupText").innerText = ""; | ||||
| }); | ||||
| // confirm | ||||
| document.getElementById("registerconfirm").addEventListener("click", async function () { | ||||
|     const apiUrl = `${currentUrl}account/register`; | ||||
|     const inputFieldSharedSecret = document.getElementById("sharedsecret"); | ||||
|     const inputFieldPublicKey = document.getElementById("publickey"); | ||||
|     let pubkey = null; | ||||
|     if (!inputFieldPublicKey.value) { | ||||
|         const { privateKey, publicKey } = await genKey(); | ||||
|         pubkey = exportedKeyToPem(publicKey, "public"); | ||||
|         document.getElementById("registerPopupText").innerText = exportedKeyToPem(privateKey, "private"); | ||||
|     } else { | ||||
|         pubkey = inputFieldPublicKey.value; | ||||
|     } | ||||
|     const postData = { | ||||
|         sharedSecret: inputFieldSharedSecret.value, | ||||
|         publicKey: pubkey | ||||
|     }; | ||||
|     // clear input fields | ||||
|     inputFieldSharedSecret.value=''; | ||||
|     inputFieldPublicKey.value=''; | ||||
|  | ||||
|     const requestOptions = { | ||||
|         method: 'POST', | ||||
|         headers: { | ||||
|             'Content-Type': 'application/json', | ||||
|         }, | ||||
|         body: JSON.stringify(postData) | ||||
|     }; | ||||
|     const response = await fetch(apiUrl, requestOptions) | ||||
|         .catch(error => { | ||||
|         console.error('Error during POST request:', error); | ||||
|     }); | ||||
|  | ||||
|     if (response.ok) { | ||||
|         console.log(response); | ||||
|     } else { | ||||
|         throw new Error('Error in server response'); | ||||
|     } | ||||
| document.getElementById("registerconfirm").addEventListener("click", async () => { | ||||
|   await registerConfirm(); | ||||
| }); | ||||
|  | ||||
| //login popup | ||||
| @@ -69,48 +39,6 @@ document.getElementById("logincancel").addEventListener("click", function () { | ||||
|     loginPopup.style.display = 'none'; | ||||
| }); | ||||
| // confirm | ||||
| document.getElementById("loginconfirm").addEventListener("click", async function () { | ||||
|     const apiUrl = `${currentUrl}account/login`; | ||||
|     const inputFieldPrivateKey = document.getElementById("privatekey"); | ||||
|     const response = await fetch(apiUrl, { method: 'GET' }); | ||||
|     if (!response.ok) { | ||||
|         throw new Error('Failed to fetch challenge'); | ||||
|     } | ||||
|     const { challenge } = await response.json(); | ||||
|     console.log("Received challenge:", challenge); | ||||
|  | ||||
|     let privKey = await pemToKey(inputFieldPrivateKey.value, "private"); | ||||
|  | ||||
|     const encoder = new TextEncoder(); | ||||
|     let encodedData = encoder.encode(challenge); | ||||
|  | ||||
|     // Sign the data using the private key. | ||||
|     const signature = await crypto.subtle.sign( | ||||
|         { | ||||
|             name: "Ed25519", | ||||
|         }, | ||||
|         privKey, | ||||
|         encodedData, | ||||
|     ); | ||||
|     let signatureString = ab2str(signature); | ||||
|     let signatureBase64 = window.btoa(signatureString); | ||||
|  | ||||
|     const verifyApiUrl = `${currentUrl}account/verify-challenge`; | ||||
|     const verifyResponse = await fetch(verifyApiUrl, { | ||||
|         method: 'POST', | ||||
|         headers: { | ||||
|             'Content-Type': 'application/json' | ||||
|         }, | ||||
|         body: JSON.stringify({ | ||||
|             signature: signatureBase64 | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|     if (!verifyResponse.ok) { | ||||
|         throw new Error('Failed to verify the challenge'); | ||||
|     } else { | ||||
|         const verifyResult = await verifyResponse.json(); | ||||
|         console.log("Verification result:", verifyResult); | ||||
|         location.reload(); | ||||
|     } | ||||
| document.getElementById("loginconfirm").addEventListener("click", async () => { | ||||
|   await loginConfirm(); | ||||
| }); | ||||
|   | ||||
							
								
								
									
										89
									
								
								src/public/register.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/public/register.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| const currentUrl = window.location.href; | ||||
| import { ab2str, exportedKeyToPem, pemToKey, genKey } from "./ecc.js"; | ||||
|  | ||||
| export async function registerConfirm() { | ||||
|     const apiUrl = `${currentUrl}account/register`; | ||||
|     const inputFieldSharedSecret = document.getElementById("sharedsecret"); | ||||
|     const inputFieldPublicKey = document.getElementById("publickey"); | ||||
|     let pubkey = null; | ||||
|     if (!inputFieldPublicKey.value) { | ||||
|         const { privateKey, publicKey } = await genKey(); | ||||
|         pubkey = exportedKeyToPem(publicKey, "public"); | ||||
|         document.getElementById("registerPopupText").innerText = exportedKeyToPem(privateKey, "private"); | ||||
|     } else { | ||||
|         pubkey = inputFieldPublicKey.value; | ||||
|     } | ||||
|     const postData = { | ||||
|         sharedSecret: inputFieldSharedSecret.value, | ||||
|         publicKey: pubkey | ||||
|     }; | ||||
|     // clear input fields | ||||
|     inputFieldSharedSecret.value=''; | ||||
|     inputFieldPublicKey.value=''; | ||||
|  | ||||
|     const requestOptions = { | ||||
|         method: 'POST', | ||||
|         headers: { | ||||
|             'Content-Type': 'application/json', | ||||
|         }, | ||||
|         body: JSON.stringify(postData) | ||||
|     }; | ||||
|     const response = await fetch(apiUrl, requestOptions) | ||||
|         .catch(error => { | ||||
|         console.error('Error during POST request:', error); | ||||
|     }); | ||||
|  | ||||
|     if (response.ok) { | ||||
|         console.log(response); | ||||
|     } else { | ||||
|         document.getElementById("registerPopupText").innerText = "Registration failed. Please try again."; | ||||
|         console.error('Error in server response.', response); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export async function loginConfirm() { | ||||
|     const apiUrl = `${currentUrl}account/login`; | ||||
|     const inputFieldPrivateKey = document.getElementById("privatekey"); | ||||
|     const response = await fetch(apiUrl, { method: 'GET' }); | ||||
|     if (!response.ok) { | ||||
|         throw new Error('Failed to fetch challenge'); | ||||
|     } | ||||
|     const { challenge } = await response.json(); | ||||
|     console.log("Received challenge:", challenge); | ||||
|  | ||||
|     let privKey = await pemToKey(inputFieldPrivateKey.value, "private"); | ||||
|  | ||||
|     const encoder = new TextEncoder(); | ||||
|     let encodedData = encoder.encode(challenge); | ||||
|  | ||||
|     // Sign the data using the private key. | ||||
|     const signature = await crypto.subtle.sign( | ||||
|         { | ||||
|             name: "Ed25519", | ||||
|         }, | ||||
|         privKey, | ||||
|         encodedData, | ||||
|     ); | ||||
|     let signatureString = ab2str(signature); | ||||
|     let signatureBase64 = window.btoa(signatureString); | ||||
|  | ||||
|     const verifyApiUrl = `${currentUrl}account/verify-challenge`; | ||||
|     const verifyResponse = await fetch(verifyApiUrl, { | ||||
|         method: 'POST', | ||||
|         headers: { | ||||
|             'Content-Type': 'application/json' | ||||
|         }, | ||||
|         body: JSON.stringify({ | ||||
|             signature: signatureBase64 | ||||
|         }) | ||||
|     }); | ||||
|  | ||||
|     if (!verifyResponse.ok) { | ||||
|         throw new Error('Failed to verify the challenge'); | ||||
|     } else { | ||||
|         const verifyResult = await verifyResponse.json(); | ||||
|         console.log("Verification result:", verifyResult); | ||||
|         inputFieldPrivateKey.value = ''; | ||||
|         location.reload(); | ||||
|     } | ||||
| } | ||||
| @@ -26,4 +26,8 @@ router | ||||
|   .route("/chat.js") | ||||
|   .get(mainController.chat); | ||||
|  | ||||
| router | ||||
|   .route("/register.js") | ||||
|   .get(mainController.register); | ||||
|  | ||||
| module.exports = router; | ||||
|   | ||||
| @@ -12,6 +12,7 @@ html(lang="en-US") | ||||
|       script(src="/chat.js", defer) | ||||
|     else | ||||
|        script(type="module", src="/popups.js", defer) | ||||
|        script(type="module", src="/register.js", defer) | ||||
|     link(rel="stylesheet" href="/css/bootstrap.min.css") | ||||
|   body | ||||
|     #mainbody | ||||
|   | ||||
		Reference in New Issue
	
	Block a user