Having trouble with my JSFiddle code not functioning properly in a standard web browser for a Google Authenticator

Here is the code snippet that I am having trouble with: http://jsfiddle.net/sk1hg4h3/1/. It works fine in jsfiddle, but not in a normal browser. I have included the necessary elements in the head to call all the external files.

<head>
    <script src="auth.js" type="text/javascript"></script>
    <script src="sha.js" type="text/javascript"></script>
    <link rel="stylesheet"  href="bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="am.css">
    <script type="text/javascript" src="http://ajax.googleapis.co/ajax/libs/jquery/1.9.1/jquery.min.js"></script>>
</head>

Answer №1

Take a look at the example below. Make sure to include jQuery before sha.js and load the JavaScript files before closing the body tag.


    function dec2hex(s) {
      return (s < 15.5 ? '0' : '') + Math.round(s).toString(16);
    }

    function hex2dec(s) {
      return parseInt(s, 16);
    }

    function base32tohex(base32) {
      var base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
      var bits = "";
      var hex = "";

      for (var i = 0; i < base32.length; i++) {
        var val = base32chars.indexOf(base32.charAt(i).toUpperCase());
        bits += leftpad(val.toString(2), 5, '0');
      }

      for (var i = 0; i + 4 <= bits.length; i += 4) {
        var chunk = bits.substr(i, 4);
        hex = hex + parseInt(chunk, 2).toString(16);
      }
      return hex;

    }

    function leftpad(str, len, pad) {
      if (len + 1 >= str.length) {
        str = Array(len + 1 - str.length).join(pad) + str;
      }
      return str;
    }

    function updateOtp() {

      var key = base32tohex($('#secret').val());
      var epoch = Math.round(new Date().getTime() / 1000.0);
      var time = leftpad(dec2hex(Math.floor(epoch / 30)), 16, '0');

      // updated for jsSHA v2.0.0 - http://caligatio.github.io/jsSHA/
      var shaObj = new jsSHA("SHA-1", "HEX");
      shaObj.setHMACKey(key, "HEX");
      shaObj.update(time);
      var hmac = shaObj.getHMAC("HEX");

      $('#qrImg').attr('src', 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chl=200x200&chld=M|0&cht=qr&chl=otpauth://totp/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5227213720123a3d21267c313d3f">[email protected]</a>%3Fsecret%3D' + $('#secret').val());
      $('#secretHex').text(key);
      $('#secretHexLength').text((key.length * 4) + ' bits');
      $('#epoch').text(time);
      $('#hmac').empty();

      if (hmac == 'KEY MUST BE IN BYTE INCREMENTS') {
        $('#hmac').append($('<span/>').addClass('label important').append(hmac));
      } else {
        var offset = hex2dec(hmac.substring(hmac.length - 1));
        var part1 = hmac.substr(0, offset * 2);
        var part2 = hmac.substr(offset * 2, 8);
        var part3 = hmac.substr(offset * 2 + 8, hmac.length - offset);
        if (part1.length > 0) $('#hmac').append($('<span/>').addClass('label label-default').append(part1));
        $('#hmac').append($('<span/>').addClass('label label-primary').append(part2));
        if (part3.length > 0) $('#hmac').append($('<span/>').addClass('label label-default').append(part3));
      }

      var otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec('7fffffff')) + '';
      otp = (otp).substr(otp.length - 6, 6);

      $('#otp').text(otp);
    }

    function timer() {
      var epoch = Math.round(new Date().getTime() / 1000.0);
      var countDown = 30 - (epoch % 30);
      if (epoch % 30 == 0) updateOtp();
      $('#updatingIn').text(countDown);

    }

    $(function() {
      updateOtp();

      $('#update').click(function(event) {
        updateOtp();
        event.preventDefault();
      });

      $('#secret').keyup(function() {
        updateOtp();
      });

      setInterval(timer, 1000);
    });

      body {
        padding-top: 60px;
      }
      
      .container-fluid {
        min-width: 100px
      }
