@nitra/cf-security 3.0.0 → 3.1.0
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/README.md +14 -0
- package/package.json +23 -6
- package/src/index.js +7 -5
- package/src/jwt.js +47 -0
- package/super-linter.log +0 -2533
package/README.md
CHANGED
|
@@ -17,3 +17,17 @@ exports.function = async (req, res) => {
|
|
|
17
17
|
return
|
|
18
18
|
}
|
|
19
19
|
```
|
|
20
|
+
|
|
21
|
+
```HTTP
|
|
22
|
+
ALLOWED_ROLES: role1,role2
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```JavaScript
|
|
26
|
+
import runSecurity from '@nitra/cf-security'
|
|
27
|
+
|
|
28
|
+
exports.function = async (req, res) => {
|
|
29
|
+
if (!runSecurity(req)) {
|
|
30
|
+
res.send(`Nitra security not passed`)
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
```
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitra/cf-security",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "check header in cloud functions",
|
|
5
|
-
"main": "src/index.js",
|
|
6
5
|
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/index.js",
|
|
8
|
+
"./jwt": "./src/jwt.js"
|
|
9
|
+
},
|
|
7
10
|
"scripts": {
|
|
8
|
-
"fix": "npx
|
|
11
|
+
"fix": "npx eslint --fix . && npx prettier --write . ",
|
|
9
12
|
"test": "env $(cat ./test/.env) npx coverage-node test/index.js"
|
|
10
13
|
},
|
|
11
14
|
"repository": {
|
|
@@ -18,13 +21,27 @@
|
|
|
18
21
|
"url": "https://github.com/nitra/cf-security/issues"
|
|
19
22
|
},
|
|
20
23
|
"homepage": "https://github.com/nitra/cf-security#readme",
|
|
21
|
-
"prettier": "prettier-config
|
|
24
|
+
"prettier": "@nitra/prettier-config",
|
|
25
|
+
"eslintConfig": {
|
|
26
|
+
"extends": [
|
|
27
|
+
"@nitra/eslint-config/node"
|
|
28
|
+
],
|
|
29
|
+
"root": true
|
|
30
|
+
},
|
|
22
31
|
"devDependencies": {
|
|
23
|
-
"
|
|
32
|
+
"@nitra/eslint-config": "^1.0.9",
|
|
33
|
+
"@nitra/prettier-config": "^1.0.1",
|
|
24
34
|
"test-director": "^7.0.0"
|
|
25
35
|
},
|
|
26
36
|
"dependencies": {
|
|
37
|
+
"@nitra/bunyan": "^1.1.1",
|
|
27
38
|
"@nitra/check-env": "^2.0.1",
|
|
28
|
-
"@nitra/
|
|
39
|
+
"@nitra/jwt": "^3.1.2"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"src"
|
|
43
|
+
],
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=16.0.0"
|
|
29
46
|
}
|
|
30
47
|
}
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import getLogger from '@nitra/bunyan/trace'
|
|
2
2
|
import checkEnv from '@nitra/check-env'
|
|
3
3
|
checkEnv(['X_NITRA_CF_KEY'])
|
|
4
4
|
|
|
@@ -9,23 +9,25 @@ checkEnv(['X_NITRA_CF_KEY'])
|
|
|
9
9
|
* @return {boolean} if check passed
|
|
10
10
|
*/
|
|
11
11
|
export const cfSecurity = req => {
|
|
12
|
+
const log = getLogger(req)
|
|
13
|
+
|
|
12
14
|
if (typeof req.headers === 'undefined') {
|
|
13
|
-
|
|
15
|
+
log.info('Request without headers')
|
|
14
16
|
return false
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
if (typeof req.headers['x-nitra-cf-key'] === 'undefined') {
|
|
18
|
-
|
|
20
|
+
log.info('Nitra key not exist in request')
|
|
19
21
|
return false
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
if (req.headers['x-nitra-cf-key'] === 0) {
|
|
23
|
-
|
|
25
|
+
log.info('Empty Nitra key in headers request')
|
|
24
26
|
return false
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
if (req.headers['x-nitra-cf-key'] !== process.env.X_NITRA_CF_KEY) {
|
|
28
|
-
|
|
30
|
+
log.info('Not equal Nitra key')
|
|
29
31
|
return false
|
|
30
32
|
}
|
|
31
33
|
|
package/src/jwt.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import getLogger from '@nitra/bunyan/trace'
|
|
2
|
+
import checkEnv from '@nitra/check-env'
|
|
3
|
+
import verify from '@nitra/jwt/verify'
|
|
4
|
+
|
|
5
|
+
checkEnv(['ALLOWED_ROLES'])
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Check request for Nitra security rules WI
|
|
9
|
+
*
|
|
10
|
+
* @param {object} req - Fastify Request for check
|
|
11
|
+
* @return {string} token if check passed
|
|
12
|
+
*/
|
|
13
|
+
export default async req => {
|
|
14
|
+
const log = getLogger(req)
|
|
15
|
+
|
|
16
|
+
// Перевіряємо токен тільки
|
|
17
|
+
if (!req.headers?.authorization) {
|
|
18
|
+
log.info('[verification] no authorization data')
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const authHeaders = req.headers.authorization.split(' ')
|
|
23
|
+
const token = await verify(authHeaders[1])
|
|
24
|
+
|
|
25
|
+
if (!token) {
|
|
26
|
+
log.info('[verification] invalid token')
|
|
27
|
+
return false
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const roleArray = token.body['https://hasura.io/jwt/claims']['x-hasura-allowed-roles']
|
|
31
|
+
|
|
32
|
+
const allowedRoles = process.env.ALLOWED_ROLES.split(',')
|
|
33
|
+
|
|
34
|
+
const intersectRoles = intersection(roleArray, allowedRoles)
|
|
35
|
+
|
|
36
|
+
if (intersectRoles.length === 0) {
|
|
37
|
+
log.info('[verification] invalid all roles')
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return token.body
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function intersection(a, b) {
|
|
45
|
+
const setA = new Set(a)
|
|
46
|
+
return b.filter(value => setA.has(value))
|
|
47
|
+
}
|