feat: hard-code prevent registering as "root"

and allow migration script to not throw when root user is missing

this facilitates safely removing root user altogether via database query
if you don't use it
This commit is contained in:
Bobby Wibowo 2022-08-08 06:22:18 +07:00
parent 493d2a8df3
commit d8b78d29ed
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
3 changed files with 24 additions and 5 deletions

View File

@ -162,6 +162,13 @@ self.register = async (req, res) => {
throw new ClientError(`Username must have ${self.user.min}-${self.user.max} characters.`)
}
// Please be advised that root user is hard-coded to always have superadmin permission
// However, you may choose to delete the root user via direct database query,
// so it is also hard-coded to always prevent it from being re-created via the API
if (username === 'root') {
throw new ClientError('Username is reserved.')
}
const password = typeof req.body.password === 'string'
? req.body.password.trim()
: ''
@ -245,6 +252,10 @@ self.createUser = async (req, res) => {
throw new ClientError(`Username must have ${self.user.min}-${self.user.max} characters.`)
}
if (username === 'root') {
throw new ClientError('Username is reserved.')
}
let password = typeof req.body.password === 'string'
? req.body.password.trim()
: ''
@ -270,7 +281,9 @@ self.createUser = async (req, res) => {
.where('username', username)
.first()
if (exists) throw new ClientError('Username already exists.')
if (exists) {
throw new ClientError('Username already exists.')
}
const hash = await bcrypt.hash(password, saltRounds)

View File

@ -15,7 +15,9 @@ self.keys = Object.freeze(Object.keys(self.permissions))
self.group = user => {
// root bypass
if (user.username === 'root') return 'superadmin'
if (user.username === 'root') {
return 'superadmin'
}
for (const key of self.keys) {
if (user.permission === self.permissions[key]) {
return key
@ -27,8 +29,12 @@ self.group = user => {
// returns true if user is in the group OR higher
self.is = (user, group) => {
// root bypass
if (user.username === 'root') return true
if (typeof group !== 'string' || !group) return false
if (user.username === 'root') {
return true
}
if (typeof group !== 'string' || !group) {
return false
}
const permission = user.permission || 0
return permission >= self.permissions[group]
}

View File

@ -55,7 +55,7 @@ const map = {
.where('username', 'root')
.select('permission')
.first()
if (root.permission !== perms.permissions.superadmin) {
if (root && root.permission !== perms.permissions.superadmin) {
await db.table('users')
.where('username', 'root')
.first()