<div class="container-fluid">
  <div>
    <div class="row">
      <div class="span8">
        <h1>Time-based One-time Password Algorithm</h1>
        <p>This page contains a javascript implementation of the <em>Time-based One-time Password Algorithm</em> used by Google Authenticator and described in the <a href="http://tools.ietf.org/id/draft-mraihi-totp-timebased-06.html">TOTP RFC Draft</a>.</p>

        <p>Install Google Authenticator on your smartphone: <a href="http://itunes.apple.com/au/app/google-authenticator/id388497605?mt=8">iOS</a>, <a href="https://market.android.com/details?id=com.google.android.apps.authenticator&hl=en">Android</a>,
          <a href="http://m.google.com/authenticator">Blackberry</a>. As the TOTP is an open standard you can use this app to create one-time passwords for your own application. You add an account plus secret by scanning a QR code (more info on the
          <a
          href="http://code.google.com/p/google-authenticator/wiki/KeyUriFormat">google code wiki</a>). The javascript below implements the algorithm the smartphone app uses to generate the OTP - you would use this same algorithm <em>server-side</em> to verify an OTP.</p>

        <p>Put it to the test by setting the base32 secret, scanning the QR code in Google Authenticate. You should see the same OTP on your smartphone and displayed at the bottom on the page.</p>

      </div>
    </div>
    <div class="row">

      <form>
        <fieldset>

          <div class="clearfix">
            <label for="secret">Secret (base32)</label>
            <div class="input">
              <input type="text" size="30" name="secret" id="secret" class="xlarge" value="JBSWY3DPEHPK3PXP" />
            </div>
          </div>
          <!-- /clearfix -->
          <div class="clearfix">
            <label>Secret (hex)</label>
            <div class="input"><span class="label label-default" id="secretHex"></span>
              <span id='secretHexLength'></span></div>
          </div>
          <!-- /clearfix -->
          <div class="clearfix">
            <label>QR Code</label>
            <div class="input"><img id="qrImg" src="" /></div>
          </div>
          <!-- /clearfix -->
          <div class="clearfix">
            <label>Unix epoch div 30 (padded hex)</label>
            <div class="input"><span class="label label-default" id='epoch'></span></div>
          </div>
          <!-- /clearfix -->
          <div class="clearfix">
            <label>HMAC(secret, time)</label>
            <div class="input" id='hmac'></div>
          </div>
          <!-- /clearfix -->
          <div class="clearfix">
            <label>One-time Password</label>
            <div class="input"><span class="label label-primary" id='otp'></span></div>
          </div>
          <!-- /clearfix -->
          <div class="clearfix">
            <label>Updating in</label>
            <div class="input"><span id='updatingIn'></span></div>
          </div>
          <!-- /clearfix -->


        </fieldset>
      </form>
    </div>
  </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<script src="https://caligatio.github.io/jsSHA/sha.js"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps for splitting a numbered list and adding an image above each item:

I have a challenge I'm trying to tackle with my list: My goal is to create a long, numbered list that is divided into different sections I also want to include an image within each list item and have it display above the numbered title of the sectio ...

Using require to access an Immediately Invoked Function Expression variable from another file in Node.js

