adapt-authoring-roles 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/releases.yml +9 -2
- package/lib/RolesModule.js +31 -29
- package/package.json +9 -9
|
@@ -3,10 +3,16 @@ on:
|
|
|
3
3
|
push:
|
|
4
4
|
branches:
|
|
5
5
|
- master
|
|
6
|
+
|
|
6
7
|
jobs:
|
|
7
8
|
release:
|
|
8
9
|
name: Release
|
|
9
10
|
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write # to be able to publish a GitHub release
|
|
13
|
+
issues: write # to be able to comment on released issues
|
|
14
|
+
pull-requests: write # to be able to comment on released pull requests
|
|
15
|
+
id-token: write # to enable use of OIDC for trusted publishing and npm provenance
|
|
10
16
|
steps:
|
|
11
17
|
- name: Checkout
|
|
12
18
|
uses: actions/checkout@v3
|
|
@@ -16,10 +22,11 @@ jobs:
|
|
|
16
22
|
uses: actions/setup-node@v3
|
|
17
23
|
with:
|
|
18
24
|
node-version: 'lts/*'
|
|
25
|
+
- name: Update npm
|
|
26
|
+
run: npm install -g npm@latest
|
|
19
27
|
- name: Install dependencies
|
|
20
28
|
run: npm ci
|
|
21
29
|
- name: Release
|
|
22
30
|
env:
|
|
23
31
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
24
|
-
|
|
25
|
-
run: npx semantic-release
|
|
32
|
+
run: npx semantic-release
|
package/lib/RolesModule.js
CHANGED
|
@@ -8,6 +8,7 @@ class RolesModule extends AbstractApiModule {
|
|
|
8
8
|
/** @override */
|
|
9
9
|
async init () {
|
|
10
10
|
await super.init()
|
|
11
|
+
this.cache.isEnabled = true
|
|
11
12
|
try {
|
|
12
13
|
await this.initConfigRoles()
|
|
13
14
|
|
|
@@ -54,11 +55,7 @@ class RolesModule extends AbstractApiModule {
|
|
|
54
55
|
*/
|
|
55
56
|
async shortNamesToIds (roles) {
|
|
56
57
|
return Promise.all(roles.map(async r => {
|
|
57
|
-
|
|
58
|
-
if (!role) {
|
|
59
|
-
[role] = await this.find({ shortName: r })
|
|
60
|
-
this.roleCache[r] = role
|
|
61
|
-
}
|
|
58
|
+
const [role] = await this.find({ shortName: r })
|
|
62
59
|
return role._id.toString()
|
|
63
60
|
}))
|
|
64
61
|
}
|
|
@@ -84,12 +81,6 @@ class RolesModule extends AbstractApiModule {
|
|
|
84
81
|
* @return {Promise}
|
|
85
82
|
*/
|
|
86
83
|
async initDefaultRoles () {
|
|
87
|
-
/**
|
|
88
|
-
* Local store of roles
|
|
89
|
-
* @type {Object}
|
|
90
|
-
*/
|
|
91
|
-
this.roleCache = {}
|
|
92
|
-
|
|
93
84
|
const rolesforAll = await this.shortNamesToIds(this.getConfig('defaultRoles'))
|
|
94
85
|
const rolesForAuth = Object.entries(this.getConfig('defaultRolesForAuthTypes')).reduce((m, [k, v]) => {
|
|
95
86
|
return { [m[k]]: this.shortNamesToIds(v) }
|
|
@@ -116,12 +107,23 @@ class RolesModule extends AbstractApiModule {
|
|
|
116
107
|
* @returns {Promise}
|
|
117
108
|
*/
|
|
118
109
|
async onUpdateRoles (req) {
|
|
119
|
-
if (
|
|
110
|
+
if (req.apiData?.modifying !== false || (req.method !== 'DELETE' && !req.apiData?.data.roles)) {
|
|
120
111
|
return
|
|
121
112
|
}
|
|
122
|
-
if (!req.auth.isSuper
|
|
123
|
-
|
|
124
|
-
|
|
113
|
+
if (!req.auth.isSuper) {
|
|
114
|
+
const reject = reason => {
|
|
115
|
+
this.log('error', 'UNAUTHORISED', req.auth.user._id.toString(), reason)
|
|
116
|
+
throw this.app.errors.UNAUTHORISED
|
|
117
|
+
}
|
|
118
|
+
if (!req.auth.scopes.includes('assign:roles')) {
|
|
119
|
+
reject('assign role')
|
|
120
|
+
}
|
|
121
|
+
if (req.apiData.data.roles.includes(await this.getSuperRoleId())) {
|
|
122
|
+
reject('assign superuser')
|
|
123
|
+
}
|
|
124
|
+
if (await this.isTargetSuper(req.apiData.query._id)) {
|
|
125
|
+
reject('modify superuser')
|
|
126
|
+
}
|
|
125
127
|
}
|
|
126
128
|
if (req.method !== 'POST') {
|
|
127
129
|
const auth = await this.app.waitForModule('auth')
|
|
@@ -129,22 +131,22 @@ class RolesModule extends AbstractApiModule {
|
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
* @param {external:ExpressRequest} req
|
|
135
|
-
* @param {Object} data Request data
|
|
136
|
-
*/
|
|
137
|
-
async onCheckUserAccess (req, data) {
|
|
138
|
-
if (['GET', 'POST'].includes(req.method)) {
|
|
139
|
-
return true
|
|
140
|
-
}
|
|
141
|
-
const users = await this.app.waitForModule('users')
|
|
142
|
-
const [user] = await users.find({ _id: req.apiData.query._id })
|
|
143
|
-
const scopes = user.roles.length === 1 ? await this.getScopesForRole(user.roles[0]) : []
|
|
144
|
-
const isSuper = scopes.length === 1 && scopes[0] === '*:*'
|
|
145
|
-
if (isSuper && !req.auth.isSuper) {
|
|
134
|
+
async onCheckUserAccess (req) { // note access checks don't run for super users
|
|
135
|
+
if (req.apiData.modifying && await this.isTargetSuper(req.apiData.query._id)) {
|
|
146
136
|
throw this.app.errors.UNAUTHORISED
|
|
147
137
|
}
|
|
138
|
+
return true
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async getSuperRoleId () {
|
|
142
|
+
const [superRole] = await this.find({ scopes: ['*:*'] })
|
|
143
|
+
return superRole._id.toString()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async isTargetSuper (_id) {
|
|
147
|
+
const users = await this.app.waitForModule('users')
|
|
148
|
+
const [user] = await users.find({ _id }, { projection: { roles: 1 } })
|
|
149
|
+
return user.roles.length === 1 && user.roles[0].toString() === await this.getSuperRoleId()
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
152
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adapt-authoring-roles",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Module for managing user roles",
|
|
5
5
|
"homepage": "https://github.com/adapt-security/adapt-authoring-roles",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
"adapt-authoring-core": "github:adapt-security/adapt-authoring-core"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"
|
|
16
|
-
"@semantic-release/commit-analyzer": "^9.0.2",
|
|
15
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
17
16
|
"@semantic-release/git": "^10.0.1",
|
|
18
|
-
"@semantic-release/github": "^
|
|
19
|
-
"@semantic-release/npm": "^
|
|
20
|
-
"@semantic-release/release-notes-generator": "^
|
|
21
|
-
"conventional-changelog-eslint": "^
|
|
22
|
-
"semantic-release": "^
|
|
23
|
-
"semantic-release-replace-plugin": "^1.2.7"
|
|
17
|
+
"@semantic-release/github": "^12.0.2",
|
|
18
|
+
"@semantic-release/npm": "^13.1.2",
|
|
19
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
20
|
+
"conventional-changelog-eslint": "^6.0.0",
|
|
21
|
+
"semantic-release": "^25.0.2",
|
|
22
|
+
"semantic-release-replace-plugin": "^1.2.7",
|
|
23
|
+
"standard": "^17.1.0"
|
|
24
24
|
},
|
|
25
25
|
"release": {
|
|
26
26
|
"plugins": [
|