1
\$\begingroup\$

The following code is part of the front-end of a micro webservice for users to allow them to register MAC addresses of their network devices and administrators to enable those and to generate a dhcpd.conf file for a firewall application. You can find the whole project here.

macreg.js

/*
    (C) 2018 Richard Neumann <mail at richard dash neumann period de>
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';

var macreg = macreg || {};

macreg.LOGIN_URL = 'login';
macreg.SUBMIT_URL = 'mac';


/*
  Makes a request returning a promise.
*/
macreg.makeRequest = function (method, url, data=null, ...headers) {
    function parseResponse (response) {
        try {
            return JSON.parse(response);
        } catch (error) {
            return response;
        }
    }

    function executor (resolve, reject) {
        function onload () {
            if (this.status >= 200 && this.status < 300) {
                resolve({
                    response: parseResponse(xhr.response),
                    status: this.status,
                    statusText: xhr.statusText
                });
            } else {
                reject({
                    response: parseResponse(xhr.response),
                    status: this.status,
                    statusText: xhr.statusText
                });
            }
        }

        function onerror () {
            reject({
                response: parseResponse(xhr.response),
                status: this.status,
                statusText: xhr.statusText
            });
        }

        const xhr = new XMLHttpRequest();
        xhr.withCredentials = true;
        xhr.open(method, url);

        for (let header of headers) {
            xhr.setRequestHeader(...header);
        }

        xhr.onload = onload;
        xhr.onerror = onerror;

        if (data == null) {
            xhr.send();
        } else {
            xhr.send(data);
        }
    }

    return new Promise(executor);
};


/*
    Filters MAC address records.
*/
macreg._filter = function* (records) {
    const filterString = document.getElementById('filter').value.trim();

    if (filterString == '') {
        yield* records;
        return;
    }

    for (let record of records) {
        let matchDate = record.timestamp.includes(filterString);
        let matchUserName = record.userName.includes(filterString);
        let matchMacAddress = record.macAddress.includes(filterString);
        let matchDescription = record.description.includes(filterString);
        let matchIpv4address = record.ipv4address.includes(filterString);

        if (matchDate || matchUserName || matchMacAddress || matchDescription || matchIpv4address) {
            yield record;
        }
    }
};


/*
    Creates a toggle button for the respective record.
*/
macreg._toggleButton = function (record) {
    const column = document.createElement('td');
    const buttonToggle = document.createElement('button');
    buttonToggle.setAttribute('data-id', record.id);

    if (record.ipv4address == null) {
        buttonToggle.setAttribute('class', 'btn btn-success macreg-toggle');
        buttonToggle.textContent = 'Enable';
    } else {
        buttonToggle.setAttribute('class', 'btn btn-warning macreg-toggle');
        buttonToggle.textContent = 'Disable';
    }

    column.appendChild(buttonToggle);
    return column;
};


/*
    Creates a delete button for the respective record.
*/
macreg._deleteButton = function (record) {
    const column = document.createElement('td');
    const buttonDelete = document.createElement('button');
    buttonDelete.setAttribute('class', 'btn btn-danger macreg-delete');
    buttonDelete.setAttribute('data-id', record.id);
    buttonDelete.setAttribute('data-toggle', 'tooltip');
    buttonDelete.setAttribute('data-placement', 'top');
    buttonDelete.setAttribute('title', 'Delete this MAC address.');
    buttonDelete.textContent = 'Delete';
    column.appendChild(buttonDelete);
    return column;
};


/*
  Renders the respective records.
*/
macreg._render = function (response) {
    const container = document.getElementById('records');
    container.innerHTML = '';
    const records = macreg._filter(response.response);

    for (let record of records) {
        let row = document.createElement('tr');
        let fields = [
            record.timestamp,
            record.userName,
            record.macAddress,
            record.description,
            record.ipv4address || 'N/A'
        ];

        for (let field of fields) {
            let column = document.createElement('td');
            column.textContent = field;
            row.appendChild(column);
        }

        row.appendChild(macreg._toggleButton(record));
        row.appendChild(macreg._deleteButton(record));
        container.appendChild(row);
    }

    for (let button of document.getElementsByClassName('macreg-toggle')) {
        button.addEventListener('click', function() {
            macreg._toggle(button.getAttribute('data-id'));
        });
    }

    for (let button of document.getElementsByClassName('macreg-delete')) {
        button.addEventListener('click', function() {
            macreg._delete(button.getAttribute('data-id'));
        });
    }
};


/*
  Toggles a MAC address between enabled / disabled.
*/
macreg._toggle = function (id) {
    return macreg.makeRequest('PATCH', macreg.SUBMIT_URL + '/' + id).then(
        macreg.render,
        function (error) {
            alert(error.response);

            if (error.status == 401) {
                window.location = 'index.html';
            }
        }
    );
};


/*
    Deletes a MAC address.
*/
macreg._delete = function (id) {
    return macreg.makeRequest('DELETE', macreg.SUBMIT_URL + '/' + id).then(
        macreg.render,
        function (error) {
            alert(error.response);

            if (error.status == 401) {
                window.location = 'index.html';
            }
        }
    );
};


