Skip to content

Commit

Permalink
Update admin dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernest Paśnik committed Dec 11, 2023
1 parent 08eb58e commit a32d07e
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 63 deletions.
24 changes: 23 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ const minifyHTML = require('express-minify-html-2');
const bodyParser = require('body-parser');
const passport = require('passport');
const SteamStrategy = require('passport-steam').Strategy;
const UAParser = require('ua-parser-js');

const github = 'https://github.com/TeamHypersomnia';
const pressKit = `${github}/PressKit/blob/main/README.md#intro`;
const app = express();
const port = 3000;
const visitors = {};

// Passport
passport.serializeUser((user, done) => {
Expand Down Expand Up @@ -93,6 +95,26 @@ function adm(req, res, next) {
return next();
}

app.use((req, res, next) => {
const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
const ts = Math.floor(Date.now() / 1000);
if (visitors.hasOwnProperty(ip)) {
visitors[ip].lastSeen = ts;
} else {
const parser = new UAParser();
const userAgent = req.headers['user-agent'];
const result = parser.setUA(userAgent).getResult();
visitors[ip] = {
lastSeen: ts,
ip: ip,
os: result.os,
browser: result.browser,
referer: req.get('Referrer')
};
}
next();
});

// Routes
app.use('/', require('./src/index'));
app.use('/guide', require('./src/guide'));
Expand All @@ -109,7 +131,7 @@ app.get('/press', (req, res) => res.redirect(pressKit));
app.use('/upload', require('./src/upload'));
app.get('/admin', adm, (req, res) => res.redirect('/admin/system'));
app.use('/admin/system', adm, require('./src/admin/system'));
app.use('/admin/visitors', adm, require('./src/admin/visitors'));
app.use('/admin/visitors', adm, require('./src/admin/visitors')(visitors));
app.use('/admin/users', adm, require('./src/admin/users'));
app.use('/admin/creators', adm, require('./src/admin/creators'));
app.use('/admin/settings', adm, require('./src/admin/settings')(app.locals));
Expand Down
86 changes: 44 additions & 42 deletions nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,56 @@ user ubuntu;
worker_processes 2;

events {
use epoll;
worker_connections 1024;
use epoll;
worker_connections 1024;
}

http {
include mime.types;
server_tokens off;
sendfile on;
default_type application/octet-stream;
gzip on;
gzip_comp_level 5;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/rss+xml text/javascript image/x-icon;
gzip_http_version 1.0;
gzip_vary on;
gzip_disable msie6;
include mime.types;
server_tokens off;
sendfile on;
default_type application/octet-stream;
gzip on;
gzip_comp_level 5;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/rss+xml text/javascript image/x-icon;
gzip_http_version 1.0;
gzip_vary on;
gzip_disable msie6;

server {
listen 80;
listen 443 ssl http2;
server_name hypersomnia.xyz www.hypersomnia.xyz;
include ssl.conf;
client_max_body_size 25M;
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
server {
listen 80;
listen 443 ssl http2;
server_name hypersomnia.xyz www.hypersomnia.xyz;
include ssl.conf;
client_max_body_size 25M;
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

if ($scheme = http) {
return 308 https://hypersomnia.xyz$request_uri;
}

location / {
proxy_pass http://localhost:3000;
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;
}
if ($scheme = http) {
return 308 https://hypersomnia.xyz$request_uri;
}

location /builds {
alias /var/www/html/builds;
autoindex on;
}
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}

error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location /builds {
alias /var/www/html/builds;
autoindex on;
}

error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
}
}
25 changes: 24 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"moment": "^2.29.4",
"multer": "^1.4.5-lts.1",
"passport": "^0.7.0",
"passport-steam": "^1.0.18"
"passport-steam": "^1.0.18",
"ua-parser-js": "^1.0.37"
}
}
9 changes: 4 additions & 5 deletions src/admin/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ function loadUsers() {
}

