diff --git a/api/db.js b/api/db.js index 2753f30..8c8ec4f 100644 --- a/api/db.js +++ b/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; diff --git a/api/info.js b/api/info.js index aeeedeb..5fb0e81 100644 --- a/api/info.js +++ b/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' }); } }); diff --git a/api/user.js b/api/user.js index 39da8ae..6ade53e 100644 --- a/api/user.js +++ b/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' }); diff --git a/index.js b/index.js index efb2c73..f936c53 100644 --- a/index.js +++ b/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') { diff --git a/package-lock.json b/package-lock.json index ce54752..a3faf82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index c61211e..a3f2d0a 100644 --- a/package.json +++ b/package.json @@ -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": {