@platformatic/db-authorization 3.4.1 → 3.5.1

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Fastify plugin that adds role-based authorization hooks to [`@platformatic/sql-mapper`](https://www.npmjs.com/package/@platformatic/sql-mapper).
4
4
 
5
- Check out the full documentation on [our website](https://docs.platformatic.dev/docs/db/authorization/overview).
5
+ Check out the full documentation on [our website](https://docs.platformatic.dev/docs/reference/db/authorization/overview).
6
6
 
7
7
  ## Install
8
8
 
package/eslint.config.js CHANGED
@@ -1,7 +1,3 @@
1
- 'use strict'
1
+ import neostandard from 'neostandard'
2
2
 
3
- const neostandard = require('neostandard')
4
-
5
- module.exports = neostandard({
6
- ts: true,
7
- })
3
+ export default neostandard({ ts: true })
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  type PlatformaticContext,
3
- type WhereCondition,
3
+ type WhereClause,
4
4
  } from '@platformatic/sql-mapper'
5
5
  import { type FastifyPluginAsync } from 'fastify'
6
6
  import { type FastifyUserPluginOptions } from 'fastify-user'
@@ -9,11 +9,11 @@ import { FastifyError } from '@fastify/error'
9
9
  export type OperationFunction<T> = (args: {
10
10
  user: T,
11
11
  ctx: PlatformaticContext,
12
- where: WhereCondition
13
- }) => WhereCondition
12
+ where: WhereClause
13
+ }) => WhereClause
14
14
 
15
15
  export interface OperationChecks {
16
- checks: Record<string, any> | WhereCondition
16
+ checks: Record<string, any> | WhereClause
17
17
  }
18
18
 
19
19
  export interface OperationFields {
@@ -52,7 +52,7 @@ export interface DBAuthorizationPluginOptions<T = any> extends FastifyUserPlugin
52
52
  roleKey?: string
53
53
  isRolePath?: boolean
54
54
  anonymousRole?: string
55
- rules: Array<AuthorizationRule<T>>
55
+ rules?: Array<AuthorizationRule<T>>
56
56
  }
57
57
 
58
58
  export interface DBAuthorizationPluginInterface {
package/index.js CHANGED
@@ -1,17 +1,9 @@
1
- 'use strict'
2
-
3
- const fp = require('fastify-plugin')
4
- const leven = require('leven')
5
- const fastifyUser = require('fastify-user')
6
- const errors = require('./lib/errors')
7
-
8
- const findRule = require('./lib/find-rule')
9
- const { getRequestFromContext, getRoles } = require('./lib/utils')
10
- const {
11
- Unauthorized,
12
- UnauthorizedField,
13
- MissingNotNullableError,
14
- } = require('./lib/errors')
1
+ import fp from 'fastify-plugin'
2
+ import fastifyUser from 'fastify-user'
3
+ import leven from 'leven'
4
+ import { MissingNotNullableError, Unauthorized, UnauthorizedField } from './lib/errors.js'
5
+ import { findRule } from './lib/find-rule.js'
6
+ import { getRequestFromContext, getRoles } from './lib/utils.js'
15
7
 
16
8
  const PLT_ADMIN_ROLE = 'platformatic-admin'
17
9
 
@@ -49,7 +41,7 @@ async function auth (app, opts) {
49
41
  value = PLT_ADMIN_ROLE
50
42
  }
51
43
  return value
52
- },
44
+ }
53
45
  })
54
46
  }
55
47
  }
@@ -58,14 +50,14 @@ async function auth (app, opts) {
58
50
  // We replace just the role in `request.user`, all the rest is untouched
59
51
  request.user = {
60
52
  ...request.user,
61
- [roleKey]: PLT_ADMIN_ROLE,
53
+ [roleKey]: PLT_ADMIN_ROLE
62
54
  }
63
55
  }
64
56
  }
65
57
 
66
58
  const rules = opts.rules || []
67
59
 
