mirror of
https://github.com/psforever/PSFPortal.git
synced 2026-01-19 18:14:45 +00:00
Merge pull request #8 from jgillich/master
Update db schema, fix broken /stats route
This commit is contained in:
commit
10b075ed78
170
api/db.js
170
api/db.js
|
|
@ -4,11 +4,11 @@ import bcrypt from 'bcrypt'
|
|||
import assert from 'assert'
|
||||
|
||||
function objectFlip(obj) {
|
||||
const ret = {};
|
||||
Object.keys(obj).forEach(key => {
|
||||
ret[obj[key]] = key;
|
||||
});
|
||||
return ret;
|
||||
const ret = {};
|
||||
Object.keys(obj).forEach(key => {
|
||||
ret[obj[key]] = key;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
let pg_error_inv = objectFlip(pg_error)
|
||||
|
|
@ -16,73 +16,73 @@ let pg_error_inv = objectFlip(pg_error)
|
|||
export let pool;
|
||||
|
||||
export const FACTION_MAP = {
|
||||
0 : ["Terran Republic", "TR"],
|
||||
1 : ["New Conglomerate", "NC"],
|
||||
2 : ["Vanu Sovereignty", "VS"],
|
||||
3 : ["Neutral", "NL"],
|
||||
0: ["Terran Republic", "TR"],
|
||||
1: ["New Conglomerate", "NC"],
|
||||
2: ["Vanu Sovereignty", "VS"],
|
||||
3: ["Neutral", "NL"],
|
||||
}
|
||||
|
||||
export const FACTION_MAP_INV = objectFlip(FACTION_MAP)
|
||||
const BCRYPT_ROUNDS = 4;
|
||||
|
||||
export const SQL_ORDER = Object.freeze({
|
||||
ASCENDING: Symbol("ASC"),
|
||||
DESCENDING: Symbol("DESC"),
|
||||
ASCENDING: Symbol("ASC"),
|
||||
DESCENDING: Symbol("DESC"),
|
||||
});
|
||||
|
||||
export const ACCOUNT = Object.freeze({
|
||||
THIS: Symbol("accounts"),
|
||||
ID: Symbol("id"),
|
||||
USER: Symbol("username"),
|
||||
PASSWORD: Symbol("passhash"),
|
||||
CREATED: Symbol("created"),
|
||||
MODIFIED: Symbol("last_modified"),
|
||||
BANNED: Symbol("inactive"),
|
||||
ADMIN: Symbol("gm"),
|
||||
THIS: Symbol("account"),
|
||||
ID: Symbol("id"),
|
||||
USER: Symbol("username"),
|
||||
PASSWORD: Symbol("passhash"),
|
||||
CREATED: Symbol("created"),
|
||||
MODIFIED: Symbol("last_modified"),
|
||||
BANNED: Symbol("inactive"),
|
||||
ADMIN: Symbol("gm"),
|
||||
|
||||
// A derived table column
|
||||
LAST_LOGIN: Symbol("last_login"),
|
||||
LAST_LOGIN: Symbol("last_login"),
|
||||
});
|
||||
|
||||
export const CHARACTER = Object.freeze({
|
||||
THIS: Symbol("characters"),
|
||||
ID: Symbol("id"),
|
||||
NAME: Symbol("name"),
|
||||
ACCOUNT_ID: Symbol("account_id"),
|
||||
FACTION: Symbol("faction_id"),
|
||||
GENDER: Symbol("gender_id"),
|
||||
HEAD: Symbol("head_id"),
|
||||
VOICE: Symbol("void_id"),
|
||||
CREATED: Symbol("created"),
|
||||
LAST_LOGIN: Symbol("last_login"),
|
||||
LAST_MODIFIED: Symbol("last_modified"),
|
||||
DELETED: Symbol("deleted"),
|
||||
THIS: Symbol("avatar"),
|
||||
ID: Symbol("id"),
|
||||
NAME: Symbol("name"),
|
||||
ACCOUNT_ID: Symbol("account_id"),
|
||||
FACTION: Symbol("faction_id"),
|
||||
GENDER: Symbol("gender_id"),
|
||||
HEAD: Symbol("head_id"),
|
||||
VOICE: Symbol("void_id"),
|
||||
CREATED: Symbol("created"),
|
||||
LAST_LOGIN: Symbol("last_login"),
|
||||
LAST_MODIFIED: Symbol("last_modified"),
|
||||
DELETED: Symbol("deleted"),
|
||||
});
|
||||
|
||||
export const LOGIN = Object.freeze({
|
||||
THIS: Symbol("logins"),
|
||||
ID: Symbol("id"),
|
||||
ACCOUNT_ID: Symbol("account_id"),
|
||||
THIS: Symbol("login"),
|
||||
ID: Symbol("id"),
|
||||
ACCOUNT_ID: Symbol("account_id"),
|
||||
});
|
||||
|
||||
function to_sql(symbol) {
|
||||
assert(typeof symbol == 'symbol',
|
||||
`symbol expected got ${typeof symbol}`)
|
||||
return String(symbol).slice(7,-1);
|
||||
return String(symbol).slice(7, -1);
|
||||
}
|
||||
|
||||
function to_sql_kv(fields, idx=1) {
|
||||
function to_sql_kv(fields, idx = 1) {
|
||||
let SQL = [];
|
||||
let values = [];
|
||||
|
||||
// This will ONLY get Symbols in the field dict
|
||||
if (!fields || Object.getOwnPropertySymbols(fields).length == 0) {
|
||||
return { sql : [], next_idx: idx, values: [] }
|
||||
return { sql: [], next_idx: idx, values: [] }
|
||||
}
|
||||
|
||||
Object.getOwnPropertySymbols(fields).forEach(key => {
|
||||
assert(typeof key == 'symbol')
|
||||
SQL.push(to_sql(key)+"=$"+idx++);
|
||||
SQL.push(to_sql(key) + "=$" + idx++);
|
||||
values.push(fields[key]);
|
||||
});
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ function to_sql_kv(fields, idx=1) {
|
|||
}
|
||||
}
|
||||
|
||||
function build_SET(fields, idx=1) {
|
||||
function build_SET(fields, idx = 1) {
|
||||
const kv = to_sql_kv(fields, idx);
|
||||
|
||||
assert(kv.sql.length > 0, "SET MUST have at least one kv pair")
|
||||
|
|
@ -103,7 +103,7 @@ function build_SET(fields, idx=1) {
|
|||
return kv;
|
||||
}
|
||||
|
||||
function build_WHERE(filter, idx=1) {
|
||||
function build_WHERE(filter, idx = 1) {
|
||||
const kv = to_sql_kv(filter.fields, idx);
|
||||
|
||||
if (kv.sql.length > 1) {
|
||||
|
|
@ -136,7 +136,7 @@ function build_ORDER_BY(sort) {
|
|||
return Symbol(`ORDER BY ${SQL.join(", ")}`);
|
||||
}
|
||||
|
||||
function build_OFFSET(offset, limit, idx=1) {
|
||||
function build_OFFSET(offset, limit, idx = 1) {
|
||||
assert(typeof offset == 'number', "offset must be a number");
|
||||
assert(typeof limit == 'number', "limit must be a number");
|
||||
|
||||
|
|
@ -147,13 +147,13 @@ function build_OFFSET(offset, limit, idx=1) {
|
|||
};
|
||||
}
|
||||
|
||||
async function get_row_count(table, filter=undefined) {
|
||||
async function get_row_count(table, filter = undefined) {
|
||||
let resp;
|
||||
|
||||
if (filter) {
|
||||
const where = build_WHERE(filter);
|
||||
resp = await pool.query(`SELECT COUNT(*) FROM ${to_sql(table)} ${to_sql(where.sql)}`,
|
||||
where.values);
|
||||
where.values);
|
||||
} else {
|
||||
resp = await pool.query(`SELECT COUNT(*) FROM ${to_sql(table)}`);
|
||||
}
|
||||
|
|
@ -180,7 +180,7 @@ export async function connect_to_db() {
|
|||
|
||||
export async function get_account_by_id(id) {
|
||||
try {
|
||||
const account = await pool.query('SELECT * FROM accounts WHERE id=$1', [id]);
|
||||
const account = await pool.query('SELECT * FROM account WHERE id=$1', [id]);
|
||||
|
||||
if (account.rows.length == 0) {
|
||||
return undefined;
|
||||
|
|
@ -196,12 +196,12 @@ export async function get_account_by_id(id) {
|
|||
}
|
||||
|
||||
export async function get_accounts(pagination, sort, order) {
|
||||
const start_id = (pagination.page-1)*pagination.items_per_page;
|
||||
const start_id = (pagination.page - 1) * pagination.items_per_page;
|
||||
const values = [start_id, pagination.items_per_page];
|
||||
|
||||
try {
|
||||
const account_count = await get_row_count(ACCOUNT.THIS);
|
||||
const accounts = await pool.query(`SELECT id, username, created, last_modified, gm, inactive FROM accounts ORDER BY ${to_sql(sort)} ${to_sql(order)} OFFSET $1 LIMIT $2`, values);
|
||||
const accounts = await pool.query(`SELECT id, username, created, last_modified, gm, inactive FROM account ORDER BY ${to_sql(sort)} ${to_sql(order)} OFFSET $1 LIMIT $2`, values);
|
||||
|
||||
pagination.item_count = account_count;
|
||||
pagination.page_count = Math.ceil(pagination.item_count / pagination.items_per_page);
|
||||
|
|
@ -220,7 +220,7 @@ export async function get_accounts(pagination, sort, order) {
|
|||
}
|
||||
|
||||
export async function get_accounts_login_info(pagination, sort, filter) {
|
||||
const start_id = (pagination.page-1)*pagination.items_per_page;
|
||||
const start_id = (pagination.page - 1) * pagination.items_per_page;
|
||||
const values = [start_id, pagination.items_per_page];
|
||||
|
||||
try {
|
||||
|
|
@ -233,17 +233,17 @@ export async function get_accounts_login_info(pagination, sort, filter) {
|
|||
// this was a really hard query to get right...
|
||||
// https://www.gab.lc/articles/better_faster_subqueries_postgresql/
|
||||
const accounts = await pool.query(
|
||||
'SELECT accounts.*, COALESCE(l.lastLogin, TIMESTAMP \'epoch\') as last_login, l2.ip_address, l2.canonical_hostname FROM accounts' +
|
||||
' LEFT OUTER JOIN (' +
|
||||
' SELECT MAX(id) as loginId, account_id, MAX(login_time) as lastLogin' +
|
||||
' FROM logins' +
|
||||
' GROUP BY account_id' +
|
||||
' ) l ON l.account_id = accounts.id' +
|
||||
' LEFT OUTER JOIN logins l2' +
|
||||
' ON l2.id = l.loginId' +
|
||||
` ${to_sql(where.sql)}` +
|
||||
` ${to_sql(order)}` +
|
||||
` ${to_sql(offset.sql)}`, values);
|
||||
'SELECT account.*, COALESCE(l.lastLogin, TIMESTAMP \'epoch\') as last_login, l2.ip_address, l2.canonical_hostname FROM account' +
|
||||
' LEFT OUTER JOIN (' +
|
||||
' SELECT MAX(id) as loginId, account_id, MAX(login_time) as lastLogin' +
|
||||
' FROM login' +
|
||||
' GROUP BY account_id' +
|
||||
' ) l ON l.account_id = account.id' +
|
||||
' LEFT OUTER JOIN login l2' +
|
||||
' ON l2.id = l.loginId' +
|
||||
` ${to_sql(where.sql)}` +
|
||||
` ${to_sql(order)}` +
|
||||
` ${to_sql(offset.sql)}`, values);
|
||||
|
||||
pagination.item_count = account_count;
|
||||
pagination.page_count = Math.ceil(pagination.item_count / pagination.items_per_page);
|
||||
|
|
@ -254,9 +254,9 @@ export async function get_accounts_login_info(pagination, sort, filter) {
|
|||
|
||||
if (r.ip_address !== null) {
|
||||
r.last_login = {
|
||||
time : r.last_login,
|
||||
hostname : r.canonical_hostname,
|
||||
ip : r.ip_address,
|
||||
time: r.last_login,
|
||||
hostname: r.canonical_hostname,
|
||||
ip: r.ip_address,
|
||||
}
|
||||
} else {
|
||||
r.last_login = {}
|
||||
|
|
@ -277,12 +277,12 @@ export async function get_accounts_login_info(pagination, sort, filter) {
|
|||
}
|
||||
|
||||
export async function get_characters(pagination, sort, order) {
|
||||
const start_id = (pagination.page-1)*pagination.items_per_page;
|
||||
const start_id = (pagination.page - 1) * pagination.items_per_page;
|
||||
const values = [start_id, pagination.items_per_page];
|
||||
|
||||
try {
|
||||
const char_count = await get_row_count(CHARACTER.THIS);
|
||||
const chars = await pool.query(`SELECT id, account_id, name, faction_id, created, last_login FROM characters ORDER BY ${to_sql(sort)} ${to_sql(order)} OFFSET $1 LIMIT $2`, values);
|
||||
const chars = await pool.query(`SELECT id, account_id, name, faction_id, created, last_login FROM avatar ORDER BY ${to_sql(sort)} ${to_sql(order)} OFFSET $1 LIMIT $2`, values);
|
||||
|
||||
pagination.item_count = char_count;
|
||||
pagination.page_count = Math.ceil(pagination.item_count / pagination.items_per_page);
|
||||
|
|
@ -297,7 +297,7 @@ export async function get_characters(pagination, sort, order) {
|
|||
|
||||
export async function get_characters_by_account(account_id) {
|
||||
try {
|
||||
const characters = await pool.query('SELECT * FROM characters WHERE account_id=$1 AND deleted=false', [account_id])
|
||||
const characters = await pool.query('SELECT * FROM avatar WHERE account_id=$1 AND deleted=false', [account_id])
|
||||
return characters.rows;
|
||||
} catch (e) {
|
||||
if (e.code)
|
||||
|
|
@ -308,7 +308,7 @@ export async function get_characters_by_account(account_id) {
|
|||
|
||||
export async function get_account_by_name(name) {
|
||||
try {
|
||||
const account = await pool.query('SELECT * FROM accounts WHERE username=$1', [name]);
|
||||
const account = await pool.query('SELECT * FROM account WHERE username=$1', [name]);
|
||||
return account.rows[0];
|
||||
} catch (e) {
|
||||
if (e.code)
|
||||
|
|
@ -319,7 +319,7 @@ export async function get_account_by_name(name) {
|
|||
|
||||
export async function get_character_by_name(name) {
|
||||
try {
|
||||
const account = await pool.query('SELECT id, account_id, name, faction_id, created, last_login FROM characters WHERE name=$1 AND deleted=false', [name]);
|
||||
const account = await pool.query('SELECT id, account_id, name, faction_id, created, last_login FROM avatar WHERE name=$1 AND deleted=false', [name]);
|
||||
return account.rows[0];
|
||||
} catch (e) {
|
||||
if (e.code)
|
||||
|
|
@ -331,7 +331,7 @@ export async function get_character_by_name(name) {
|
|||
export async function create_account(username, password) {
|
||||
try {
|
||||
const passhash = await bcrypt.hash(password, BCRYPT_ROUNDS);
|
||||
const account_id = await pool.query('INSERT INTO accounts(username, passhash) VALUES($1, $2) RETURNING id', [username, passhash]);
|
||||
const account_id = await pool.query('INSERT INTO account(username, passhash) VALUES($1, $2) RETURNING id', [username, passhash]);
|
||||
return account_id.rows[0].id;
|
||||
} catch (e) {
|
||||
if (e.code)
|
||||
|
|
@ -349,7 +349,7 @@ export async function update_account(account_id, fields) {
|
|||
set.values.push(account_id)
|
||||
|
||||
try {
|
||||
const update_result = await pool.query(`UPDATE accounts ${to_sql(set.sql)} WHERE id=$${set.next_idx}`, set.values);
|
||||
const update_result = await pool.query(`UPDATE account ${to_sql(set.sql)} WHERE id=$${set.next_idx}`, set.values);
|
||||
return update_result.rowCount;
|
||||
} catch (e) {
|
||||
if (e.code)
|
||||
|
|
@ -360,7 +360,7 @@ export async function update_account(account_id, fields) {
|
|||
|
||||
export async function get_empire_stats() {
|
||||
try {
|
||||
const query = await pool.query('SELECT faction_id, COUNT(*) FROM characters GROUP BY faction_id');
|
||||
const query = await pool.query('SELECT faction_id, COUNT(*) FROM avatar GROUP BY faction_id');
|
||||
const empires = {};
|
||||
|
||||
query.rows.forEach((r) => {
|
||||
|
|
@ -380,7 +380,7 @@ export async function get_stats() {
|
|||
try {
|
||||
const account_count = await get_row_count(ACCOUNT.THIS);
|
||||
const character_count = await get_row_count(CHARACTER.THIS);
|
||||
const last_character = await pool.query('SELECT id, account_id, name, faction_id, created FROM characters ORDER BY id DESC LIMIT 1');
|
||||
const last_character = await pool.query('SELECT id, account_id, name, faction_id, created FROM avatar ORDER BY id DESC LIMIT 1');
|
||||
|
||||
const stats = {}
|
||||
|
||||
|
|
@ -398,16 +398,16 @@ export async function get_stats() {
|
|||
}
|
||||
|
||||
export async function get_account_logins(account_id, pagination) {
|
||||
const start_id = (pagination.page-1)*pagination.items_per_page;
|
||||
const start_id = (pagination.page - 1) * pagination.items_per_page;
|
||||
const values = [account_id, start_id, pagination.items_per_page];
|
||||
|
||||
try {
|
||||
const login_count = await get_row_count(LOGIN.THIS, {
|
||||
fields : {
|
||||
[LOGIN.ACCOUNT_ID] : account_id,
|
||||
fields: {
|
||||
[LOGIN.ACCOUNT_ID]: account_id,
|
||||
}
|
||||
});
|
||||
const logins = await pool.query('SELECT * FROM logins WHERE account_id=$1 ORDER by login_time DESC ' + ` OFFSET $2 LIMIT $3`, values);
|
||||
const logins = await pool.query('SELECT * FROM login WHERE account_id=$1 ORDER by login_time DESC ' + ` OFFSET $2 LIMIT $3`, values);
|
||||
|
||||
pagination.item_count = login_count;
|
||||
pagination.page_count = Math.ceil(pagination.item_count / pagination.items_per_page);
|
||||
|
|
@ -421,7 +421,7 @@ export async function get_account_logins(account_id, pagination) {
|
|||
}
|
||||
|
||||
export async function search(term, pagination) {
|
||||
const start_id = (pagination.page-1)*pagination.items_per_page;
|
||||
const start_id = (pagination.page - 1) * pagination.items_per_page;
|
||||
|
||||
term = term.replace(/%/g, "");
|
||||
|
||||
|
|
@ -429,15 +429,15 @@ export async function search(term, pagination) {
|
|||
return [];
|
||||
}
|
||||
|
||||
const values = ['%'+term.toUpperCase()+'%', start_id, pagination.items_per_page];
|
||||
const values = ['%' + term.toUpperCase() + '%', start_id, pagination.items_per_page];
|
||||
|
||||
try {
|
||||
const accounts = await pool.query('SELECT id, username, gm, inactive FROM accounts ' +
|
||||
'WHERE upper(username) LIKE $1 '+
|
||||
` ORDER BY username OFFSET $2 LIMIT $3`, values);
|
||||
const characters = await pool.query('SELECT id, name, account_id, faction_id FROM characters ' +
|
||||
'WHERE upper(name) LIKE $1 '+
|
||||
` ORDER BY name OFFSET $2 LIMIT $3`, values);
|
||||
const accounts = await pool.query('SELECT id, username, gm, inactive FROM account ' +
|
||||
'WHERE upper(username) LIKE $1 ' +
|
||||
` ORDER BY username OFFSET $2 LIMIT $3`, values);
|
||||
const characters = await pool.query('SELECT id, name, account_id, faction_id FROM avatar ' +
|
||||
'WHERE upper(name) LIKE $1 ' +
|
||||
` ORDER BY name OFFSET $2 LIMIT $3`, values);
|
||||
|
||||
pagination.item_count = 100;
|
||||
pagination.page_count = Math.ceil(pagination.item_count / pagination.items_per_page);
|
||||
|
|
@ -460,7 +460,7 @@ export async function search(term, pagination) {
|
|||
});
|
||||
|
||||
// sort by name
|
||||
results.sort(function(a, b) {
|
||||
results.sort(function (a, b) {
|
||||
var nameA = a.name.toUpperCase(); // ignore upper and lowercase
|
||||
var nameB = b.name.toUpperCase(); // ignore upper and lowercase
|
||||
if (nameA < nameB) {
|
||||
|
|
@ -484,7 +484,7 @@ export async function search(term, pagination) {
|
|||
|
||||
export async function validate_account(username, password) {
|
||||
try {
|
||||
const data = await pool.query('SELECT id, passhash FROM accounts WHERE username=$1 and gm=true', [username]);
|
||||
const data = await pool.query('SELECT id, passhash FROM account WHERE username=$1', [username]);
|
||||
|
||||
if (data.rows.length === 0) {
|
||||
return undefined;
|
||||
|
|
|
|||
12
api/info.js
12
api/info.js
|
|
@ -1,6 +1,6 @@
|
|||
import express from 'express'
|
||||
import * as db from './db.js'
|
||||
import {get_server_info} from './psadmin.js'
|
||||
import { get_server_info } from './psadmin.js'
|
||||
|
||||
const api = express.Router();
|
||||
|
||||
|
|
@ -8,27 +8,27 @@ api.get('/stats', async (req, res, next) => {
|
|||
try {
|
||||
const stats = await db.get_stats();
|
||||
|
||||
stats.empires = { "TR" : 0, "NC" : 0, "VS" : 0 }
|
||||
stats.empires = { "TR": 0, "NC": 0, "VS": 0 }
|
||||
|
||||
const info = get_server_info();
|
||||
let player_info = []
|
||||
let players = info.players;
|
||||
|
||||
for (let i = 0; i < players.length; i++) {
|
||||
const char = await db.get_character_by_name(players[i]);
|
||||
const char = await db.get_character_by_name(players[i].name);
|
||||
|
||||
if (char) {
|
||||
player_info = player_info.concat(char)
|
||||
stats.empires[db.FACTION_MAP[char.faction_id][1]] += 1
|
||||
} else {
|
||||
console.log("WARNING: cannot find player info '" + players[i] + "' (are you sure PSAdmin is configured right?)")
|
||||
console.log("WARNING: cannot find player info '" + players[i].name + "' (are you sure PSAdmin is configured right?)")
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).json({status : info.status, players : player_info, ...stats });
|
||||
res.status(200).json({ status: info.status, players: player_info, ...stats });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
res.status(500).json({ message : 'error' });
|
||||
res.status(500).json({ message: 'error' });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
12
api/user.js
12
api/user.js
|
|
@ -9,7 +9,7 @@ api.param("user", fetch_user_middleware);
|
|||
api.get('/user', NEED_SESSION, async (req, res, next) => {
|
||||
try {
|
||||
const account = await db.get_account_by_id(req.session.account_id);
|
||||
res.status(200).json({ id : account.id, name: account.username, admin : account.gm });
|
||||
res.status(200).json({ id: account.id, name: account.username, admin: account.gm });
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
res.status(500).json({ message: 'error' });
|
||||
|
|
@ -29,12 +29,12 @@ api.get('/user/:user/profile', NEED_SESSION, async (req, res, next) => {
|
|||
const characters = await db.get_characters_by_account(target_account.id);
|
||||
|
||||
res.status(200).json({
|
||||
id : account.id,
|
||||
id: account.id,
|
||||
name: account.username,
|
||||
//email : account.email, // TODO
|
||||
email : "bademail@email.com",
|
||||
account_created : account.created,
|
||||
admin : account.gm,
|
||||
email: "N/A",
|
||||
account_created: account.created,
|
||||
admin: account.gm,
|
||||
inactive: account.inactive,
|
||||
characters: characters,
|
||||
});
|
||||
|
|
@ -55,7 +55,7 @@ api.get('/user/:user/logins', NEED_SESSION, async (req, res, next) => {
|
|||
|
||||
try {
|
||||
const logins = await db.get_account_logins(account.id, pagination)
|
||||
res.status(200).json({ logins : logins, page: pagination});
|
||||
res.status(200).json({ logins: logins, page: pagination });
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
res.status(500).json({ message: 'error' });
|
||||
|
|
|
|||
43
index.js
43
index.js
|
|
@ -8,18 +8,7 @@ import api from './api/index.js'
|
|||
import { start_server_polling } from './api/psadmin.js'
|
||||
import * as db from './api/db.js'
|
||||
|
||||
const envresult = dotenv.config();
|
||||
|
||||
if (envresult.error) {
|
||||
const err = envresult.error;
|
||||
|
||||
if (err.code == 'ENOENT') {
|
||||
console.log("FATAL: your .env file is missing!")
|
||||
process.exit(1);
|
||||
} else {
|
||||
throw envresult.error;
|
||||
}
|
||||
}
|
||||
dotenv.config();
|
||||
|
||||
const PORT = process.env.PORT || 8080;
|
||||
const MODE = process.env.NODE_ENV || 'development';
|
||||
|
|
@ -48,20 +37,20 @@ if (process.env.TRUST_PROXY) {
|
|||
await start_server_polling()
|
||||
|
||||
const pgSession = connectPg(session);
|
||||
|
||||
const sessionMiddleware= session({
|
||||
store: new pgSession({
|
||||
pool : db.pool,
|
||||
tableName : 'session'
|
||||
}),
|
||||
secret: process.env.COOKIE_SECRET, // changing this will invalidate all sessions
|
||||
resave: false, // dont bother saving unchanged sessions
|
||||
saveUninitialized: false, // dont bother saving sessions that have no data
|
||||
cookie: {
|
||||
httpOnly: true,
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000,
|
||||
//secure: true, // TODO: only send cookie over https
|
||||
} // 7 days
|
||||
|
||||
const sessionMiddleware = session({
|
||||
store: new pgSession({
|
||||
pool: db.pool,
|
||||
tableName: 'session'
|
||||
}),
|
||||
secret: process.env.COOKIE_SECRET, // changing this will invalidate all sessions
|
||||
resave: false, // dont bother saving unchanged sessions
|
||||
saveUninitialized: false, // dont bother saving sessions that have no data
|
||||
cookie: {
|
||||
httpOnly: true,
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000,
|
||||
//secure: true, // TODO: only send cookie over https
|
||||
} // 7 days
|
||||
})
|
||||
|
||||
// All API requests have a session. Other requests are static
|
||||
|
|
@ -77,7 +66,7 @@ if (process.env.TRUST_PROXY) {
|
|||
// redirect work properly. If the app makes it this far, it will be an Express 404
|
||||
app.use(express.static('public'));
|
||||
|
||||
app.listen(PORT, function() {
|
||||
app.listen(PORT, function () {
|
||||
let url = '';
|
||||
|
||||
if (MODE === 'development') {
|
||||
|
|
|
|||
63
package-lock.json
generated
63
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "psfportal",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -1484,6 +1484,28 @@
|
|||
"integrity": "sha512-pWRuser61Opj/LtzrkuRkmBcCYY1dvZ7jLu83rR7vIsTzFpmQoe1KcmMalwlN3rCq1VVHssGjY42SCSe2vEizQ==",
|
||||
"requires": {
|
||||
"pg": "^7.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"pg": {
|
||||
"version": "7.18.2",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-7.18.2.tgz",
|
||||
"integrity": "sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==",
|
||||
"requires": {
|
||||
"buffer-writer": "2.0.0",
|
||||
"packet-reader": "1.0.0",
|
||||
"pg-connection-string": "0.1.3",
|
||||
"pg-packet-stream": "^1.1.0",
|
||||
"pg-pool": "^2.0.10",
|
||||
"pg-types": "^2.1.0",
|
||||
"pgpass": "1.x",
|
||||
"semver": "4.3.2"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
|
||||
"integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c="
|
||||
}
|
||||
}
|
||||
},
|
||||
"console-browserify": {
|
||||
|
|
@ -5227,20 +5249,30 @@
|
|||
}
|
||||
},
|
||||
"pg": {
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-7.17.0.tgz",
|
||||
"integrity": "sha512-70Q4ZzIdPgwMPb3zUIzAUwigNJ4v5vsWdMED6OzXMfOECeYTvTm7iSC3FpKizu/R1BHL8Do3bLs6ltGfOTAnqg==",
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.2.0.tgz",
|
||||
"integrity": "sha512-EQeWKZv7qBTQZQa7EraR61AOi0bpizvlZLvrPdgAGaraX4YI+y40iQnL39XjPMXVnHOOG3jV6kAGtc0WSJn/+A==",
|
||||
"requires": {
|
||||
"buffer-writer": "2.0.0",
|
||||
"packet-reader": "1.0.0",
|
||||
"pg-connection-string": "0.1.3",
|
||||
"pg-packet-stream": "^1.1.0",
|
||||
"pg-pool": "^2.0.9",
|
||||
"pg-connection-string": "^2.2.2",
|
||||
"pg-pool": "^3.2.0",
|
||||
"pg-protocol": "^1.2.3",
|
||||
"pg-types": "^2.1.0",
|
||||
"pgpass": "1.x",
|
||||
"semver": "4.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"pg-connection-string": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.2.2.tgz",
|
||||
"integrity": "sha512-+hel4DGuSZCjCZwglAuyi+XlodHnKmrbyTw0hVWlmGN2o4AfJDkDo5obAFzblS5M5PFBMx0uDt5Y1QjlNC+tqg=="
|
||||
},
|
||||
"pg-pool": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.0.tgz",
|
||||
"integrity": "sha512-7BLwDNDEfPFjE9vmZLcJPLFwuDAVGZ5lIZo2MeQfwYG7EPGfdNVis/dz6obI/yKqvQIx2sf6QBKXMLB+y/ftgA=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
|
||||
|
|
@ -5269,9 +5301,14 @@
|
|||
"integrity": "sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg=="
|
||||
},
|
||||
"pg-pool": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.9.tgz",
|
||||
"integrity": "sha512-gNiuIEKNCT3OnudQM2kvgSnXsLkSpd6mS/fRnqs6ANtrke6j8OY5l9mnAryf1kgwJMWLg0C1N1cYTZG1xmEYHQ=="
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.10.tgz",
|
||||
"integrity": "sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg=="
|
||||
},
|
||||
"pg-protocol": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.3.tgz",
|
||||
"integrity": "sha512-erHFURS0mPmTbq18cn/zNL3Y4IzNCrU4sgCim0qy7zAPe3Vc0rvK5cImJR6lDvIaz3fJU2R1R9FNOlnUtyF10Q=="
|
||||
},
|
||||
"pg-types": {
|
||||
"version": "2.2.0",
|
||||
|
|
@ -6048,9 +6085,9 @@
|
|||
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
|
||||
},
|
||||
"postgres-date": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz",
|
||||
"integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA=="
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.5.tgz",
|
||||
"integrity": "sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA=="
|
||||
},
|
||||
"postgres-interval": {
|
||||
"version": "1.2.0",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
"express-session": "^1.17.0",
|
||||
"morgan": "^1.9.1",
|
||||
"page": "^1.11.5",
|
||||
"pg": "^7.15.1",
|
||||
"pg": "^8.2.0",
|
||||
"pg-error-constants": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue