]> git.cworth.org Git - empires-server/commitdiff
Convert rendering of login.html to use a nunjucks template
authorCarl Worth <cworth@cworth.org>
Sat, 23 May 2020 02:29:33 +0000 (19:29 -0700)
committerCarl Worth <cworth@cworth.org>
Sat, 23 May 2020 12:49:28 +0000 (05:49 -0700)
This new base.html template will allow us to avoid duplicating a bunch
of boilerplate as we start adding additional HTML pages.

Also, we pull the undisplay, add_message, lmno_login, and
lmno_login_loaded functions in instead of including the static
JavaScript file from /lmno.js.

This makes things much more independent here, (rather than relying on
JavaScript functions defined in a script file that is maintained in a
separate git repository: lmno.games).

lmno.js
login.html [deleted file]
templates/base.html [new file with mode: 0644]
templates/login.html [new file with mode: 0644]

diff --git a/lmno.js b/lmno.js
index abcdba2ef220bd6aff8375bb3190d0cfbc87c727..ff66a9bda71579c180123bbd7dfabbff50836407 100644 (file)
--- a/lmno.js
+++ b/lmno.js
@@ -4,6 +4,7 @@ const body_parser = require("body-parser");
 const session = require("express-session");
 const bcrypt = require("bcrypt");
 const path = require("path");
+const nunjucks = require("nunjucks");
 
 try {
   var lmno_config = require("./lmno-config.json");
@@ -40,6 +41,11 @@ app.use(session({
   saveUninitialized: false
 }));
 
+nunjucks.configure("templates", {
+  autoescape: true,
+  express: app
+});
+
 /* Load each of our game mini-apps. */
 var empires = require("./empires");
 
@@ -184,7 +190,7 @@ app.get('/login', (request, response) => {
     return;
   }
 
-  response.sendFile(path.join(__dirname, './login.html'));
+  response.render('login.html');
 });
 
 app.post('/login', async (request, response) => {
diff --git a/login.html b/login.html
deleted file mode 100644 (file)
index f78e679..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8"/>
-    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
-
-    <title>LMNO: Login</title>
-
-    <link rel="stylesheet" href="/reset.css" type="text/css" />
-    <link rel="stylesheet" href="/style.css" type="text/css" />
-  </head>
-  <body>
-
-    <script src="/lmno.js"></script>
-
-    <div id="page">
-
-      <div id="message-area">
-      </div>
-
-      <!-- The return false prevents the page from being reloaded -->
-      <form id="login-form" onsubmit="lmno_login(this); return false">
-        <div class="form-field large">
-          <label for="username">Username</label>
-          <input type="text" id="username" required>
-        </div>
-
-        <div class="form-field large">
-          <label for="Password">Password</label>
-          <input type="password" id="password" required>
-        </div>
-
-        <div class="form-field large">
-          <button type="submit">
-            Login
-          </button>
-        </div>
-      </form>
-
-    </div>
-  </body>
-</html>
diff --git a/templates/base.html b/templates/base.html
new file mode 100644 (file)
index 0000000..6895772
--- /dev/null
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
+
+    <title>{{ title }}</title>
+
+    <link rel="stylesheet" href="/reset.css" type="text/css" />
+    <link rel="stylesheet" href="/style.css" type="text/css" />
+
+    <script>
+      function undisplay(element) {
+        element.style.display="none";
+      }
+
+      function add_message(severity, message) {
+        message = `<div class="message ${severity}" onclick="undisplay(this)">
+<span class="hide-button" onclick="undisplay(this.parentElement)">&times;</span>
+${message}
+</div>`;
+        const message_area = document.getElementById('message-area');
+        message_area.insertAdjacentHTML('beforeend', message);
+      }
+    </script>
+    {% block head %}
+    {% endblock %}
+
+  </head>
+  <body>
+
+    <div id="page">
+
+      <div id="message-area">
+      </div>
+
+      {% block page %}
+      {% endblock %}
+
+    </div>
+  </body>
+</html>
diff --git a/templates/login.html b/templates/login.html
new file mode 100644 (file)
index 0000000..5767316
--- /dev/null
@@ -0,0 +1,57 @@
+{% extends "base.html" %}
+
+{% block head %}
+<script>
+  function lmno_login_loadend(request, username) {
+  if (request.status === 404) {
+    add_message("danger", "User authentication failed. Please try again.");
+    return;
+  }
+
+  /* Now that user is logged in, advance to the desired page (if any). */
+  const url = new URL(window.location);
+  const next_param = url.searchParams.get('next');
+  if (next_param) {
+    window.location.href = next_param;
+    return;
+  }
+
+  /* Otherwise, just report the successful login. */
+  add_message("success", `User ${username} logged in. Have fun.`);
+}
+
+function lmno_login(form) {
+  const username = form.username.value;
+  const password = form.password.value;
+
+  console.log("In lmno_login with username: " + username);
+  var request = new XMLHttpRequest();
+  request.addEventListener("loadend", () => lmno_login_loadend(request, username));
+
+  request.open("POST", "/login");
+  request.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
+  request.send(`{"username": "${username}", "password": "${password}"}`);
+}
+</script>
+{% endblock %}
+
+{% block page %}
+<!-- The return false prevents the page from being reloaded -->
+<form id="login-form" onsubmit="lmno_login(this); return false">
+  <div class="form-field large">
+    <label for="username">Username</label>
+    <input type="text" id="username" required>
+  </div>
+
+  <div class="form-field large">
+    <label for="Password">Password</label>
+    <input type="password" id="password" required>
+  </div>
+
+  <div class="form-field large">
+    <button type="submit">
+      Login
+    </button>
+  </div>
+</form>
+{% endblock %}