Project import generated by Copybara.
GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/src/js/secondfactor.js b/src/js/secondfactor.js
new file mode 100644
index 0000000..f537146
--- /dev/null
+++ b/src/js/secondfactor.js
@@ -0,0 +1,107 @@
+function verify() {
+ if (!document.getElementById("code").checkValidity()) {
+ document.querySelector(".mdl-js-snackbar").MaterialSnackbar.showSnackbar({
+ message: "El código de verificación debe tener 6 cifras."
+ });
+
+ return;
+ }
+
+ var body = {
+ code: document.getElementById("code").value
+ };
+
+ var content = document.getElementById("content");
+ content.innerHTML = '<div class="mdl-spinner mdl-js-spinner is-active"></div>';
+ content.style.textAlign = "center";
+ componentHandler.upgradeElements(content);
+
+ fetch("ajax/verifysecuritycode.php", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(body)
+ }).then(response => {
+ if (response.status !== 200) {
+ throw new Error("HTTP status is not 200.");
+ }
+
+ return response.json();
+ }).then(response => {
+ switch (response.status) {
+ case "ok":
+ document.location = "index.php";
+ break;
+
+ case "wrongCode":
+ document.location = "index.php?msg=secondfactorwrongcode";
+ break;
+
+ default:
+ console.error("An unknown status code was returned.");
+ }
+ }).catch(err => console.error("An unexpected error occurred.", err));
+}
+
+function verifyKeypress(e) {
+ if (event.keyCode == 13) {
+ verify();
+ }
+}
+
+function startWebauthn() {
+ fetch("ajax/startwebauthnauthentication.php", {
+ method: "POST"
+ }).then(response => {
+ if (response.status !== 200) {
+ response.text(); // @TODO: Remove this. It is only used so the response is available in Chrome Dev Tools
+ throw new Error("HTTP status is not 200.");
+ }
+
+ return response.json();
+ }).then(response => {
+ recursiveBase64StrToArrayBuffer(response);
+ return response;
+ }).then(getCredentialArgs => {
+ return navigator.credentials.get(getCredentialArgs);
+ }).then(cred => {
+ return {
+ id: cred.rawId ? arrayBufferToBase64(cred.rawId) : null,
+ clientDataJSON: cred.response.clientDataJSON ? arrayBufferToBase64(cred.response.clientDataJSON) : null,
+ authenticatorData: cred.response.authenticatorData ? arrayBufferToBase64(cred.response.authenticatorData) : null,
+ signature : cred.response.signature ? arrayBufferToBase64(cred.response.signature) : null
+ };
+ }).then(JSON.stringify).then(AuthenticatorAttestationResponse => {
+ return window.fetch("ajax/completewebauthnauthentication.php", {
+ method: "POST",
+ body: AuthenticatorAttestationResponse,
+ });
+ }).then(response => {
+ if (response.status !== 200) {
+ response.text(); // @TODO: remove this. It is only used so the response is available in Chrome Dev Tools
+ throw new Error("HTTP status is not 200 (2).");
+ }
+
+ return response.json();
+ }).then(json => {
+ if (json.status == "ok") {
+ document.location = "index.php";
+ }
+ }).catch(err => console.error("An unexpected error occurred.", err));
+}
+
+window.addEventListener("load", function() {
+ if (document.getElementById("totp")) {
+ document.getElementById("verify").addEventListener("click", verify);
+ document.getElementById("code").addEventListener("keypress", verifyKeypress);
+ document.getElementById("code").focus();
+ document.querySelector("a[href=\"#totp\"]").addEventListener("click", _ => {
+ document.getElementById("code").focus();
+ });
+ }
+
+ if (document.getElementById("startwebauthn")) {
+ document.getElementById("startwebauthn").addEventListener("click", startWebauthn);
+ }
+});