diff options
Diffstat (limited to 'csci4131/hw7')
-rw-r--r-- | csci4131/hw7/api/utilities.js | 64 | ||||
-rw-r--r-- | csci4131/hw7/create_accounts_table.js | 41 | ||||
-rw-r--r-- | csci4131/hw7/create_contacts_table.js | 44 | ||||
-rw-r--r-- | csci4131/hw7/dbconfig.xml | 8 | ||||
-rw-r--r-- | csci4131/hw7/dbio.js | 136 | ||||
-rw-r--r-- | csci4131/hw7/index.js | 109 | ||||
-rw-r--r-- | csci4131/hw7/insert_into_accounts_table.js | 45 | ||||
-rw-r--r-- | csci4131/hw7/login.html | 48 | ||||
-rw-r--r-- | csci4131/hw7/package.json | 21 | ||||
-rw-r--r-- | csci4131/hw7/public/contacts_old.html | 82 | ||||
-rw-r--r-- | csci4131/hw7/public/stock.html | 123 | ||||
-rw-r--r-- | csci4131/hw7/public/welcome.html | 53 |
12 files changed, 774 insertions, 0 deletions
diff --git a/csci4131/hw7/api/utilities.js b/csci4131/hw7/api/utilities.js new file mode 100644 index 0000000..12e06aa --- /dev/null +++ b/csci4131/hw7/api/utilities.js @@ -0,0 +1,64 @@ +const express = require('express')
+const db = require ('../dbio')
+const router = express.Router()
+router.use(express.urlencoded({ extended: true }))
+
+router.get('/contacts', function (req, res) {
+ db.getContacts().then(function(table) {
+ res.send(table)
+ });
+});
+
+router.post('/login', async function(req, res) {
+ var loginInfo = req.body;
+ var login = loginInfo.login;
+ var pwd = loginInfo.password;
+ let rows = [];
+
+ // Query the database tbl_login with login and hashed password
+ db.query(login, pwd).then(function(rows) {
+ // Provided there is no error, and the results set is assigned to a variable named rows:
+ if (rows.length >= 1) {// the length should be 0 or 1, but this will work for now
+ //success, set the session, return success
+ req.session.user = login;
+ res.json({ status: 'success' });
+ } else {
+ res.json({ status: 'fail' });
+ }
+ });
+
+});
+
+router.get('/logout', function(req, res) {
+ if(!req.session.user) {
+ res.send('Session not started, can not logout!');
+ } else {
+ req.session.destroy();
+ res.redirect('/login');
+ }
+});
+
+router.post('/addContact', function(req, res) {
+ var contact = req.body;
+ db.addContact(contact).then(function(r) {
+ res.send({flag: r});
+ }).catch(function() {
+
+ })
+});
+
+router.post('/updateContact', function(req, res) {
+ var edit = req.body;
+ db.editContact(edit).then(function(f) {
+ res.send({flag:f});
+ });
+})
+
+router.post('/deleteContact', function(req, res) {
+ var contact = req.body.name;
+ db.deleteContact(contact).then(function(r) {
+ res.send({flag: r});
+ })
+})
+
+module.exports = router;
diff --git a/csci4131/hw7/create_accounts_table.js b/csci4131/hw7/create_accounts_table.js new file mode 100644 index 0000000..61b2602 --- /dev/null +++ b/csci4131/hw7/create_accounts_table.js @@ -0,0 +1,41 @@ +/* +TO DO: +----- +READ ALL COMMENTS AND REPLACE VALUES ACCORDINGLY +*/ + +const mysql = require("mysql"); + +const dbCon = mysql.createConnection({ + host: "cse-mysql-classes-01.cse.umn.edu", + user: "C4131S21U83", // replace with the database user provided to you + password: "6919", // replace with the database password provided to you + database: "C4131S21U83", // replace with the database user provided to you + port: 3306 +}); + +console.log("Attempting database connection"); +dbCon.connect(function (err) { + if (err) { + throw err; + } + console.log("Connected to database!"); + + const sql = `CREATE TABLE tbl_accounts ( + acc_id INT NOT NULL AUTO_INCREMENT, + acc_name VARCHAR(20), + acc_login VARCHAR(20), + acc_password VARCHAR(200), + PRIMARY KEY (acc_id) + )`; + + console.log("Attempting to create table: tbl_accounts"); + dbCon.query(sql, function (err, result) { + if (err) { + throw err; + } + console.log("Table tbl_accounts created"); + }); + + dbCon.end(); +}); diff --git a/csci4131/hw7/create_contacts_table.js b/csci4131/hw7/create_contacts_table.js new file mode 100644 index 0000000..bcad389 --- /dev/null +++ b/csci4131/hw7/create_contacts_table.js @@ -0,0 +1,44 @@ +/* +TO DO: +----- +READ ALL COMMENTS AND REPLACE VALUES ACCORDINGLY +*/ + +const mysql = require("mysql"); + +const dbCon = mysql.createConnection({ + host: "cse-mysql-classes-01.cse.umn.edu", + user: "C4131S21U83", // replace with the database user provided to you + password: "6919", // replace with the database password provided to you + database: "C4131S21U83", // replace with the database user provided to you + port: 3306 +}); + +console.log("Attempting database connection"); +dbCon.connect(function (err) { + if (err) { + throw err; + } + console.log("Connected to database!"); + + const sql = `CREATE TABLE tbl_contacts ( + contact_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(30), + category VARCHAR(40), + location VARCHAR(300), + contact_info VARCHAR(200), + email VARCHAR(30), + website VARCHAR(300), + website_url VARCHAR(300) + )`; + + console.log("Attempting to create table: tbl_contacts"); + dbCon.query(sql, function (err, result) { + if (err) { + throw err; + } + console.log("Table tbl_accounts created"); + }); + + dbCon.end(); +}); diff --git a/csci4131/hw7/dbconfig.xml b/csci4131/hw7/dbconfig.xml new file mode 100644 index 0000000..a7e83ba --- /dev/null +++ b/csci4131/hw7/dbconfig.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<dbconfig> + <host>cse-mysql-classes-01.cse.umn.edu</host> + <user>C4131S21U83</user> + <password>6919</password> + <database>C4131S21U83</database> + <port>3306</port> +</dbconfig> diff --git a/csci4131/hw7/dbio.js b/csci4131/hw7/dbio.js new file mode 100644 index 0000000..96faf93 --- /dev/null +++ b/csci4131/hw7/dbio.js @@ -0,0 +1,136 @@ +var mysql = require("mysql"); +var bcrypt = require("bcrypt"); +var fs = require("fs"); +var xml2js = require("xml2js"); +var parser = new xml2js.Parser(); +var conInfo; +var connection; + +fs.readFile(__dirname + '/dbconfig.xml', function (err, data) { + if (err) throw err; + parser.parseString(data, function (err, result) { + if (err) throw err; + conInfo = result; + }); + connection = mysql.createConnection({ + host: conInfo.dbconfig.host[0], + user: conInfo.dbconfig.user[0], + password: conInfo.dbconfig.password[0], + database: conInfo.dbconfig.database[0], + port: conInfo.dbconfig.port[0] + }); + + connection.connect(function (err) { + if (err) { + throw err; + }; + console.log("Connected to MYSQL database!"); + }); +}); + + + +function passcheck(user,pass) { + return new Promise(function(resolve, reject) { + connection.query('SELECT * FROM tbl_accounts', function(err, rows, fields) { + let ret = []; + if (err) { + return reject(err); + } + for (var i = 0; i < rows.length; i++) { + if (rows[i].acc_login.localeCompare(user) === 0) { + if (bcrypt.compareSync(pass, rows[i].acc_password)) { + ret += rows[i]; + } + } + } + resolve(ret); + }); + }); +} + +function getContacts() { + return new Promise (function(resolve, reject) { + let conTab = [] + connection.query('SELECT * FROM tbl_contacts', function (err, rows, fields) { + if (err) throw err; + resolve(rows); + }); + }); +} + +function addContacts(contact) { + let newCon = { + name: contact.name, + category: contact.category, + location: contact.location, + contact_info: contact.contact, + email: contact.email, + website: contact.website, + } + return new Promise (function (resolve, reject) { + connection.query('SELECT * FROM tbl_contacts where name=?', contact.name, function(err, rows, fields) { + if (err) throw err; + console.log("Table found") + if (rows.length > 0) { + // Duplicate + console.log("found Duplicate name!"); + resolve(false); + } else { + connection.query('INSERT tbl_contacts SET ?', newCon, function (err, result) { //Parameterized insert + if (err) throw err; + console.log("Values inserted."); + resolve(true); + }); + } + }); + }); +} + + + +function editContact(contact) { + let edit = { + name: contact.name, + category: contact.category, + location: contact.location, + contact_info: contact.contact, + email: contact.email, + website: contact.website, + } + + return new Promise(function (resolve, reject) { + connection.query('SELECT * FROM tbl_contacts where name=?', contact.name, function (err, rows, fields) { + if (err) throw err; + if (rows.length == 0) { + console.log("Name Changed!"); + resolve(false); + } else { + connection.query('UPDATE tbl_contacts SET ? WHERE name=?', [edit, edit.name], function(err, result) { + if (err) throw err; + console.log("Value edited successfully?") + resolve(true); + }); + } + }); + }); +} + +function deleteContact(contact) { + return new Promise(function(resolve, reject) { + connection.query('DELETE FROM tbl_contacts WHERE name=?', contact, function (err, result) { + if (err) throw err; + console.log("Row deleted!") + resolve(); + }) + }) +} + + + + +exports.addContact = addContacts; +exports.query = passcheck; +exports.getContacts = getContacts; +exports.deleteContact = deleteContact; +exports.editContact = editContact; diff --git a/csci4131/hw7/index.js b/csci4131/hw7/index.js new file mode 100644 index 0000000..851b096 --- /dev/null +++ b/csci4131/hw7/index.js @@ -0,0 +1,109 @@ +// YOU CAN USE THIS FILE AS REFERENCE FOR SERVER DEVELOPMENT +const createError = require('http-errors'); + +// Include the express module +const express = require('express'); + +// helps in extracting the body portion of an incoming request stream +var bodyparser = require('body-parser'); + +// Path module - provides utilities for working with file and directory paths. +const path = require('path'); + +// Helps in managing user sessions +const session = require('express-session'); + +// include the mysql module +var mysql = require('mysql'); + +// Bcrypt library for comparing password hashes +const bcrypt = require('bcrypt'); + +// Include the express router. +const utilities = require('./api/utilities'); + +const port = 9001; + +// create an express application +const app = express(); + +// Use express-session +// In-memory session is sufficient for this assignment +app.use(session({ + secret: "csci4131secretkey", + saveUninitialized: true, + resave: false + } +)); + +// middle ware to serve static files +app.use(express.static(path.join(__dirname, 'public'))); + +// server listens on port for incoming connections +app.listen(port, () => console.log('Listening on port', port)); + +app.get('/', function (req, res) { + res.sendFile(path.join(__dirname, 'public/welcome.html')); +}); + +// GET method route for the contacts page. +// It serves contact.html present in public folder +app.get('/contacts', function(req, res) { + if(!req.session.user) { + res.redirect('/login'); + } else { + res.sendFile(path.join(__dirname, 'public/contacts.html')); + } +}); + +app.get('/stocks', function(req, res) { + res.redirect('/stock'); +}) + +app.get('/stock', function (req, res) { + if (!req.session.user) { + res.redirect('/login'); + } else { + res.sendFile(path.join(__dirname, 'public/stock.html')); + } +}); + +app.get('/addContact', function (req, res) { + if (!req.session.user) { + res.redirect('/login'); + } else { + res.sendFile(path.join(__dirname, 'public/addContact.html')); + } +}); + +app.get('/login', function (req, res) { + if (req.session.user) { + res.redirect('/contacts'); + } else { + res.sendFile(path.join(__dirname, 'login.html')); + } +}); + +app.get('/logout', function(req, res) { + res.redirect('/api/logout') +}); + +// Makes Express use a router called utilities +app.use('/api', utilities); + +// function to return the 404 message and error to client +app.use(function (req, res, next) { + next(createError(404)); +}); + +// error handler +app.use(function (err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + // res.render('error'); + res.send(); +}); diff --git a/csci4131/hw7/insert_into_accounts_table.js b/csci4131/hw7/insert_into_accounts_table.js new file mode 100644 index 0000000..0be14ce --- /dev/null +++ b/csci4131/hw7/insert_into_accounts_table.js @@ -0,0 +1,45 @@ +/* +TO DO: +----- +READ ALL COMMENTS AND REPLACE VALUES ACCORDINGLY +*/ + +const mysql = require("mysql"); +const bcrypt = require('bcrypt'); + +const dbCon = mysql.createConnection({ + host: "cse-mysql-classes-01.cse.umn.edu", + user: "C4131S21U83", // replace with the database user provided to you + password: "6919", // replace with the database password provided to you + database: "C4131S21U83", // replace with the database user provided to you + port: 3306 +}); + +console.log("Attempting database connection"); +dbCon.connect(function (err) { + if (err) { + throw err; + } + + console.log("Connected to database!"); + + const saltRounds = 10; + const myPlaintextPassword = 'admin%'; // replace with password chosen by you OR retain the same value + const passwordHash = bcrypt.hashSync(myPlaintextPassword, saltRounds); + + const rowToBeInserted = { + acc_name: 'admin$', // replace with acc_name chosen by you OR retain the same value + acc_login: 'admin$', // replace with acc_login chosen by you OR retain the same value + acc_password: passwordHash + }; + + console.log("Attempting to insert record into tbl_accounts"); + dbCon.query('INSERT tbl_accounts SET ?', rowToBeInserted, function (err, result) { + if (err) { + throw err; + } + console.log("Table record inserted!"); + }); + + dbCon.end(); +}); diff --git a/csci4131/hw7/login.html b/csci4131/hw7/login.html new file mode 100644 index 0000000..9bb80cc --- /dev/null +++ b/csci4131/hw7/login.html @@ -0,0 +1,48 @@ +<html> + +<head> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <script src="https://code.jquery.com/jquery-2.2.4.min.js"integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> +</head> + +<body> + <div class="jumbotron" style="background: DarkSeaGreen !important"> + <h1>Login Page</h1> + <div id="error"></div> + <br><br> + <form id="myForm" name="myForm" style="list-style-type:none"> + <div> + <label for="login">login:</label> + <input type="text" id="login" name="login" required> + </div> + <div> + <label for="password">password:</label> + <input id="password" name="password" type="password" required> + </div> + <input type="submit"value="Submit!"> + </form> + </div> + <script> + //jQuery below. Tread with caution as sneezing near here may rupture the fabric of reality. + $(document).ready(function () { + $('#myForm').submit(function (event) { + event.preventDefault();//collect the form data using Id Selector for whatever data you need to send to server + let login=$('#login').val(); + let password=$('#password').val(); + $.post('api/login', + {"login": login,"password": password}, + (data) => { + if(data.status === 'success'){ + //pseudo code + //Make sure error message is not displayed + //Re-direct to contacts page, + window.location.href='contacts';} + else{ + //Display error message + $('#error').html("<b>Login failed. Please try again.</b>") + }}); + }); + });</script> + +</html> diff --git a/csci4131/hw7/package.json b/csci4131/hw7/package.json new file mode 100644 index 0000000..0598cc4 --- /dev/null +++ b/csci4131/hw7/package.json @@ -0,0 +1,21 @@ +{ + "name": "strap012_hw7", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node index.js", + "test": "node index.js" + }, + "author": "", + "license": "MIT", + "dependencies": { + "bcrypt": "^5.0.1", + "body-parser": "^1.19.0", + "express": "^4.17.1", + "express-session": "^1.17.1", + "http-errors": "^1.8.0", + "mysql": "^2.18.1", + "xml2js": "^0.4.23" + } +} diff --git a/csci4131/hw7/public/contacts_old.html b/csci4131/hw7/public/contacts_old.html new file mode 100644 index 0000000..d0131ee --- /dev/null +++ b/csci4131/hw7/public/contacts_old.html @@ -0,0 +1,82 @@ +<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ <script type="text/javascript" defer>
+ //Get JSON
+ var xmlhttp = new XMLHttpRequest();
+ var url = "api/contacts";
+ xmlhttp.onreadystatechange = function () {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ var parse = JSON.parse(xmlhttp.responseText);
+ process(parse);
+ }
+ }
+ xmlhttp.open("GET", url, true);
+ xmlhttp.send();
+
+ function process(a) {
+ var table = document.getElementsByTagName("tbody")[0];
+ var contacts = a;
+ for (var i of contacts) {
+ var contact = i;
+ var row = table.insertRow();
+ for (var j in contact) {
+ if (j === "contact_id") continue;
+ if (j === "website_url") {
+ var url = row.insertCell();
+ url.innerHTML = "<a href =" + contact[j] + ">" + contact[j] + "</a>";
+ } else if (j === "email") {
+ var email = row.insertCell();
+ email.innerHTML = "<a href =mailto://" + contact[j] + ">" + contact[j] + "</a>";
+ } else {
+ var value = row.insertCell();
+ value.innerHTML = contact[j];
+ }
+ }
+ }
+ }
+
+ function add() {
+
+ }
+
+ </script>
+ </head>
+ <body>
+ <nav class="navbar navbar-default">
+ <div class="container-fluid">
+ <ul class="nav navbar-nav">
+ <li><a href="/"><b>Home</b></a></li>
+ <li><a href="contacts"><b>Contacts</b></a></li>
+ <li><a href="stock"><b>Stock Page</b></a></li>
+ <li><a href="logout"><b>Logout</b></a></li>
+ </ul>
+ </div>
+ </nav>
+ <br><br>
+
+ <div class="container">
+ <button type="button" id="add">Add Contact</button>
+ <table class="table" id="contactsTable">
+ <thead>
+ <tr>
+ <th scope="col">Name</th>
+ <th scope="col">Category</th>
+ <th scope="col">Location</th>
+ <th scope="col">Contact Information</th>
+ <th scope="col">Email</th>
+ <th scope="col">Website <br> (URL) </th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ <script type="text/javascript">
+
+ </script>
+ </body>
+</html>
\ No newline at end of file diff --git a/csci4131/hw7/public/stock.html b/csci4131/hw7/public/stock.html new file mode 100644 index 0000000..ae9d077 --- /dev/null +++ b/csci4131/hw7/public/stock.html @@ -0,0 +1,123 @@ +<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ <style>
+ pre {
+ max-height: 12em;
+ }
+ textarea {
+ width: 100%;
+ min-height: 30rem;
+ background-color: black;
+ font-family: "Lucida Console", Monaco, monospace;
+ font-size: 0.75 rem;
+ line-height: 1.2;
+ color: #fff;
+ }
+ </style>
+</head>
+
+<body>
+ <nav class="navbar navbar-default">
+ <div class="container-fluid">
+ <ul class="nav navbar-nav">
+ <li><a href="/"><b>Home</b></a></li>
+ <li><a href="contacts"><b>Contacts</b></a></li>
+ <li><a href="stock"><b>Stock Page</b></a></li>
+ <li><a href="logout"><b>Logout</b></a></li>
+ </ul>
+ </div>
+ </nav>
+ <br><br>
+
+ <div class="container">
+ <div class="panel panel-default">
+ <div class="panel-body"><center>Welcome to Stock Page</center></div>
+ </div>
+ </div>
+
+ <div class="container">
+ <div class="row">
+ <div class="col">
+ <table class="table table-bordered table-hover">
+ <tbody>
+ <tr>
+ <td class="col-md-6">Company</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <select id="Company" name="Company">
+ <option value="GME">Gamestop</option>
+ <option value="MSFT">Microsoft</option>
+ <option value="BA">Boeing Company</option>
+ <option value="AAPL">Apple Inc</option>
+ <option value="AMZN">Amazon</option>
+ <option value="NVDA">NVIDIA Corporation</option>
+ </select>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <button type="button" onclick="Click()">Get Data</button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+ <div class="container">
+ <div id="chartContainer"></div>
+ </div>
+
+ <div class="container">
+ <table class="table" id="StockData">
+ <thead>
+ <tr>
+ <th scope="col" id="meta">Company-MetaData</th>
+ <th scope="col" id="Time">Stock-Info</th>
+ </tr>
+ </thead>
+ <pre>
+ <tbody></tbody>
+ </pre>
+ </table>
+ </div>
+
+ <script>
+ function Click() {
+ var comp = document.getElementById("Company").value;
+ var xmlhttp = new XMLHttpRequest();
+ var url = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=" + comp + "&apikey=8MWSNPDWKH0BTBH2";
+ xmlhttp.onreadystatechange = function () {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ var parse = JSON.parse(xmlhttp.responseText);
+ var table = document.getElementById("StockData").getElementsByTagName("tbody")[0];
+ var row = table.insertRow();
+ for (var i in parse) {
+ var cell = row.insertCell();
+ cell.innerHTML = "<pre>" + JSON.stringify(parse[i], undefined, 2) + "</pre>";
+ }
+ }
+ }
+ xmlhttp.open("GET", url, true);
+ xmlhttp.send();
+
+ }
+ /* TODO:
+ / Bonus 1. Request the TIME_SERIES_DAILY endpoint of alphavantage API
+ / for the company selected in the dropdown. Display the JSON
+ / in the result according to the write up.
+ / Bonus 2. Take the JSON from the alphavantage API and chart it to a
+ / line chart using Chart.js to the chartContainer div. Ensure
+ / the chart meets all requirements from the HW writeup.
+ /*/
+ </script>
+</body>
+</html>
diff --git a/csci4131/hw7/public/welcome.html b/csci4131/hw7/public/welcome.html new file mode 100644 index 0000000..095023e --- /dev/null +++ b/csci4131/hw7/public/welcome.html @@ -0,0 +1,53 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <title>Welcome to Node.js</title> + <style type="text/css"> + .jumbotron { + text-align: center; + } + </style> +</head> + +<body> +<div class="jumbotron" style="background: DarkSeaGreen !important"> + <h1>Welcome to Express (Node.js)</h1> + <p>The objective of this assignment is to develop a basic website with:</p> + <p><b>Express</b> which is a Node.js web application framework.</p> + <br/> + <p>Following are some useful resources:</p> + + <ul style="list-style-type:none"> + <li><a href="https://expressjs.com/">Express website</a></li> + <li><a href="https://expressjs.com/en/starter/installing.html">Express installation</a></li> + <li><a href="https://expressjs.com/en/starter/hello-world.html">Hello world example</a></li> + <li><a href="https://expressjs.com/en/starter/basic-routing.html">Basic routing</a></li> + <li><a href="https://expressjs.com/en/starter/static-files.html">Serving static files in Express</a></li> + <li><a href="https://expressjs.com/en/starter/faq.html">FAQ</a></li> + <li><a href="https://expressjs.com/en/guide/routing.html">Routing</a></li> + <li><a href="https://expressjs.com/en/4x/api.html">API Reference</a></li> + <li><a href="https://expressjs.com/en/resources/books-blogs.html">Books and blogs</a></li> + <li><a href="https://docs.npmjs.com/getting-started/what-is-npm">NPM introduction</a></li> + </ul> + + <br/> + <br/> + +</div> + +<div class="row"> + <div class="col-md-1"></div> + <div class="col-md-10"> + <button id="myButton" type="button" class="btn btn-primary btn-block" onclick="location.href ='/login'"> + Navigate to website + </button> + </div> + <div class="col-md-1"></div> +</div> +</body> +</html> |