-
-
Save ebarault/e7218a9c66bab0539ecf672346e798dd to your computer and use it in GitHub Desktop.
LoopBack 3 boot script for protecting userId properties on custom models
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* Add before safe hook and validation to all custom models with an userId property to prevent changing userId | |
* properties by non-admin users. | |
*/ | |
const USER_ID_PROPERTY = 'userId'; | |
const INVALID_USER_ID = -1; | |
function getBeforeSaveHook(app) { | |
return (ctx, next) => { | |
const accessToken = ctx.options.accessToken; | |
const userId = accessToken && accessToken.userId; | |
const data = ctx.instance || ctx.data; | |
if (data.hasOwnProperty(USER_ID_PROPERTY) && data.userId !== userId) { | |
const Role = app.models.Role; | |
const RoleMapping = app.models.RoleMapping; | |
Role.isInRole('admin', { principalType: RoleMapping.USER, principalId: userId }, (err, isInRole) => { | |
if (err) return next(err); | |
if (!isInRole) data.userId = INVALID_USER_ID; | |
next(); | |
}); | |
} else { | |
next(); | |
} | |
}; | |
} | |
module.exports = function(app) { | |
const builtInModels = ['User', 'AccessToken', 'ACL', 'RoleMapping', 'Role']; | |
const patchedModels = []; | |
for (let model in app.models) { | |
if (!app.models.hasOwnProperty(model)) continue; | |
// Don't patch in-built models. | |
if (builtInModels.indexOf(model) !== -1) continue; | |
model = app.models[model]; | |
// Patch models only once. | |
if (patchedModels.indexOf(model) !== -1) continue; | |
if (model.definition.properties[USER_ID_PROPERTY]) { | |
model.observe('before save', getBeforeSaveHook(app)); | |
model.validatesExclusionOf(USER_ID_PROPERTY, { in: [INVALID_USER_ID], message: 'Invalid userId.' }); | |
patchedModels.push(model); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment