Skip to content

Commit

Permalink
Merge branch 'minor' into minor
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderGeere authored Nov 13, 2024
2 parents 3859e3f + 2024bfa commit 0338fef
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 49 deletions.
91 changes: 52 additions & 39 deletions mod/utils/roles.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,42 +74,44 @@ function check(obj, user_roles) {
}

/**
* Recursively merges role-specific object properties based on user roles
* @param {Object} obj - The object to process
* @param {roles} obj.roles - Role configuration object
* @param {Array<string>} user_roles - Array of roles assigned to the user
* @returns {Object} Processed object with merged role-specific properties
*
* @example
* const obj = {
* name: 'layer',
* roles: {
* admin: { secretField: 'sensitive' },
* user: { publicField: 'visible' }
* }
* };
*
* // With admin role
* objMerge(obj, ['admin']);
* // Returns: { name: 'layer', secretField: 'sensitive', roles: {...} }
*
* // With user role
* objMerge(obj, ['user']);
* // Returns: { name: 'layer', publicField: 'visible', roles: {...} }
*
* @description
* The function handles several special cases:
* - Recursively processes nested objects
* - Handles arrays by mapping over their elements
* - Processes negated roles (prefixed with '!')
* - Preserves the original object if conditions aren't met
* - Skip null or undefined values
*/
@function objMerge
@description
Recursively merges role-specific object properties based on user roles.
The function handles several special cases:
- Recursively processes nested objects
- Handles arrays by mapping over their elements
- Processes negated roles (prefixed with '!')
- Preserves the original object if conditions aren't met
- Skip null or undefined values
```js
const obj = {
name: 'layer',
roles: {
admin: { secretField: 'sensitive' },
user: { publicField: 'visible' }
}
};
// With admin role
objMerge(obj, ['admin']);
// Returns: { name: 'layer', secretField: 'sensitive', roles: {...} }
// With user role
objMerge(obj, ['user']);
// Returns: { name: 'layer', publicField: 'visible', roles: {...} }
```
@param {Object} obj The object to process
@param {Array<string>} user_roles Array of roles assigned to the user
@property {roles} obj.roles Role configuration object
@returns {Object} Processed object with merged role-specific properties
*/
function objMerge(obj, user_roles) {

if (typeof obj !== 'object') return obj;

if (!user_roles) return obj
if (!Array.isArray(user_roles)) return obj

if (Array.isArray(obj)) {

Expand All @@ -136,13 +138,6 @@ function objMerge(obj, user_roles) {

const clone = structuredClone(obj)

function notIncludesNegatedRole(role, user_roles) {

return role.match(/(?<=^!)(.*)/g)?.[0] ?
!user_roles.includes(role.match(/(?<=^!)(.*)/g)?.[0]) :
false
}

Object.keys(clone.roles)
.filter(role => clone.roles[role] !== true)
.filter(role => clone.roles[role] !== null)
Expand All @@ -154,4 +149,22 @@ function objMerge(obj, user_roles) {
})

return clone
}

/**
@function notIncludesNegatedRole
@description
The utility method checks whether a negated role [prefixed with an exclamation mark !] is not included in the array of user roles.
@param {String} role A role name
@param {Array<string>} user_roles Array of roles assigned to the user
@returns {Boolean} True if the negated role is not included in the user_roles array.
*/
function notIncludesNegatedRole(role, user_roles) {

// A negated role is prefixes with an exclamation mark.
return role.match(/(?<=^!)(.*)/g)?.[0] ?
!user_roles.includes(role.match(/(?<=^!)(.*)/g)?.[0]) :
false
}
21 changes: 11 additions & 10 deletions mod/workspace/_workspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ async function layer(req, res) {
return res.status(400).send(layer.message)
}

res.json(layer)
res.json(removeRoles(layer))
}

/**
Expand Down Expand Up @@ -452,14 +452,14 @@ function templateUse(obj, test) {
}

/**
* @function removeRoles
* @description
* Recursively removes all 'roles' objects from the provided locale.
* This function is designed to sanitize locale configuration objects before sending to the client,
* ensuring that role-based permissions data is not exposed.
* @param {object} obj
* @returns {object}
*/
@function removeRoles
@description
Recursively removes all 'roles' objects from the provided object [locale, layer].
This function is designed to sanitize locale configuration objects before sending to the client,
ensuring that role-based permissions data is not exposed.
@param {object} obj A locale or layer JSON object.
@returns {object}
*/
function removeRoles(obj) {

// If param is not an object or is null, return as is
Expand All @@ -477,6 +477,7 @@ function removeRoles(obj) {

// Process each property in the object
for (const [key, value] of Object.entries(obj)) {

// Skip 'roles' properties
if (key === 'roles') {
continue;
Expand All @@ -487,4 +488,4 @@ function removeRoles(obj) {
}

return cleanedObj;
}
}

0 comments on commit 0338fef

Please sign in to comment.