File 1 - Monitor.js var MONITOR = (function () { // Code for Monitoring return { doThing: function() { doThing(); } }; })(); File 2 - Test.js var monitor = require('../public/js/monitor.js'); I am trying to access the doThing() funct ...

Prevent the beforeunload dialog box from appearing

Looking for a solution that is compatible with all browsers and operating systems. Referring to this resource https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload This is what I have so far: window.addEventListener("beforeunload", function ( ...

Encountered a network error 500 when attempting to access a CodeIgniter controller action through Ajax

I am facing an issue with my admin controller. Within this controller, I have a processReq function that is triggered by a button click event. However, every time I click the button, I encounter an error message: "NetworkError: 500 Internal Server Error ...

What is the process of displaying an image every 5 seconds in React?

Each time you visit this URL: , a new image is displayed. I am trying to make my React component show a different image with this URL every 5 seconds, but I'm having trouble. Here is the code I have: import { useEffect, useState } from "react"; ...

Do not exceed 3 elements in a row when using Bootstrap's col-auto class

col-auto is excellent. It effortlessly arranges items by size in a row, but I need it to strictly limit the number of items in each row to a maximum of 3. Each row should only contain between 1-3 items. <link rel="stylesheet" href="https://cdn.jsdeli ...

Warning message in React about missing floating prop in components

application.js (Webpack Entry Point) import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; document.addEventListener('DOMContentLoaded', () => { ReactDOM.render(<App /> ...

When outputting HTML, make sure to use an if statement

Looking to dynamically generate select options without using if statements. Instead of string manipulation, I want a cleaner solution. <select name="test"> <option disabled selected> -- Select an industry -- </option> <?php ...

Tips for deploying an Angular application with Node.js

Currently, I've set up a nodejs backend by following a tutorial to integrate tweets into the frontend of my application. As I prepare to deploy to a development server, I have successfully built the frontend using ng build --prod. However, I am facin ...

Running a Custom Tab Component in a React Application

I am currently facing an issue with my React app that has multiple tabs. When I click on a specific tab, I want only that tab to render, but currently all tabs are rendering when I click on one. I have used console.log to confirm that all tabs are indeed r ...

Experiencing difficulties accessing the API route through Express

Every time I attempt to access /api/file, I am receiving a status code of 404. Here is the relevant code snippet: app.js : ... app.use("/api", require("./routes/users")); app.use("/api", require("./routes/file")); ...

Issues with Displaying Components Generated from an Array in JSX

I have a task variable which has the structure as follows: [ team_id_1: { task_id_1: { description: ... }, task_id_2: { description: ... } }, team_id_2: { ... } ] When trying ...

What could be causing the DIV to be out of place when the window is resized?

When the window is minimized, all elements remain intact except for the navigation. https://i.sstatic.net/xewNu.jpg The image below shows the layout when the window is maximized, while the image above depicts the layout when the window is minimized. HTM ...

Creating Beautiful Math Equations with LaTeX in EaselJS

Can MathJAX or a similar tool be integrated into an EaselJS DisplayObject? I am looking for alternative options. I want to render text like $$ 5 + 3 - 3 = 5 $$ on a canvas that serves as an EaselJS stage. Ideally, I hope to achieve this using the Text Cl ...

I can't seem to establish a connection with my MongoDB Atlas cluster. I encountered the MongooseError, which is as follows:

Error [MongooseError]: The uri parameter for the openUri() method needs to be a string but is currently set as "undefined". Please ensure that the first parameter for mongoose.connect() or mongoose.createConnection() is a valid string. const express = r ...

Ensuring User Data is Current in the UI with Firebase Auth Callbacks

Below is the standard method for setting the user state to currentuser that is returned from onAuthStateChanged. I am looking for a useEffect hook that will be triggered whenever there is an update to the user's information. Unfortunately, I am unable ...

Enhancing the appearance of a hyperlink heading

Seeking guidance on how to customize the title of a hyperlink. For instance, if I have a hyperlink structured like this: <a href="#" title="Hello">Click Here</a> Is there a way to alter the font style and size specifically for the word ' ...

The modal popup is getting lost behind the slider

I am facing an issue with opening a Modal popup for customer details. The problem occurs when the modal opens behind a slider on the website. However, when I slide the page down, the content of the modal becomes fully visible. https://i.stack.imgur.com/wR ...

When retrieving data from a JSON file, only display the value instead of showing the entire

When a user tries to login, I have created a modal window. If the user enters incorrect credentials, it returns SignInStatus.Failure, which is fine. However, the page then refreshes and only displays the number "3" at the top of the page with no other cont ...

What could be causing my website to lose its responsiveness after linking a domain?

Recently, I created a basic website for an event in my town using AWS Amplify from Amazon. Initially, the website was hosted without a custom domain and had a random URL. It worked well on both web and mobile platforms. However, after connecting a custom d ...