/*
  Initializes the login page.
*/
macreg.loginInit = function () {
    document.removeEventListener('DOMContentLoaded', macreg.loginInit);
    document.getElementById('btnLogin').addEventListener('click', function(event) {
        event.preventDefault();
    });
};


/*
  Initializes the submit page.
*/
macreg.submitInit = function () {
    document.removeEventListener('DOMContentLoaded', macreg.submitInit);
    document.getElementById('btnSubmit').addEventListener('click', function(event) {
        event.preventDefault();
    });
    document.getElementById('filter').addEventListener('change', macreg.render);
    return macreg.render();
};


/*
  Renders the page.
*/
macreg.render = function () {
    return macreg.makeRequest('GET', macreg.SUBMIT_URL).then(
        macreg._render,
        function (error) {
            if (error.status == 401) {
                // Session expired.
                alert(error.response);
                window.location = 'index.html';
            }
        }
    );
};


/*
  Performs a login.
*/
macreg.login = function () {
    const userName = document.getElementById('userName').value;
    const password = document.getElementById('password').value;
    const header = ['Content-Type', 'application/json'];
    const payload = {'userName': userName, 'passwd': password};
    const data = JSON.stringify(payload);
    return macreg.makeRequest('POST', macreg.LOGIN_URL, data, header).then(
        function () {
            window.location = 'submit.html';
        },
        function (error) {
            alert(error.response || 'Anmeldung fehlgeschlagen.');
        }
    );
};


/*
  Submits a new MAC address.
*/
macreg.submit = function () {
    const macAddress = document.getElementById('macAddress').value;
    const description = document.getElementById('description').value;
    const payload = {'macAddress': macAddress.trim(), 'description': description.trim()};
    const header = ['Content-Type', 'application/json'];
    const data = JSON.stringify(payload);
    return macreg.makeRequest('POST', macreg.SUBMIT_URL, data, header).then(
        function () {
            const form = document.getElementById('submitForm');
            form.reset();
            macreg.render();
        },
        function (error) {
            alert(error.response);

            switch(error.status) {
            case 401:
                window.location = 'index.html';
                break;
            default:
                macreg.render();
                break;
            }
        }
    );
};

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8"/>
  <title>MAC Address registration</title>
  <link rel="stylesheet" href="bootstrap.min.css">
  <script src="macreg.js"></script>
  <script>
    document.addEventListener('DOMContentLoaded', macreg.loginInit);
  </script>
</head>
<div class="container">
  <div class="row">
    <div class="col col-md-12">
      <h1>Login</h1>
      <form>
        <div class="form-group">
          <label for="userName">User Name</label>
          <input type="text" class="form-control" id="userName" aria-describedby="userNameHelp" placeholder="User Name">
          <small id="userNameHelp" class="form-text text-muted">Your local user name.</small>
        </div>
        <div class="form-group">
          <label for="password">Password</label>
          <input type="password" class="form-control" id="password" aria-describedby="passwordHelp" placeholder="Password">
          <small id="passwordHelp" class="form-text text-muted">Never give your password to somebody else.</small>
        </div>
        <button id="btnLogin" onclick="macreg.login();" type="submit" class="btn btn-primary btn-block">Login</button>
      </form>
    </div>
  </div>
</div>

submit.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8"/>
  <title>MAC Address registration</title>
  <link rel="stylesheet" href="bootstrap.min.css">
  <script src="macreg.js"></script>
  <script>
    document.addEventListener('DOMContentLoaded', macreg.submitInit);
  </script>
</head>
<div class="container">
  <div class="row">
    <div class="col col-md-12">
      <h1>MAC Address registration</h1>
      <form id="submitForm">
        <div class="form-group">
          <label for="macAddress">MAC Address</label>
          <input type="text" class="form-control" id="macAddress" aria-describedby="macAddressHelp" placeholder="MAC Address">
          <small id="macAddressHelp" class="form-text text-muted">On Windows press <kbd><kbd>Ctrl</kbd> + <kbd>R</kbd></kbd>, type <code>cmd</code> then hit Enter. In the terminal run <code>ipconfig /all</code>.<br/>
            In the output, look for your respective Ethernet or Wifi Addapter and search for the line <code>Physical Address</code>.
          </small>
        </div>
        <div class="form-group">
          <label for="description">Description</label>
          <input type="text" class="form-control" id="description" aria-describedby="descriptionHelp" placeholder="Description">
          <small id="descriptionHelp" class="form-text text-muted">Describe what kind of device this MAC address is for.</small>
        </div>
        <button id="btnSubmit" onclick="macreg.submit();" type="submit" class="btn btn-primary btn-block">Submit</button>
      </form>
      <br/>
      <h2>Registered MAC addresses</h2>
      <input type="text" class="form-control" id="filter" aria-describedby="macAddressHelp" placeholder="Filter...">
      <table class="table">
        <thead>
          <tr id="headRow">
            <th scope="row">Date</th>
            <th scope="row">User Name</th>
            <th scope="row">MAC Address</th>
            <th scope="row">Description</th>
            <th scope="row">IPv4 Address</th>
            <th scope="row">Toggle</th>
            <th scope="row">Delete</th>
          </tr>
        </thead>
        <tbody id="records"></tbody>
      </table>
    </div>
  </div>
</div>

I'd like to get feedback especially on the ES6 code quality and possible improvements.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.