68
- app.platformatic.addRulesForRoles = (_rules) => {
60
+ app.platformatic.addRulesForRoles = _rules => {
69
61
  for (const rule of _rules) {
70
62
  rules.push(rule)
71
63
  }
@@ -76,14 +68,17 @@ async function auth (app, opts) {
76
68
  // There is an unknown entity. Let's find out the nearest one for a nice error message
77
69
  const entities = Object.keys(app.platformatic.entities)
78
70
 
79
- const nearest = entities.reduce((acc, entity) => {
80
- const distance = leven(ruleEntity, entity)
81
- if (distance < acc.distance) {
82
- acc.distance = distance
83
- acc.entity = entity
84
- }
85
- return acc
86
- }, { distance: Infinity, entity: null })
71
+ const nearest = entities.reduce(
72
+ (acc, entity) => {
73
+ const distance = leven(ruleEntity, entity)
74
+ if (distance < acc.distance) {
75
+ acc.distance = distance
76
+ acc.entity = entity
77
+ }
78
+ return acc
79
+ },
80
+ { distance: Infinity, entity: null }
81
+ )
87
82
  return nearest
88
83
  }
89
84
 
@@ -105,7 +100,9 @@ async function auth (app, opts) {
105
100
  const newRule = { ...rule, entity: ruleEntity, entities: undefined }
106
101
  if (!app.platformatic.entities[newRule.entity]) {
107
102
  const nearest = findNearestEntity(ruleEntity)
108
- throw new Error(`Unknown entity '${ruleEntity}' in authorization rule ${i}. Did you mean '${nearest.entity}'?`)
103
+ throw new Error(
104
+ `Unknown entity '${ruleEntity}' in authorization rule ${i}. Did you mean '${nearest.entity}'?`
105
+ )
109
106
  }
110
107
 
111
108
  if (!entityRules[ruleEntity]) {
@@ -131,7 +128,9 @@ async function auth (app, opts) {
131
128
  }
132
129
  const keys = Object.keys(checks)
133
130
  if (keys.length !== 1) {
134
- throw new Error(`Subscription requires that the role "${rule.role}" has only one check in the find rule for entity "${rule.entity}"`)
131
+ throw new Error(
132
+ `Subscription requires that the role "${rule.role}" has only one check in the find rule for entity "${rule.entity}"`
133
+ )
135
134
  }
136
135
  const key = keys[0]
137
136
 
@@ -153,7 +152,7 @@ async function auth (app, opts) {
153
152
  role: PLT_ADMIN_ROLE,
154
153
  find: true,
155
154
  save: true,
156
- delete: true,
155
+ delete: true
157
156
  })
158
157
  }
159
158
 
@@ -219,7 +218,7 @@ async function auth (app, opts) {
219
218
  const found = await type.find({
220
219
  where,
221
220
  ctx,
222
- fields,
221
+ fields
223
222
  })
224
223
 
225
224
  if (found.length === 0) {
@@ -311,7 +310,7 @@ async function auth (app, opts) {
311
310
  }
312
311
 
313
312
  return originalTopic
314
- },
313
+ }
315
314
  })
316
315
  }
317
316
  })
