Skip to content
22 changes: 22 additions & 0 deletions config.sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@ db:
db: wiki
ssl: false

# Optional - How often (in ms) to clean up expired sessions from the DB (default: 86400000 = 1 day)
# sessionCleanupInterval: 86400000

# Optional - How often (in ms) the /healthz endpoint checks the DB (default: 14400000 = 4 hours)
# healthCheckInterval: 14400000

# ---------------------------------------------------------------------
# Analytics
# ---------------------------------------------------------------------

# analytics:
# Optional - How long (in seconds) to cache analytics config (default: 86400 = 1 day)
# cacheTTL: 86400

# ---------------------------------------------------------------------
# Authentication
# ---------------------------------------------------------------------

# auth:
# Optional - How long (in seconds) to cache deserialized users (default: 14400 = 4 hours, 0 to disable)
# userCacheTTL: 14400

# Optional - PostgreSQL / MySQL / MariaDB only:
# -> Uncomment lines you need below and set `auto` to false
# -> Full list of accepted options: https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options
Expand Down
8 changes: 8 additions & 0 deletions dev/build/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ db:
db: $(DB_NAME)
storage: $(DB_FILEPATH)
ssl: $(DB_SSL)
sessionCleanupInterval: $(DB_SESSION_CLEANUP_INTERVAL:60000)
healthCheckInterval: $(DB_HEALTH_CHECK_INTERVAL:14400000)
pool:
min: $(DB_POOL_MIN:2)
ssl:
enabled: $(SSL_ACTIVE)
port: 3443
Expand All @@ -18,3 +22,7 @@ ssl:
logLevel: $(LOG_LEVEL:info)
logFormat: $(LOG_FORMAT:default)
ha: $(HA_ACTIVE)
analytics:
cacheTTL: $(ANALYTICS_CACHE_TTL:86400)
auth:
userCacheTTL: $(AUTH_USER_CACHE_TTL:14400)
7 changes: 6 additions & 1 deletion server/app/data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ defaults:
storage: ./db.sqlite
sslOptions:
auto: true
sessionCleanupInterval: 60000
healthCheckInterval: 14400000
ssl:
enabled: false
pool:
min: 1
min: 2
bindIP: 0.0.0.0
logLevel: info
logFormat: default
Expand Down Expand Up @@ -61,6 +63,8 @@ defaults:
iconset: 'md'
darkMode: false
tocPosition: 'left'
analytics:
cacheTTL: 86400
auth:
autoLogin: false
enforce2FA: false
Expand All @@ -69,6 +73,7 @@ defaults:
audience: 'urn:wiki.js'
tokenExpiration: '30m'
tokenRenewal: '14d'
userCacheTTL: 14400
editShortcuts:
editFab: true
editMenuBar: false
Expand Down
10 changes: 0 additions & 10 deletions server/controllers/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ router.get('/robots.txt', (req, res, next) => {
}
})

/**
* Health Endpoint
*/
router.get('/healthz', (req, res, next) => {
if (WIKI.models.knex.client.pool.numFree() < 1 && WIKI.models.knex.client.pool.numUsed() < 1) {
res.status(503).json({ ok: false }).end()
} else {
res.status(200).json({ ok: true }).end()
}
})

/**
* Administration
Expand Down
11 changes: 11 additions & 0 deletions server/core/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = {
groups: {},
validApiKeys: [],
revocationList: require('./cache').init(),
userCache: require('./cache').init(),

/**
* Initialize the authentication module
Expand All @@ -34,10 +35,20 @@ module.exports = {

passport.deserializeUser(async (id, done) => {
try {
const ttl = WIKI.config.auth.userCacheTTL
if (ttl > 0) {
const cached = this.userCache.get(id)
if (cached !== undefined) {
return done(null, cached)
}
}
const user = await WIKI.models.users.query().findById(id).withGraphFetched('groups').modifyGraph('groups', builder => {
builder.select('groups.id', 'permissions')
})
if (user) {
if (ttl > 0) {
this.userCache.set(id, user, ttl)
}
done(null, user)
} else {
done(new Error(WIKI.lang.t('auth:errors:usernotfound')), null)
Expand Down
23 changes: 22 additions & 1 deletion server/master.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,26 @@ module.exports = async () => {

app.use('/', ctrl.ssl)

// ----------------------------------------
// Health Endpoint (before Passport to avoid DB queries on healthcheck)
// ----------------------------------------

let healthLastCheck = 0
let healthLastOk = false
app.get('/healthz', async (req, res) => {
const now = Date.now()
if (now - healthLastCheck > WIKI.config.db.healthCheckInterval) {
try {
await WIKI.models.knex.raw('SELECT 1')
healthLastOk = true
} catch (err) {
healthLastOk = false
}
healthLastCheck = now
}
res.status(healthLastOk ? 200 : 503).json({ ok: healthLastOk }).end()
})

// ----------------------------------------
// Passport Authentication
// ----------------------------------------
Expand All @@ -81,7 +101,8 @@ module.exports = async () => {
resave: false,
saveUninitialized: false,
store: new KnexSessionStore({
knex: WIKI.models.knex
knex: WIKI.models.knex,
clearInterval: WIKI.config.db.sessionCleanupInterval
})
}))
app.use(WIKI.auth.passport.initialize())
Expand Down
2 changes: 1 addition & 1 deletion server/models/analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ module.exports = class Analytics extends Model {
analyticsCode.bodyEnd += code.bodyEnd
}

await WIKI.cache.set('analytics', analyticsCode, 300)
await WIKI.cache.set('analytics', analyticsCode, WIKI.config.analytics.cacheTTL)

return analyticsCode
} catch (err) {
Expand Down