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 acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.