mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-02-23 13:49:03 +00:00
refactor: generateUniqueToken -> getUniqueToken
this now matches lifecycle with similar functions in upload and album controllers also added a new util function .mask() for basic string masking
This commit is contained in:
parent
b7dcf30578
commit
4591b8bb42
@ -6,7 +6,6 @@ const perms = require('./permissionController')
|
||||
const tokens = require('./tokenController')
|
||||
const utils = require('./utilsController')
|
||||
const ClientError = require('./utils/ClientError')
|
||||
const ServerError = require('./utils/ServerError')
|
||||
const config = require('./../config')
|
||||
|
||||
// Don't forget to update min/max length of text inputs in auth.njk
|
||||
@ -96,10 +95,7 @@ self.register = async (req, res) => {
|
||||
|
||||
const hash = await bcrypt.hash(password, saltRounds)
|
||||
|
||||
const token = await tokens.generateUniqueToken()
|
||||
if (!token) {
|
||||
throw new ServerError('Failed to allocate a unique token. Try again?')
|
||||
}
|
||||
const token = await tokens.getUniqueToken(res)
|
||||
|
||||
await utils.db.table('users')
|
||||
.insert({
|
||||
@ -110,8 +106,8 @@ self.register = async (req, res) => {
|
||||
permission: perms.permissions.user,
|
||||
registration: Math.floor(Date.now() / 1000)
|
||||
})
|
||||
|
||||
utils.invalidateStatsCache('users')
|
||||
tokens.onHold.delete(token)
|
||||
|
||||
return res.json({ success: true, token })
|
||||
}
|
||||
@ -195,10 +191,7 @@ self.createUser = async (req, res) => {
|
||||
|
||||
const hash = await bcrypt.hash(password, saltRounds)
|
||||
|
||||
const token = await tokens.generateUniqueToken()
|
||||
if (!token) {
|
||||
throw new ServerError('Failed to allocate a unique token. Try again?')
|
||||
}
|
||||
const token = await tokens.getUniqueToken(res)
|
||||
|
||||
await utils.db.table('users')
|
||||
.insert({
|
||||
@ -209,8 +202,8 @@ self.createUser = async (req, res) => {
|
||||
permission,
|
||||
registration: Math.floor(Date.now() / 1000)
|
||||
})
|
||||
|
||||
utils.invalidateStatsCache('users')
|
||||
tokens.onHold.delete(token)
|
||||
|
||||
return res.json({ success: true, username, password, group })
|
||||
}
|
||||
|
@ -3,17 +3,23 @@ const perms = require('./permissionController')
|
||||
const utils = require('./utilsController')
|
||||
const ClientError = require('./utils/ClientError')
|
||||
const ServerError = require('./utils/ServerError')
|
||||
const logger = require('./../logger')
|
||||
|
||||
const self = {
|
||||
tokenLength: 64,
|
||||
tokenMaxTries: 3,
|
||||
onHold: new Set()
|
||||
|
||||
onHold: new Set() // temporarily held random tokens
|
||||
}
|
||||
|
||||
self.generateUniqueToken = async () => {
|
||||
self.getUniqueToken = async res => {
|
||||
for (let i = 0; i < self.tokenMaxTries; i++) {
|
||||
const token = randomstring.generate(self.tokenLength)
|
||||
if (self.onHold.has(token)) continue
|
||||
|
||||
if (self.onHold.has(token)) {
|
||||
logger.debug(`Token ${utils.mask(token)} is currently held by another request (${i + 1}/${utils.idMaxTries}).`)
|
||||
continue
|
||||
}
|
||||
|
||||
// Put token on-hold (wait for it to be inserted to DB)
|
||||
self.onHold.add(token)
|
||||
@ -24,13 +30,36 @@ self.generateUniqueToken = async () => {
|
||||
.first()
|
||||
if (user) {
|
||||
self.onHold.delete(token)
|
||||
logger.debug(`User with token ${utils.mask(token)} already exists (${i + 1}/${utils.idMaxTries}).`)
|
||||
continue
|
||||
}
|
||||
|
||||
// Unhold token once the Response has been sent
|
||||
if (res) {
|
||||
// Keep in an array for future-proofing
|
||||
// if a single Request needs to generate multiple tokens
|
||||
if (!res.locals.tokens) {
|
||||
res.locals.tokens = []
|
||||
res.once('finish', () => { self.unholdTokens(res) })
|
||||
}
|
||||
res.locals.tokens.push(token)
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
return null
|
||||
throw new ServerError('Failed to allocate a unique token. Try again?')
|
||||
}
|
||||
|
||||
self.unholdTokens = res => {
|
||||
if (!res.locals.tokens) return
|
||||
|
||||
for (const token of res.locals.tokens) {
|
||||
self.onHold.delete(token)
|
||||
logger.debug(`Unheld token ${utils.mask(token)}.`)
|
||||
}
|
||||
|
||||
delete res.locals.tokens
|
||||
}
|
||||
|
||||
self.verify = async (req, res) => {
|
||||
@ -84,10 +113,7 @@ self.list = async (req, res) => {
|
||||
self.change = async (req, res) => {
|
||||
const user = await utils.authorize(req, 'token')
|
||||
|
||||
const newToken = await self.generateUniqueToken()
|
||||
if (!newToken) {
|
||||
throw new ServerError('Failed to allocate a unique token. Try again?')
|
||||
}
|
||||
const newToken = await self.getUniqueToken(res)
|
||||
|
||||
await utils.db.table('users')
|
||||
.where('token', user.token)
|
||||
@ -95,7 +121,6 @@ self.change = async (req, res) => {
|
||||
token: newToken,
|
||||
timestamp: Math.floor(Date.now() / 1000)
|
||||
})
|
||||
self.onHold.delete(newToken)
|
||||
|
||||
return res.json({ success: true, token: newToken })
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ self.escape = string => {
|
||||
}
|
||||
|
||||
self.stripIndents = string => {
|
||||
if (!string) return
|
||||
if (!string) return string
|
||||
const result = string.replace(/^[^\S\n]+/gm, '')
|
||||
const match = result.match(/^[^\S\n]*(?=\S)/gm)
|
||||
const indent = match && Math.min(...match.map(el => el.length))
|
||||
@ -373,6 +373,19 @@ self.stripIndents = string => {
|
||||
return result
|
||||
}
|
||||
|
||||
self.mask = string => {
|
||||
if (!string) return string
|
||||
const max = Math.min(Math.floor(string.length / 2), 8)
|
||||
const fragment = Math.floor(max / 2)
|
||||
if (string.length <= fragment) {
|
||||
return '*'.repeat(string.length)
|
||||
} else {
|
||||
return string.substring(0, fragment) +
|
||||
'*'.repeat(Math.min(string.length - (fragment * 2), 4)) +
|
||||
string.substring(string.length - fragment)
|
||||
}
|
||||
}
|
||||
|
||||
self.assertRequestType = (req, type) => {
|
||||
if (!req.is(type)) {
|
||||
throw new ClientError(`Request Content-Type must be ${type}.`)
|
||||
|
Loading…
Reference in New Issue
Block a user