Skip to content

Commit

Permalink
Enable eslint and standard ruleset
Browse files Browse the repository at this point in the history
  • Loading branch information
taylortom committed Mar 20, 2023
1 parent 18d96c5 commit 87771ea
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 60 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
14 changes: 14 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"env": {
"browser": false,
"node": true,
"commonjs": false,
"es2020": true
},
"extends": [
"standard"
],
"parserOptions": {
"ecmaVersion": 2020
}
}
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
/**
* User role functionality
* @namespace roles
*/
export { default } from './lib/RolesModule.js';
export { default } from './lib/RolesModule.js'
121 changes: 63 additions & 58 deletions lib/RolesModule.js
Original file line number Diff line number Diff line change
@@ -1,111 +1,116 @@
import AbstractApiModule from 'adapt-authoring-api';
import AbstractApiModule from 'adapt-authoring-api'
/**
* Module which handles user roles
* @memberof roles
* @extends {AbstractApiModule}
*/
class RolesModule extends AbstractApiModule {
/** @override */
async init() {
await super.init();
async init () {
await super.init()
try {
await this.initConfigRoles();
await this.initConfigRoles()

const hasRoles = this.getConfig('defaultRolesForAuthTypes').length || this.getConfig('defaultRoles').length;
if(hasRoles) await this.initDefaultRoles();
} catch(e) {
this.log('error', e);
const hasRoles = this.getConfig('defaultRolesForAuthTypes').length || this.getConfig('defaultRoles').length
if (hasRoles) await this.initDefaultRoles()
} catch (e) {
this.log('error', e)
}
const [localauth, users] = await this.app.waitForModule('localauth', 'users');
localauth.registerHook.tap(this.onUpdateRoles.bind(this));
users.requestHook.tap(this.onUpdateRoles.bind(this));
const [localauth, users] = await this.app.waitForModule('localauth', 'users')
localauth.registerHook.tap(this.onUpdateRoles.bind(this))
users.requestHook.tap(this.onUpdateRoles.bind(this))
}

/**
* Adds any role definitions from the current config file to the database
* @return {Promise}
*/
async initConfigRoles() {
const mongodb = await this.app.waitForModule('mongodb');
async initConfigRoles () {
const mongodb = await this.app.waitForModule('mongodb')
return Promise.allSettled(this.getConfig('roleDefinitions').map(async r => {
const [doc] = await this.find({ shortName: r.shortName });
if(doc) {
const [doc] = await this.find({ shortName: r.shortName })
if (doc) {
try {
await mongodb.replace(this.collectionName, { _id: doc._id }, r);
this.log('debug', 'REPLACE', this.schemaName, r.shortName);
} catch(e) {
if(e.code !== 11000) this.log('warn', `failed to update '${r.shortName}' role, ${e.message}`);
await mongodb.replace(this.collectionName, { _id: doc._id }, r)
this.log('debug', 'REPLACE', this.schemaName, r.shortName)
} catch (e) {
if (e.code !== 11000) this.log('warn', `failed to update '${r.shortName}' role, ${e.message}`)
}
return;
return
}
try {
await this.insert(r);
this.log('debug', 'INSERT', this.schemaName, r.shortName);
} catch(e) {
if(e.code !== 11000) this.log('warn', `failed to add '${r.shortName}' role, ${e.message}`);
await this.insert(r)
this.log('debug', 'INSERT', this.schemaName, r.shortName)
} catch (e) {
if (e.code !== 11000) this.log('warn', `failed to add '${r.shortName}' role, ${e.message}`)
}
}));
}))
}

/**
* Adds the specified default roles during new user creation
* @return {Promise}
*/
async shortNamesToIds(roles) {
async shortNamesToIds (roles) {
return Promise.all(roles.map(async r => {
let role = this.roleCache[r];
if(!role) {
[role] = await this.find({ shortName: r });
this.roleCache[r] = role;
let role = this.roleCache[r]
if (!role) {
[role] = await this.find({ shortName: r })
this.roleCache[r] = role
}
return role._id.toString();
}));
return role._id.toString()
}))
}

/**
* Handles setting defined default roles when new users are added
* @return {Promise}
*/
async initDefaultRoles() {
async initDefaultRoles () {
/**
* Local store of roles
* @type {Object}
*/
this.roleCache = {};
this.roleCache = {}

const rolesforAll = await this.shortNamesToIds(this.getConfig('defaultRoles'));
const rolesForAuth = Object.entries(this.getConfig('defaultRolesForAuthTypes')).reduce((m,[k,v]) => {
return { [m[k]]: this.shortNamesToIds(v) };
}, {});
const users = await this.app.waitForModule('users');
const rolesforAll = await this.shortNamesToIds(this.getConfig('defaultRoles'))
const rolesForAuth = Object.entries(this.getConfig('defaultRolesForAuthTypes')).reduce((m, [k, v]) => {
return { [m[k]]: this.shortNamesToIds(v) }
}, {})
const users = await this.app.waitForModule('users')
users.preInsertHook.tap(data => {
if(!data.roles || !data.roles.length) {
data.roles = rolesForAuth[data.authType] || rolesforAll || [];
if (!data.roles || !data.roles.length) {
data.roles = rolesForAuth[data.authType] || rolesforAll || []
}
});
})
}

/** @override */
async setValues() {
/** @ignore */ this.root = 'roles';
/** @ignore */ this.schemaName = 'role';
/** @ignore */ this.collectionName = 'roles';
this.useDefaultRouteConfig();
async setValues () {
/** @ignore */ this.root = 'roles'
/** @ignore */ this.schemaName = 'role'
/** @ignore */ this.collectionName = 'roles'
this.useDefaultRouteConfig()
}

/**
* Handler for requests which attempt to update roles
* @param {external:ExpressRequest} req
* @param {external:ExpressRequest} req
* @returns {Promise}
*/
async onUpdateRoles(req) {
if(!req.body.roles || req.method === 'GET' || req.method === 'DELETE') {
return;
async onUpdateRoles (req) {
if (!req.body.roles || req.method === 'GET' || req.method === 'DELETE') {
return
}
if(!req.auth.isSuper && !req.auth.scopes.includes('assign:roles')) {
this.log('error', 'User does not have the correct permissions to assign user roles');
throw this.app.errors.UNAUTHORISED;
if (!req.auth.isSuper && !req.auth.scopes.includes('assign:roles')) {
this.log('error', 'User does not have the correct permissions to assign user roles')
throw this.app.errors.UNAUTHORISED
}
if(req.method !== 'POST') {
const auth = await this.app.waitForModule('auth');
await auth.authentication.disavowUser({ userId: req.params._id || req.body._id });
if (req.method !== 'POST') {
const auth = await this.app.waitForModule('auth')
await auth.authentication.disavowUser({ userId: req.params._id || req.body._id })
}
}
}

export default RolesModule;
export default RolesModule
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@
"peerDependencies": {
"adapt-authoring-api": "github:adapt-security/adapt-authoring-api",
"adapt-authoring-core": "github:adapt-security/adapt-authoring-core"
},
"devDependencies": {
"eslint": "^8.36.0",
"standard": "^17.0.0"
}
}

0 comments on commit 87771ea

Please sign in to comment.