mirror of
https://github.com/psforever/PSFPortal.git
synced 2026-03-09 07:20:28 +00:00
Enable foreign profile view
This commit is contained in:
parent
20946fdb43
commit
cb918033a6
14 changed files with 248 additions and 125 deletions
|
|
@ -47,7 +47,7 @@ api.post('/user/:user/add_gm', async (req, res, next) => {
|
|||
const account = req.user;
|
||||
|
||||
try {
|
||||
await db.update_account(account.id, {"gm" : true})
|
||||
await db.update_account(account.id, {[db.ACCOUNT.ADMIN] : true})
|
||||
res.status(200).json({});
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
|
|
@ -59,7 +59,7 @@ api.post('/user/:user/remove_gm', async (req, res, next) => {
|
|||
const account = req.user;
|
||||
|
||||
try {
|
||||
await db.update_account(account.id, {"gm" : false})
|
||||
await db.update_account(account.id, {[db.ACCOUNT.ADMIN] : false})
|
||||
res.status(200).json({});
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
|
|
@ -72,7 +72,7 @@ api.post('/user/:user/ban', async (req, res, next) => {
|
|||
|
||||
try {
|
||||
// also drop GM if they had it...
|
||||
await db.update_account(account.id, {"inactive" : true, "gm" : false})
|
||||
await db.update_account(account.id, {[db.ACCOUNT.BANNED] : true, [db.ACCOUNT.ADMIN] : false})
|
||||
res.status(200).json({});
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
|
|
@ -84,10 +84,9 @@ api.post('/user/:user/unban', async (req, res, next) => {
|
|||
const account = req.user;
|
||||
|
||||
try {
|
||||
await db.update_account(account.id, {"inactive" : false})
|
||||
await db.update_account(account.id, {[db.ACCOUNT.BANNED] : false})
|
||||
res.status(200).json({});
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
res.status(500).json({ message: 'error' });
|
||||
}
|
||||
|
||||
|
|
|
|||
90
api/db.js
90
api/db.js
|
|
@ -56,13 +56,59 @@ export const CHARACTER = Object.freeze({
|
|||
DELETED: Symbol("deleted"),
|
||||
});
|
||||
|
||||
export const LOGIN = Object.freeze({
|
||||
THIS: Symbol("logins"),
|
||||
ID: Symbol("id"),
|
||||
ACCOUNT_ID: Symbol("account_id"),
|
||||
});
|
||||
|
||||
function to_sql(symbol) {
|
||||
assert(typeof symbol == 'symbol')
|
||||
return String(symbol).slice(7,-1);
|
||||
}
|
||||
|
||||
async function get_row_count(table) {
|
||||
const resp = await pool.query(`SELECT COUNT(*) FROM ${to_sql(table)}`);
|
||||
function to_sql_kv(fields, idx=1) {
|
||||
let SQL = [];
|
||||
let values = [];
|
||||
|
||||
// This will ONLY get Symbols in the field dict
|
||||
assert(Object.getOwnPropertySymbols(fields).length > 0, "to_sql_kv must have at least one field")
|
||||
|
||||
Object.getOwnPropertySymbols(fields).forEach(key => {
|
||||
assert(typeof key == 'symbol')
|
||||
SQL.push(to_sql(key)+"=$"+idx++);
|
||||
values.push(fields[key]);
|
||||
});
|
||||
|
||||
return {
|
||||
sql: SQL,
|
||||
next_idx: idx,
|
||||
values: values,
|
||||
}
|
||||
}
|
||||
|
||||
function build_SET(fields, idx=1) {
|
||||
const kv = to_sql_kv(fields, idx);
|
||||
kv.sql = Symbol(kv.sql.join(", "));
|
||||
return kv;
|
||||
}
|
||||
|
||||
function build_WHERE(fields, idx=1) {
|
||||
const kv = to_sql_kv(fields, idx);
|
||||
kv.sql = Symbol(kv.sql.join(" AND "));
|
||||
return kv;
|
||||
}
|
||||
|
||||
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)} WHERE ${to_sql(where.sql)}`,
|
||||
where.values);
|
||||
} else {
|
||||
resp = await pool.query(`SELECT COUNT(*) FROM ${to_sql(table)}`);
|
||||
}
|
||||
return parseInt(resp.rows[0].count);
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +116,13 @@ export async function connect_to_db() {
|
|||
pool = new pg.Pool()
|
||||
try {
|
||||
const res = await pool.query('SELECT NOW()')
|
||||
|
||||
// Quick hack for query debugging (throws exception)
|
||||
const _query = pool.query;
|
||||
pool.query_log = (q, v) => {
|
||||
console.log("QUERY LOG: ", q, v);
|
||||
return _query(q, v);
|
||||
}
|
||||
console.log(`Connected to the psql database at ${process.env.PGHOST}`)
|
||||
} catch (e) {
|
||||
console.log("Unable to connect to the database: " + e.message);
|
||||
|
|
@ -80,9 +133,14 @@ 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_obj = account.rows[0];
|
||||
|
||||
if (account.rows.length == 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const account_obj = account.rows[0];
|
||||
delete account_obj.passhash;
|
||||
|
||||
return account_obj;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
|
|
@ -222,29 +280,16 @@ export async function create_account(username, password) {
|
|||
}
|
||||
}
|
||||
|
||||
function build_set(fields, idx=1) {
|
||||
let SQL = []
|
||||
let values = []
|
||||
|
||||
// TODO: sort for consistency
|
||||
Object.keys(fields).forEach(key => {
|
||||
SQL.push(key+"=$"+idx++)
|
||||
values.push(fields[key])
|
||||
});
|
||||
|
||||
return [SQL.join(", "), idx, values]
|
||||
}
|
||||
|
||||
export async function update_account(account_id, fields) {
|
||||
if (fields === {}) {
|
||||
return
|
||||
}
|
||||
|
||||
const set = build_set(fields);
|
||||
set[2].push(account_id)
|
||||
const set = build_SET(fields);
|
||||
set.values.push(account_id)
|
||||
|
||||
try {
|
||||
const update_result = await pool.query('UPDATE accounts SET ' + set[0] + ' WHERE id=$'+set[1],set[2]);
|
||||
const update_result = await pool.query(`UPDATE accounts SET ${to_sql(set.sql)} WHERE id=$${set.next_idx}`, set.values);
|
||||
return update_result.rowCount;
|
||||
} catch (e) {
|
||||
if (e.code)
|
||||
|
|
@ -287,9 +332,10 @@ export async function get_account_logins(account_id, pagination) {
|
|||
const values = [account_id, start_id, pagination.items_per_page];
|
||||
|
||||
try {
|
||||
const logins = await pool.query('SELECT * FROM logins WHERE account_id=$1 ORDER by login_time DESC ' +
|
||||
` OFFSET $2 LIMIT $3`, values);
|
||||
pagination.item_count = 100;
|
||||
const login_count = await get_row_count(LOGIN.THIS, { [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);
|
||||
|
||||
pagination.item_count = login_count;
|
||||
pagination.page_count = Math.ceil(pagination.item_count / pagination.items_per_page);
|
||||
|
||||
return logins.rows;
|
||||
|
|
|
|||
28
api/index.js
28
api/index.js
|
|
@ -20,13 +20,6 @@ if (process.env.NODE_ENV !== "production") {
|
|||
async function sessionRequired(req, res, next) {
|
||||
if (!req.session || !req.session.account_id) {
|
||||
res.status(403).json({message: 'session required'})
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
async function adminRequired(req, res, next) {
|
||||
if (!req.session || !req.session.account_id) {
|
||||
res.status(403).json({message: 'admin required'})
|
||||
} else {
|
||||
try {
|
||||
const account = await db.get_account_by_id(req.session.account_id);
|
||||
|
|
@ -35,11 +28,8 @@ async function adminRequired(req, res, next) {
|
|||
console.log("ERROR: failed to lookup account from session!")
|
||||
res.status(500).json({message: 'error'});
|
||||
} else {
|
||||
if (account.gm === true && account.inactive === false) {
|
||||
next();
|
||||
} else {
|
||||
res.status(403).json({message : 'admin required'})
|
||||
}
|
||||
req.session_account = account;
|
||||
next();
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
|
@ -47,6 +37,18 @@ async function adminRequired(req, res, next) {
|
|||
}
|
||||
}
|
||||
}
|
||||
async function adminRequired(req, res, next) {
|
||||
if (!req.session_account) {
|
||||
console.log("ERROR: sessionRequired needs to be called before adminRequired")
|
||||
res.status(500).json({message: ''})
|
||||
} else {
|
||||
if (req.session_account.gm === true && req.session_account.inactive === false) {
|
||||
next();
|
||||
} else {
|
||||
res.status(403).json({message : 'admin required'})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
api.use(bodyParser.json());
|
||||
api.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
|
@ -54,7 +56,7 @@ api.use(bodyParser.urlencoded({ extended: true }));
|
|||
api.use(api_auth)
|
||||
api.use(api_info)
|
||||
api.use(sessionRequired, api_user)
|
||||
api.use(adminRequired, api_admin)
|
||||
api.use(sessionRequired, adminRequired, api_admin)
|
||||
|
||||
api.post("/bad_route", async (req, res, next) => {
|
||||
console.log("BAD APP ROUTE:", req.body.route)
|
||||
|
|
|
|||
17
api/user.js
17
api/user.js
|
|
@ -16,10 +16,17 @@ api.get('/user', async (req, res, next) => {
|
|||
}
|
||||
});
|
||||
|
||||
api.get('/user/profile', async (req, res, next) => {
|
||||
api.get('/user/:user/profile', async (req, res, next) => {
|
||||
const target_account = req.user;
|
||||
|
||||
if (target_account.id !== req.session.account_id && !req.session_account.gm) {
|
||||
res.status(403).json({ message: 'not allowed to see for other users' });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const account = await db.get_account_by_id(req.session.account_id);
|
||||
const characters = await db.get_characters_by_account(req.session.account_id);
|
||||
const account = await db.get_account_by_id(target_account.id);
|
||||
const characters = await db.get_characters_by_account(target_account.id);
|
||||
|
||||
res.status(200).json({
|
||||
id : account.id,
|
||||
|
|
@ -36,19 +43,17 @@ api.get('/user/profile', async (req, res, next) => {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
api.get('/user/:user/logins', async (req, res, next) => {
|
||||
const account = req.user;
|
||||
const pagination = get_pagination(req);
|
||||
|
||||
if (account.id !== req.session.account_id) {
|
||||
if (account.id !== req.session.account_id && !req.session_account.gm) {
|
||||
res.status(403).json({ message: 'not allowed to see for other users' });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const logins = await db.get_account_logins(account.id, pagination)
|
||||
console.log(logins)
|
||||
res.status(200).json({ logins : logins, page: pagination});
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,13 @@ export function get_pagination(req) {
|
|||
}
|
||||
|
||||
export async function fetch_user_middleware(req, res, next, id) {
|
||||
id = parseInt(id);
|
||||
|
||||
if (id <= 0) {
|
||||
res.status(500).json({message: 'error'});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const account = await db.get_account_by_id(id);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue