@naturalcycles/backend-lib 9.24.0 → 9.26.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.
@@ -17,6 +17,13 @@ export interface RequireAdminCfg {
17
17
  * Set to `false` to debug login issues.
18
18
  */
19
19
  autoLogin?: boolean;
20
+ /**
21
+ * Defaults to `true`.
22
+ *
23
+ * Set to `true` to require that the current user has "every" permission that is listed.
24
+ * Set to `false` to require only that the current user has at least one permission that is listed.
25
+ */
26
+ andComparison?: boolean;
20
27
  }
21
28
  export type AdminMiddleware = (reqPermissions?: string[], cfg?: RequireAdminCfg) => BackendRequestHandler;
22
29
  export declare function createAdminMiddleware(adminService: BaseAdminService, cfgDefaults?: RequireAdminCfg): AdminMiddleware;
@@ -15,12 +15,12 @@ export function createAdminMiddleware(adminService, cfgDefaults = {}) {
15
15
  * Otherwise will just pass.
16
16
  */
17
17
  export function requireAdminPermissions(adminService, reqPermissions = [], cfg = {}) {
18
- const { loginHtmlPath = '/login.html', urlStartsWith, apiHost, autoLogin = true } = cfg;
18
+ const { loginHtmlPath = '/login.html', urlStartsWith, apiHost, autoLogin = true, andComparison = true, } = cfg;
19
19
  return async function requireAdminPermissionsFn(req, res, next) {
20
20
  if (urlStartsWith && !req.url.startsWith(urlStartsWith))
21
21
  return next();
22
22
  try {
23
- await adminService.requirePermissions(req, reqPermissions);
23
+ await adminService.requirePermissions(req, reqPermissions, {}, andComparison);
24
24
  return next();
25
25
  }
26
26
  catch (err) {
@@ -6,5 +6,8 @@ import type { BackendRequest } from './server.model.js';
6
6
  *
7
7
  * Gets the correct full path when used from sub-router-resources.
8
8
  * Strips away the queryString.
9
+ *
10
+ * If stripPrefix (e.g `/api/v2`) is provided, and the path starts with it (like path.startsWith(stripPrefix)),
11
+ * it will be stripped from the beginning of the path.
9
12
  */
10
- export declare function getRequestEndpoint(req: BackendRequest): string;
13
+ export declare function getRequestEndpoint(req: BackendRequest, stripPrefix?: string): string;
@@ -5,11 +5,17 @@
5
5
  *
6
6
  * Gets the correct full path when used from sub-router-resources.
7
7
  * Strips away the queryString.
8
+ *
9
+ * If stripPrefix (e.g `/api/v2`) is provided, and the path starts with it (like path.startsWith(stripPrefix)),
10
+ * it will be stripped from the beginning of the path.
8
11
  */
9
- export function getRequestEndpoint(req) {
12
+ export function getRequestEndpoint(req, stripPrefix) {
10
13
  let path = (req.baseUrl + (req.route?.path || req.path)).toLowerCase();
11
14
  if (path.length > 1 && path.endsWith('/')) {
12
15
  path = path.slice(0, path.length - 1);
13
16
  }
17
+ if (stripPrefix && path.startsWith(stripPrefix)) {
18
+ path = path.slice(stripPrefix.length);
19
+ }
14
20
  return [req.method, path].join(' ');
15
21
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/backend-lib",
3
3
  "type": "module",
4
- "version": "9.24.0",
4
+ "version": "9.26.0",
5
5
  "peerDependencies": {
6
6
  "@sentry/node": "^10"
7
7
  },
@@ -25,6 +25,14 @@ export interface RequireAdminCfg {
25
25
  * Set to `false` to debug login issues.
26
26
  */
27
27
  autoLogin?: boolean
28
+
29
+ /**
30
+ * Defaults to `true`.
31
+ *
32
+ * Set to `true` to require that the current user has "every" permission that is listed.
33
+ * Set to `false` to require only that the current user has at least one permission that is listed.
34
+ */
35
+ andComparison?: boolean
28
36
  }
29
37
 
30
38
  export type AdminMiddleware = (
@@ -54,13 +62,19 @@ export function requireAdminPermissions(
54
62
  reqPermissions: string[] = [],
55
63
  cfg: RequireAdminCfg = {},
56
64
  ): BackendRequestHandler {
57
- const { loginHtmlPath = '/login.html', urlStartsWith, apiHost, autoLogin = true } = cfg
65
+ const {
66
+ loginHtmlPath = '/login.html',
67
+ urlStartsWith,
68
+ apiHost,
69
+ autoLogin = true,
70
+ andComparison = true,
71
+ } = cfg
58
72
 
59
73
  return async function requireAdminPermissionsFn(req, res, next) {
60
74
  if (urlStartsWith && !req.url.startsWith(urlStartsWith)) return next()
61
75
 
62
76
  try {
63
- await adminService.requirePermissions(req, reqPermissions)
77
+ await adminService.requirePermissions(req, reqPermissions, {}, andComparison)
64
78
  return next()
65
79
  } catch (err) {
66
80
  if (err instanceof AppError && err.data.adminAuthRequired) {
@@ -7,12 +7,19 @@ import type { BackendRequest } from './server.model.js'
7
7
  *
8
8
  * Gets the correct full path when used from sub-router-resources.
9
9
  * Strips away the queryString.
10
+ *
11
+ * If stripPrefix (e.g `/api/v2`) is provided, and the path starts with it (like path.startsWith(stripPrefix)),
12
+ * it will be stripped from the beginning of the path.
10
13
  */
11
- export function getRequestEndpoint(req: BackendRequest): string {
14
+ export function getRequestEndpoint(req: BackendRequest, stripPrefix?: string): string {
12
15
  let path = (req.baseUrl + (req.route?.path || req.path)).toLowerCase()
13
16
  if (path.length > 1 && path.endsWith('/')) {
14
17
  path = path.slice(0, path.length - 1)
15
18
  }
16
19
 
20
+ if (stripPrefix && path.startsWith(stripPrefix)) {
21
+ path = path.slice(stripPrefix.length)
22
+ }
23
+
17
24
  return [req.method, path].join(' ')
18
25
  }