Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions server/src/configs/custom-environment-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
"__name": "API_MAX_SESSIONS",
"__format": "number"
},
"sessionCheckIntervalMs": {
"__name": "API_SESSION_CHECK_INTERVAL_MS",
"__format": "number"
},
"cookieAgeDays": {
"__name": "API_COOKIE_AGE_DAYS",
"__format": "number"
Expand Down
1 change: 1 addition & 0 deletions server/src/configs/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"sessionSecret": "98ki^e72~!@#(85o3kXLI*#c9wu5l!Z",
"reactMapSecret": "",
"maxSessions": 5,
"sessionCheckIntervalMs": 900000,
"cookieAgeDays": 7,
"rateLimit": {
"time": 60,
Expand Down
38 changes: 21 additions & 17 deletions server/src/services/DbCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,28 @@ module.exports = class DbCheck {

async historicalRarity() {
console.log('[DB] Setting historical rarity stats')
const results = await Promise.all(
(this.models.Pokemon ?? []).map(async (source) =>
source.isMad
? []
: source.SubModel.query()
.select('pokemon_id', raw('SUM(count) as total'))
.from('pokemon_stats')
.groupBy('pokemon_id'),
),
)
this.setRarity(
results.map((result) =>
Object.fromEntries(
result.map((pkmn) => [`${pkmn.pokemon_id}`, +pkmn.total]),
try {
const results = await Promise.all(
(this.models.Pokemon ?? []).map(async (source) =>
source.isMad
? []
: source.SubModel.query()
.select('pokemon_id', raw('SUM(count) as total'))
.from('pokemon_stats')
.groupBy('pokemon_id'),
),
),
true,
)
)
this.setRarity(
results.map((result) =>
Object.fromEntries(
result.map((pkmn) => [`${pkmn.pokemon_id}`, +pkmn.total]),
),
),
true,
)
} catch (e) {
console.error('[DB] Failed to set historical rarity stats', e)
}
}

bindConnections(models) {
Expand Down
90 changes: 49 additions & 41 deletions server/src/services/sessionStore.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* eslint-disable no-console */

const session = require('express-session')
const mysql2 = require('mysql2/promise')
const MySQLStore = require('express-mysql-session')(session)
const {
api: { maxSessions },
api: { maxSessions, sessionCheckIntervalMs },
database: {
schemas,
settings: { sessionTableName },
Expand All @@ -13,55 +14,62 @@ const { Session } = require('../models/index')

const dbSelection = schemas.find(({ useFor }) => useFor?.includes('session'))

// MySQL session store
const sessionStore = new MySQLStore({
// Database server IP address/hostname
host: dbSelection.host,
// Database server listening port
port: dbSelection.port,
// Database username
user: dbSelection.username,
// Password for the above database user
password: dbSelection.password,
// Database name to save sessions table to
database: dbSelection.database,
// Whether or not to automatically check for and clear expired sessions:
clearExpired: true,
// How frequently expired sessions will be cleared; milliseconds:
checkExpirationInterval: 900000,
// Whether or not to create the sessions database table, if one does not already exist
createDatabaseTable: true,
// Set Sessions table name
schema: {
tableName: sessionTableName,
const sessionStore = new MySQLStore(
{
clearExpired: true,
checkExpirationInterval: sessionCheckIntervalMs,
createDatabaseTable: true,
schema: {
tableName: sessionTableName,
},
},
})
mysql2.createPool({
host: dbSelection.host,
port: dbSelection.port,
user: dbSelection.username,
password: dbSelection.password,
database: dbSelection.database,
}),
)

const isValidSession = async (userId) => {
const ts = Math.floor(new Date().getTime() / 1000)
const results = await Session.query()
.select('session_id')
.whereRaw(`json_extract(data, '$.passport.user.id') = ${userId}`)
.andWhere('expires', '>=', ts)
return results.length < maxSessions
try {
const ts = Math.floor(new Date().getTime() / 1000)
const results = await Session.query()
.select('session_id')
.whereRaw(`json_extract(data, '$.passport.user.id') = ${userId}`)
.andWhere('expires', '>=', ts)
return results.length < maxSessions
} catch (e) {
console.error('[SESSION] Unable to validate session', e)
return false
}
}

const clearOtherSessions = async (userId, currentSessionId) => {
const results = await Session.query()
.whereRaw(`json_extract(data, '$.passport.user.id') = ${userId}`)
.andWhere('session_id', '!=', currentSessionId || '')
.delete()
console.log('[Session] Clear Result:', results)
try {
const results = await Session.query()
.whereRaw(`json_extract(data, '$.passport.user.id') = ${userId}`)
.andWhere('session_id', '!=', currentSessionId || '')
.delete()
console.log('[Session] Clear Result:', results)
} catch (e) {
console.error('[SESSION] Unable to clear other sessions', e)
}
}

const clearDiscordSessions = async (discordId, botName) => {
const results = await Session.query()
.whereRaw(
`json_extract(data, '$.passport.user.discordId') = '${discordId}'`,
)
.orWhereRaw(`json_extract(data, '$.passport.user.id') = '${discordId}'`)
.delete()
console.log(`[Session${botName && ` - ${botName}`}] Clear Result:`, results)
try {
const results = await Session.query()
.whereRaw(
`json_extract(data, '$.passport.user.discordId') = '${discordId}'`,
)
.orWhereRaw(`json_extract(data, '$.passport.user.id') = '${discordId}'`)
.delete()
console.log(`[Session${botName && ` - ${botName}`}] Clear Result:`, results)
} catch (e) {
console.error('[SESSION] Unable to clear Discord sessions', e)
}
}

module.exports = {
Expand Down