router.get('/', (req, res) => {
const users = loadUsers();
const updatedUsers = Object.fromEntries(
Object.entries(users).map(([userId, user]) => [
userId,
Object.entries(loadUsers()).map(([k, v]) => [
k,
{
...user,
lastLogin: moment(user.lastLogin * 1000).fromNow()
...v,
lastLogin: moment(v.lastLogin * 1000).fromNow()
}
])
);
Expand Down
25 changes: 19 additions & 6 deletions src/admin/visitors.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
const express = require('express');
const router = express.Router();
const moment = require('moment');

router.get('/', (req, res) => {
res.render('admin/visitors', {
page: 'Visitors',
user: req.user
module.exports = function(visitors) {
router.get('/', (req, res) => {
const updatedVisitors = Object.fromEntries(
Object.entries(visitors).map(([k, v]) => [
k,
{
...v,
lastSeen: moment(v.lastSeen * 1000).fromNow()
}
])
);
res.render('admin/visitors', {
page: 'Visitors',
user: req.user,
visitors: updatedVisitors
});
});
});

module.exports = router;
return router;
};
7 changes: 6 additions & 1 deletion src/auth.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const express = require('express');
const router = express.Router();
const fs = require('fs');
const UAParser = require('ua-parser-js');
const path = `${__dirname}/../private/users.json`;

function loadUsers() {
Expand Down Expand Up @@ -39,11 +40,15 @@ module.exports = function(passport) {
}),
function (req, res) {
const users = loadUsers();
const parser = new UAParser();
const userAgent = req.headers['user-agent'];
const result = parser.setUA(userAgent).getResult();
const data = {
name: req.user.displayName,
lastLogin: Math.floor(Date.now() / 1000),
ip: req.headers['x-forwarded-for'] || req.socket.remoteAddress,
ua: req.get('User-Agent')
os: result.os,
browser: result.browser
};
if (users.hasOwnProperty(req.user.id)) {
Object.assign(users[req.user.id], data);
Expand Down
14 changes: 9 additions & 5 deletions views/admin/users.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
<table class="sortable">
<thead>
<tr>
<th width="25%">Steam ID</th>
<th width="25%">Display name</th>
<th width="25%">IP address</th>
<th width="25%">Last login</th>
<th width="16%">Steam ID</th>
<th width="20%">Display name</th>
<th width="16%">IP address</th>
<th width="16%">Last login</th>
<th width="16%">Browser</th>
<th width="16%">Operating system</th>
</tr>
</thead>
<tbody>
Expand All @@ -17,8 +19,10 @@
<tr>
<td><a href="https://steamcommunity.com/profiles/<%= k %>" target="_blank"><%= k %></a></td>
<td><%= v.name %></td>
<td><%= v.ip %></td>
<td><a href="https://db-ip.com/<%= v.ip %>" target="_blank"><%= v.ip %></a></td>
<td><%= v.lastLogin %></td>
<td><%= v.browser.name %> <%= v.browser.major %></td>
<td><%= v.os.name %> <%= v.os.version %></td>
</tr>
<% }); %>
</tbody>
Expand Down
26 changes: 25 additions & 1 deletion views/admin/visitors.ejs
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
<%- include('../overall_header'); %>
<%- include('nav'); %>

<p>TBA</p>
<div class="table-responsive">
<table class="sortable">
<thead>
<tr>
<th width="20%">IP address</th>
<th width="20%">Last seen</th>
<th width="20%">Browser</th>
<th width="20%">Operating system</th>
<th width="20%">HTTP referer</th>
</tr>
</thead>
<tbody>
<% Object.keys(visitors).forEach((k) => { %>
<% const v = visitors[k]; %>
<tr>
<td><a href="https://db-ip.com/<%= v.ip %>" target="_blank"><%= v.ip %></a></td>
<td><%= v.lastSeen %></td>
<td><%= v.browser.name %> <%= v.browser.major %></td>
<td><%= v.os.name %> <%= v.os.version %></td>
<td><%= v.referer %></td>
</tr>
<% }); %>
</tbody>
</table>
</div>

<%- include('../overall_footer'); %>

0 comments on commit a32d07e

Please sign in to comment.