filesafe/controllers/tokenController.js
Bobby Wibowo ff54f088bd
Added client assets update detection
/api/check and /api/token/verify will now pass along v1 version string
if used (when config.cacheControl is used) for both home.js and
dashboard.js to use to compare version strings.
This should help notify users using browsers with a bit more overbearing
caching (generally mobile browsers).

Rebuilt client assets and bumped v1 version string

Slight update to yarn.lock (a small syntax change for node-gyp, idk why)
2020-04-30 05:56:28 +07:00

102 lines
2.5 KiB
JavaScript

const randomstring = require('randomstring')
const perms = require('./permissionController')
const utils = require('./utilsController')
const config = require('./../config')
const logger = require('./../logger')
const db = require('knex')(config.database)
const self = {
tokenLength: 64,
tokenMaxTries: 3,
onHold: new Set()
}
self.generateUniqueToken = async () => {
for (let i = 0; i < self.tokenMaxTries; i++) {
const token = randomstring.generate(self.tokenLength)
if (self.onHold.has(token))
continue
// Put token on-hold (wait for it to be inserted to DB)
self.onHold.add(token)
const user = await db.table('users')
.where('token', token)
.select('id')
.first()
if (user) {
self.onHold.delete(token)
continue
}
return token
}
return null
}
self.verify = async (req, res, next) => {
const token = typeof req.body.token === 'string'
? req.body.token.trim()
: ''
if (!token)
return res.json({ success: false, description: 'No token provided.' })
try {
const user = await db.table('users')
.where('token', token)
.select('username', 'permission')
.first()
if (!user)
return res.json({ success: false, description: 'Invalid token.' })
const obj = {
success: true,
username: user.username,
permissions: perms.mapPermissions(user)
}
if (utils.clientVersion) obj.version = utils.clientVersion
return res.json(obj)
} catch (error) {
logger.error(error)
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
}
}
self.list = async (req, res, next) => {
const user = await utils.authorize(req, res)
if (!user) return
return res.json({ success: true, token: user.token })
}
self.change = async (req, res, next) => {
const user = await utils.authorize(req, res)
if (!user) return
const newToken = await self.generateUniqueToken()
if (!newToken)
return res.json({ success: false, description: 'Sorry, we could not allocate a unique token. Try again?' })
try {
await db.table('users')
.where('token', user.token)
.update({
token: newToken,
timestamp: Math.floor(Date.now() / 1000)
})
self.onHold.delete(newToken)
return res.json({
success: true,
token: newToken
})
} catch (error) {
logger.error(error)
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
}
}
module.exports = self