@@ -333,19 +332,19 @@ async function fromRuleToWhere (ctx, rule, where, user) {
333
332
  for (const key of Object.keys(checks)) {
334
333
  const clauses = checks[key]
335
334
  if (typeof clauses === 'string') {
336
- // case: "userId": "X-PLATFORMATIC-USER-ID"
335
+ // case: "userId": "X-PLATFORMATIC-USER-ID"
337
336
  where[key] = {
338
- eq: request.user[clauses],
337
+ eq: request.user[clauses]
339
338
  }
340
339
  } else {
341
- // case:
342
- // userId: {
343
- // eq: 'X-PLATFORMATIC-USER-ID'
344
- // }
340
+ // case:
341
+ // userId: {
342
+ // eq: 'X-PLATFORMATIC-USER-ID'
343
+ // }
345
344
  for (const clauseKey of Object.keys(clauses)) {
346
345
  const clause = clauses[clauseKey]
347
346
  where[key] = {
348
- [clauseKey]: request.user[clause],
347
+ [clauseKey]: request.user[clause]
349
348
  }
350
349
  }
351
350
  }
@@ -412,10 +411,9 @@ function checkInputFromRuleFields (rule, inputs) {
412
411
 
413
412
  function checkSaveMandatoryFieldsInRules (type, rules) {
414
413
  // List of not nullable, not PKs field to validate save/insert when allowed fields are specified on the rule
415
- const mandatoryFields =
416
- Object.values(type.fields)
417
- .filter(k => (!k.isNullable && !k.primaryKey))
418
- .map(({ camelcase }) => (camelcase))
414
+ const mandatoryFields = Object.values(type.fields)
415
+ .filter(k => !k.isNullable && !k.primaryKey)
416
+ .map(({ camelcase }) => camelcase)
419
417
 
420
418
  for (const rule of rules) {
421
419
  const { entity, save } = rule
@@ -430,5 +428,5 @@ function checkSaveMandatoryFieldsInRules (type, rules) {
430
428
  }
431
429
  }
432
430
 
433
- module.exports = fp(auth)
434
- module.exports.errors = errors
431
+ export default fp(auth)
432
+ export * as errors from './lib/errors.js'
package/lib/errors.js CHANGED
@@ -1,11 +1,10 @@
1
- 'use strict'
1
+ import createError from '@fastify/error'
2
2
 
3
- const createError = require('@fastify/error')
3
+ export const ERROR_PREFIX = 'PLT_DB_AUTH'
4
4
 
5
- const ERROR_PREFIX = 'PLT_DB_AUTH'
6
-
7
- module.exports = {
8
- Unauthorized: createError(`${ERROR_PREFIX}_UNAUTHORIZED`, 'operation not allowed', 401),
9
- UnauthorizedField: createError(`${ERROR_PREFIX}_FIELD_UNAUTHORIZED`, 'field not allowed: %s', 401),
10
- MissingNotNullableError: createError(`${ERROR_PREFIX}_NOT_NULLABLE_MISSING`, 'missing not nullable field: "%s" in save rule for entity "%s"'),
11
- }
5
+ export const Unauthorized = createError(`${ERROR_PREFIX}_UNAUTHORIZED`, 'operation not allowed', 401)
6
+ export const UnauthorizedField = createError(`${ERROR_PREFIX}_FIELD_UNAUTHORIZED`, 'field not allowed: %s', 401)
7
+ export const MissingNotNullableError = createError(
8
+ `${ERROR_PREFIX}_NOT_NULLABLE_MISSING`,
9
+ 'missing not nullable field: "%s" in save rule for entity "%s"'
10
+ )
package/lib/find-rule.js CHANGED
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- function findRule (rules, roles) {
1
+ export function findRule (rules, roles) {
4
2
  let found = null
5
3
  for (const rule of rules) {
6
4
  for (const role of roles) {
@@ -15,5 +13,3 @@ function findRule (rules, roles) {
15
13
  }
16
14
  return found
17
15
  }
18
-
19
- module.exports = findRule
@@ -1,23 +1,19 @@
1
- 'use strict'
2
-
3
- const AuthSchema = {
1
+ export const AuthSchema = {
4
2
  $id: '/BasegraphAuth',
5
3
  type: 'object',
6
4
  properties: {
7
5
  adminSecret: {
8
6
  type: 'string',
9
- description: 'The password should be used to access routes under /_admin prefix.',
7
+ description: 'The password should be used to access routes under /_admin prefix.'
10
8
  },
11
9
  roleKey: {
12
10
  type: 'string',
13
- description: 'The key in the user object that contains the roles.',
11
+ description: 'The key in the user object that contains the roles.'
14
12
  },
15
13
  rolePath: {
16
14
  type: 'string',
17
- description: 'The path in the user object that contains the roles.',
18
- },
15
+ description: 'The path in the user object that contains the roles.'
16
+ }
19
17
  },
20
- additionalProperties: true, // TODO remove and add proper validation for the rules
18
+ additionalProperties: true // TODO remove and add proper validation for the rules
21
19
  }
22
-
23
- module.exports = AuthSchema
package/lib/utils.js CHANGED
@@ -1,13 +1,11 @@
1
- 'use strict'
2
-
3
- function getRequestFromContext (ctx) {
1
+ export function getRequestFromContext (ctx) {
4
2
  if (ctx && !ctx.reply) {
5
3
  throw new Error('Missing reply in context. You should call this function with { ctx: { reply }}')
6
4
  }
7
5
  return ctx.reply.request
8
6
  }
9
7
 
10
- function getRoles (request, roleKey, anonymousRole, isRolePath = false) {
8
+ export function getRoles (request, roleKey, anonymousRole, isRolePath = false) {
11
9
  let output = []
12
10
  const user = request.user
13
11
  if (!user) {
@@ -37,7 +35,3 @@ function getRoles (request, roleKey, anonymousRole, isRolePath = false) {
37
35
 
38
36
  return output
39
37
  }
40
- module.exports = {
41
- getRequestFromContext,
42
- getRoles,
43
- }
package/package.json CHANGED
@@ -1,31 +1,31 @@
1
1
  {
2
2
  "name": "@platformatic/db-authorization",
3
- "version": "3.4.1",
3
+ "version": "3.5.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
+ "type": "module",
6
7
  "types": "index.d.ts",
7
- "author": "Matteo Collina <hello@matteocollina.com>",
8
+ "author": "Platformatic Inc. <oss@platformatic.dev> (https://platformatic.dev)",
8
9
  "repository": {
9
10
  "type": "git",
10
11
  "url": "git+https://github.com/platformatic/platformatic.git"
11
12
  },
12
13
  "license": "Apache-2.0",
13
14
  "devDependencies": {
14
- "@fastify/cookie": "^10.0.0",
15
+ "@fastify/cookie": "^11.0.0",
15
16
  "@fastify/session": "^11.0.0",
16
- "@matteo.collina/tspl": "^0.1.1",
17
- "borp": "^0.17.0",
17
+ "cleaner-spec-reporter": "^0.5.0",
18
18
  "eslint": "9",
19
- "fast-jwt": "^4.0.0",
19
+ "fast-jwt": "^5.0.0",
20
20
  "fastify": "^5.0.0",
21
- "neostandard": "^0.11.1",
22
- "tsd": "^0.31.0",
21
+ "get-jwks": "^11.0.0",
22
+ "neostandard": "^0.12.0",
23
+ "tsd": "^0.33.0",
23
24
  "typescript": "^5.5.4",
24
25
  "why-is-node-running": "^2.2.2",
25
26
  "ws": "^8.16.0",
26
- "get-jwks": "^9.0.1",
27
- "@platformatic/db-core": "3.4.1",
28
- "@platformatic/sql-mapper": "3.4.1"
27
+ "@platformatic/sql-mapper": "3.5.1",
28
+ "@platformatic/db-core": "3.5.1"
29
29
  },
30
30
  "dependencies": {
31
31
  "@fastify/error": "^4.0.0",
@@ -33,13 +33,17 @@
33
33
  "fastify-plugin": "^5.0.0",
34
34
  "fastify-user": "^1.0.2",
35
35
  "leven": "~3.1.0",
36
- "undici": "^6.9.0"
36
+ "undici": "^7.0.0"
37
37
  },
38
38
  "tsd": {
39
39
  "directory": "test/types"
40
40
  },
41
+ "engines": {
42
+ "node": ">=22.19.0"
43
+ },
41
44
  "scripts": {
42
- "test": "pnpm run lint && borp --concurrency=1 --timeout=180000 && tsd",
45
+ "test": "node --test --test-reporter=cleaner-spec-reporter --test-concurrency=1 --test-timeout=2000000 test/*.test.js test/**/*.test.js",
46
+ "posttest": "tsd",
43
47
  "lint": "eslint"
44
48
  }
45
49
  }