Browse Source

Updated admin section of website to use template engine for the login screen and started it for the downloads page.

pull/41/head
jrtechs 6 years ago
parent
commit
93e8ca189b
10 changed files with 117 additions and 144 deletions
  1. +8
    -94
      README.md
  2. +20
    -15
      admin/admin.js
  3. +16
    -15
      admin/login/login.js
  4. +2
    -0
      admin/posts/newPost.html
  5. +24
    -7
      includes/html/adminHeader.html
  6. +1
    -2
      includes/html/header.html
  7. +16
    -6
      includes/includes.js
  8. +12
    -5
      sites/admin.js
  9. +1
    -0
      sites/projects.js
  10. +17
    -0
      utils/utils.js

+ 8
- 94
README.md View File

@ -31,67 +31,6 @@ the [Creative Commons Attribution-ShareAlike 4.0 International](https://creative
unless otherwise stated. unless otherwise stated.
## MYSQL Schema
![](docs/blogSql.svg)
```mysql
create database jrtechs_blog;
use jrtechs_blog;
create table users(
user_id mediumint unsigned not null AUTO_INCREMENT,
user_name varchar(60) not null,
password char(64) not null,
salt char(64) not null,
primary key(user_id)
);
create table categories(
category_id mediumint unsigned not null AUTO_INCREMENT,
name varchar(60) not null,
url varchar(60) not null,
primary key(category_id)
);
create table posts(
post_id mediumint unsigned not null AUTO_INCREMENT,
category_id mediumint unsigned not null,
picture_url varchar(100) not null,
published datetime not null,
name varchar(100) not null,
url varchar(100) not null,
primary key(post_id)
);
create table downloads(
download_id mediumint unsigned not null AUTO_INCREMENT,
file varchar(40) not null,
name varchar(40) not null,
download_count mediumint not null,
primary key(download_id)
);
create table popular_posts(
popular_post_id mediumint unsigned not null AUTO_INCREMENT,
post_id mediumint unsigned not null,
primary key(popular_post_id)
);
create table traffic_log(
log_id mediumint unsigned not null AUTO_INCREMENT,
url varchar(60) not null,
ip varchar(20) not null,
date datetime not null,
primary key(log_id)
);
grant all on jrtechs_blog.* to blog_user@localhost identified by "password";
```
## Node Dependencies ## Node Dependencies
```bash ```bash
@ -110,7 +49,7 @@ npm install memory-cache --save
npm install request npm install request
npm install nodemailer npm install nodemailer
npm install nodemailer-smtp-transport npm install nodemailer-smtp-transport
npm install whiskers
npm install node-pandoc npm install node-pandoc
``` ```
@ -140,7 +79,8 @@ apt-get install optipng
## NGINX Configuration ## NGINX Configuration
``` ```
#jrtechs.net.conf #jrtechs.net.conf
server {
server
{
listen 80; listen 80;
server_name www.jrtechs.net jrtechs.net; server_name www.jrtechs.net jrtechs.net;
@ -148,7 +88,8 @@ server {
return 301 https://jrtechs.net$request_uri; return 301 https://jrtechs.net$request_uri;
} }
server {
server
{
listen 443 ssl http2; listen 443 ssl http2;
server_name jrtechs.net; server_name jrtechs.net;
@ -167,38 +108,11 @@ server {
} }
``` ```
```
#admin.jrtechs.net.conf
server {
listen 80;
server_name www.admin.jrtechs.net admin.jrtechs.net;
# redirect http requests to https
return 301 https://admin.jrtechs.net$request_uri;
}
server {
listen 443 ssl http2;
server_name admin.jrtechs.net;
ssl_certificate /etc/letsencrypt/live/admin.jrtechs.net/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/admin.jrtechs.net/privkey.pem;
location / {
proxy_pass http://localhost:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
## Projects Sites ## Projects Sites
As I develop more projects I would like an easy way to add and host them on my website without having to create another subdomain and generate more ssl certs. I simply want the project site to be accessible under https://jrtechs.net/project_name.
As I develop more projects I would like an easy way to add and host them on my website without having to create another sub-domain and generate more ssl certs.
I simply want the project site to be accessible under https://jrtechs.net/project_name.
### State Diagrm of Plan
### State Diagram of Plan
![diagram](docs/projectsSites.svg) ![diagram](docs/projectsSites.svg)

+ 20
- 15
admin/admin.js View File

@ -6,6 +6,8 @@
const utils = require('../utils/utils.js'); const utils = require('../utils/utils.js');
module.exports= module.exports=
{ {
/** /**
@ -14,33 +16,36 @@ module.exports=
* @param request * @param request
* @return {*|Promise} * @return {*|Promise}
*/ */
main: function(request, clientAddress)
main: function(request, clientAddress, templateContext)
{ {
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject)
{ {
//if logged in
if(request.session && request.session.user) if(request.session && request.session.user)
{ {
templateContext.loggedIn = true;
utils.getPostData(request).then(function (postData) utils.getPostData(request).then(function (postData)
{ {
console.log(postData);
Promise.all([require("./posts/newPost.js").main(postData),
require("./category/addCategory.js").main(postData),
require("./posts/editPost.js").main(postData),
require("./downloads/manageDownloads.js").main(postData)])
.then(function(content)
{
resolve(content.join(''));
}).catch(function(error)
{
reject(error);
});
resolve();
// console.log(postData);
// Promise.all([require("./posts/newPost.js").main(postData),
// require("./category/addCategory.js").main(postData),
// require("./posts/editPost.js").main(postData),
// require("./downloads/manageDownloads.js").main(postData)])
// .then(function(content)
// {
// resolve(content.join(''));
// }).catch(function(error)
// {
// reject(error);
// });
}); });
} }
else else
{ {
require("./login/login.js").main(request).then(function(html)
require("./login/login.js").main(request, clientAddress, templateContext).then(function()
{ {
resolve(html);
resolve();
}).catch(function(err) }).catch(function(err)
{ {
console.log(err); console.log(err);

+ 16
- 15
admin/login/login.js View File

@ -15,7 +15,7 @@ const qs = require('querystring');
* @param request * @param request
* @returns {Promise} * @returns {Promise}
*/ */
const processLogin = function(request, clientAddress)
const processLogin = function(request, clientAddress, templateContext)
{ {
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject)
{ {
@ -37,10 +37,12 @@ const processLogin = function(request, clientAddress)
//what actually logs in the user //what actually logs in the user
request.session.user = loginResult.user; request.session.user = loginResult.user;
console.log("user has logged in"); console.log("user has logged in");
resolve("<meta http-equiv=\"refresh\" content=\"0\">");
templateContext.goodLoginAttempt = true;
resolve();
} }
else else
{ {
templateContext.invalid = true;
banIP(clientAddress); banIP(clientAddress);
console.log("Invader!"); console.log("Invader!");
resolve("Wrong!"); resolve("Wrong!");
@ -110,27 +112,26 @@ module.exports=
* @param request express request containing post data * @param request express request containing post data
* @returns {Promise} resolves html of login page * @returns {Promise} resolves html of login page
*/ */
main: function(request, clientAddress)
main: function(request, clientAddress, templateContext)
{ {
if(isBanned(clientAddress))
return new Promise(function(resolve, reject)
{ {
return utils.printBannedPage();
}
else
{
return new Promise(function(resolve, reject)
if(isBanned(clientAddress))
{ {
Promise.all([utils.include("./admin/login/login.html"),
require("../../sidebar/sidebar.js").main(),
processLogin(request, clientAddress)]).then(function(html)
templateContext.banned = true;
resolve();
}
else
{
processLogin(request, clientAddress, templateContext).then(function()
{ {
resolve(html.join('') + "</div>");
resolve();
}).catch(function(err) }).catch(function(err)
{ {
reject(err); reject(err);
}) })
});
}
}
});
}, },
}; };

+ 2
- 0
admin/posts/newPost.html View File

@ -19,6 +19,8 @@
</div> </div>
</div> </div>
<br> <br>
<div class="blogPost"> <div class="blogPost">
<h1 class="text-center">New Post</h1> <h1 class="text-center">New Post</h1>

+ 24
- 7
includes/html/adminHeader.html View File

@ -18,7 +18,7 @@
<link rel="apple-touch-icon" sizes="180x180" href="/includes/img/favicon/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="/includes/img/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/includes/img/favicon/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="/includes/img/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/includes/img/favicon/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="/includes/img/favicon/favicon-16x16.png">
<link rel="manifest" href="/includes/img/favicon/site.webmanifest">
<link rel="manifest" href="/includes/img/favicon/site.json">
<link rel="mask-icon" href="/includes/img/favicon/safari-pinned-tab.svg" color="#5bbad5"> <link rel="mask-icon" href="/includes/img/favicon/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c"> <meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
@ -29,9 +29,23 @@
} }
p{font-size:18px;} p{font-size:18px;}
</style> </style>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: { linebreaks: { automatic: true, width: "container" }, scale: 75 },
"HTML-CSS": { linebreaks: { automatic: true, width: "container" }, scale: 75 },
SVG: { linebreaks: { automatic: true, width: "container" }, scale: 75 }
});
</script>
<script type="text/javascript" async
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<script src="../../admin/login/login.js"></script>
</head> </head>
<body>
<body class="no-mathjax">
<div class="navbar navbar-expand-lg navbar-dark fixed-top bg-primary" id="mainNav"> <div class="navbar navbar-expand-lg navbar-dark fixed-top bg-primary" id="mainNav">
<div class="container"> <div class="container">
@ -44,10 +58,16 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto"> <ul class="navbar-nav mr-auto">
<li class="nav-item active"> <li class="nav-item active">
<a class="nav-link" href="https://jrtechs.net">Home <span class="sr-only">(current)</span></a>
<a class="nav-link" href="https://jrtechs.net">Live Blog<span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://jrtechs.net/admin/">Admin Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://jrtechs.net/admin/posts/">Posts</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="https://jrtechs.net/contact/">Contact</a>
<a class="nav-link" href="https://jrtechs.net/admin/downloads/">Downloads</a>
</li> </li>
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
@ -65,6 +85,3 @@
</div> </div>
</div> </div>
<br><br><br><br><br> <br><br><br><br><br>
<div class="container">
<div class="row">

+ 1
- 2
includes/html/header.html View File

@ -45,10 +45,9 @@
<script type="text/javascript" async <script type="text/javascript" async
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"> src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script> </script>
\
</head> </head>
<body class="no-mathjax">
<body>
<div class="navbar navbar-expand-lg navbar-dark fixed-top bg-primary" id="mainNav"> <div class="navbar navbar-expand-lg navbar-dark fixed-top bg-primary" id="mainNav">
<div class="container"> <div class="container">

+ 16
- 6
includes/includes.js View File

@ -10,6 +10,10 @@
//used for file IO //used for file IO
const utils = require('../utils/utils.js'); const utils = require('../utils/utils.js');
const HEADER_KEY = "header";
const FOOTER_KEY = "footer";
//name of header file //name of header file
const HEADER_FILE = "includes/html/header.html"; const HEADER_FILE = "includes/html/header.html";
@ -77,9 +81,9 @@ module.exports =
* @param result * @param result
* @return {*} a promise retrieved from the utils.include function * @return {*} a promise retrieved from the utils.include function
*/ */
printHeader: function()
printHeader: function(templateContext)
{ {
return utils.include(HEADER_FILE);
return utils.includeInObject(HEADER_KEY, templateContext, HEADER_FILE);
}, },
@ -88,9 +92,9 @@ module.exports =
* *
* @return {*|Promise} * @return {*|Promise}
*/ */
printFooter: function()
printFooter: function(templateContext)
{ {
return utils.include(FOOTER_FILE);
return utils.includeInObject(FOOTER_KEY, templateContext, FOOTER_FILE);
}, },
/** /**
@ -98,9 +102,9 @@ module.exports =
* *
* @returns {*|Promise} * @returns {*|Promise}
*/ */
printAdminHeader()
printAdminHeader(templateContext)
{ {
return utils.include(ADMIN_HEADER);
return utils.includeInObject(HEADER_KEY, templateContext, ADMIN_HEADER);
}, },
@ -138,6 +142,12 @@ module.exports =
}, },
fetchTemplate: function(templateName)
{
return utils.include("templates/" + templateName);
},
/**Sends the user an image from the specified fileName. /**Sends the user an image from the specified fileName.
* *
* @param result * @param result

+ 12
- 5
sites/admin.js View File

@ -1,10 +1,15 @@
//sending static content //sending static content
const includes = require('../includes/includes.js'); const includes = require('../includes/includes.js');
//used for file IO
const utils = require('../utils/utils.js');
//used to append static content to result //used to append static content to result
const contentLoader = require('../includes/staticContentServer.js'); const contentLoader = require('../includes/staticContentServer.js');
const whiskers = require('whiskers');
/** /**
* @author Jeffery Russell 11-3-18 * @author Jeffery Russell 11-3-18
* *
@ -34,11 +39,14 @@ module.exports=
const file = "../admin/admin.js"; const file = "../admin/admin.js";
Promise.all([includes.printAdminHeader(),
require(file).main(request, clientAddress),
includes.printFooter()]).then(function(content)
var templateContext = Object();
Promise.all([includes.printAdminHeader(templateContext),
require(file).main(request, clientAddress, templateContext),
includes.printFooter(templateContext),
includes.fetchTemplate("admin/adminMain.html")]).then(function(content)
{ {
result.write(content.join(''));
result.write(whiskers.render(content.join(''), templateContext));
result.end(); result.end();
}).catch(function(err) }).catch(function(err)
@ -47,6 +55,5 @@ module.exports=
throw err; throw err;
}); });
} }
} }
}; };

+ 1
- 0
sites/projects.js View File

@ -32,6 +32,7 @@ module.exports=
if (!contentLoader.serveStaticContent(request, result, filename, "/blogContent/projects")) if (!contentLoader.serveStaticContent(request, result, filename, "/blogContent/projects"))
{ {
console.log(filename);
//do something? //do something?
} }
} }

+ 17
- 0
utils/utils.js View File

@ -31,6 +31,23 @@ module.exports=
}); });
}, },
includeInObject: function(key, context, fileName)
{
return new Promise(function(resolve, reject)
{
module.exports.include(fileName).then(function(result)
{
context[key] = result;
resolve();
}).catch(function(error)
{
context[key] = "File Not Found";
reject(error);
console.log(error);
})
})
},
/** /**
* Method which return the contents of a file as a string * Method which return the contents of a file as a string

Loading…
Cancel
Save