@aeriajs/security 0.0.87 → 0.0.89

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.
@@ -1,4 +1,4 @@
1
1
  import type { Context } from '@aeriajs/types';
2
2
  import type { SecurityCheckProps, SecurityCheckReadPayload, SecurityCheckWritePayload } from './types.js';
3
3
  import { ACError } from '@aeriajs/types';
4
- export declare const checkImmutability: (props: SecurityCheckProps<SecurityCheckReadPayload | SecurityCheckWritePayload>, context: Context) => Promise<import("@aeriajs/types").Right<SecurityCheckReadPayload | SecurityCheckWritePayload> | import("@aeriajs/types").Left<ACError.ImmutabilityParentNotFound> | import("@aeriajs/types").Left<ACError.ImmutabilityIncorrectChild> | import("@aeriajs/types").Left<ACError.ImmutabilityTargetImmutable>>;
4
+ export declare const checkImmutability: (props: SecurityCheckProps<SecurityCheckReadPayload | SecurityCheckWritePayload>, context: Context) => Promise<import("@aeriajs/types").Right<SecurityCheckReadPayload | SecurityCheckWritePayload> | import("@aeriajs/types").Left<ACError.ResourceNotFound> | import("@aeriajs/types").Left<ACError.TargetImmutable>>;
@@ -2,54 +2,29 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkImmutability = void 0;
4
4
  const types_1 = require("@aeriajs/types");
5
- const mongodb_1 = require("mongodb");
6
5
  const common_1 = require("@aeriajs/common");
7
- const internalCheckImmutability = async (props, context) => {
8
- const { propertyName = '', parentId, childId, payload, } = props;
9
- const { description } = context;
10
- const source = 'what' in payload
11
- ? payload.what
12
- : payload.filters;
13
- const property = description.properties[propertyName];
14
- if (!property) {
15
- return (0, common_1.right)(props.payload);
16
- }
17
- const immutable = parentId && (description.immutable === true
18
- || (Array.isArray(description.immutable) && description.immutable.includes(propertyName)));
19
- const currentDocument = await context.collection.model.findOne({
20
- _id: new mongodb_1.ObjectId(parentId),
21
- });
22
- if (!currentDocument) {
23
- return (0, common_1.left)(types_1.ACError.ImmutabilityParentNotFound);
24
- }
25
- if (childId) {
26
- if ((Array.isArray(currentDocument[propertyName]) && !currentDocument[propertyName].some((child) => child.toString() === childId))
27
- || (!Array.isArray(currentDocument[propertyName]) && currentDocument[propertyName] && currentDocument[propertyName] !== childId.toString())) {
28
- return (0, common_1.left)(types_1.ACError.ImmutabilityIncorrectChild);
29
- }
30
- }
31
- const fulfilled = currentDocument[propertyName]
32
- && (typeof currentDocument[propertyName] === 'object' && !Object.keys(currentDocument[propertyName]).length);
33
- if (immutable
34
- && fulfilled
35
- && (property.inline || (currentDocument[propertyName]).toString() !== source[propertyName])) {
36
- return (0, common_1.left)(types_1.ACError.ImmutabilityTargetImmutable);
37
- }
38
- return (0, common_1.right)(props.payload);
39
- };
40
6
  const checkImmutability = async (props, context) => {
41
- if (!props.parentId) {
7
+ if (!context.description.immutable) {
42
8
  return (0, common_1.right)(props.payload);
43
9
  }
44
- for (const propertyName of Object.keys(props.payload)) {
45
- const result = await internalCheckImmutability({
46
- ...props,
47
- propertyName,
48
- }, context);
49
- if ((0, common_1.isLeft)(result)) {
50
- return result;
10
+ const docId = 'filters' in props.payload
11
+ ? props.payload.filters._id
12
+ : props.payload.what._id;
13
+ if (docId) {
14
+ if (typeof context.description.immutable === 'function') {
15
+ const doc = await context.collection.model.findOne({
16
+ _id: docId,
17
+ });
18
+ if (!doc) {
19
+ return (0, common_1.left)(types_1.ACError.ResourceNotFound);
20
+ }
21
+ const isImmutable = await context.description.immutable(doc);
22
+ return isImmutable
23
+ ? (0, common_1.left)(types_1.ACError.TargetImmutable)
24
+ : (0, common_1.right)(props.payload);
51
25
  }
26
+ return (0, common_1.left)(types_1.ACError.TargetImmutable);
52
27
  }
53
- return internalCheckImmutability(props, context);
28
+ return (0, common_1.right)(props.payload);
54
29
  };
55
30
  exports.checkImmutability = checkImmutability;
@@ -1,50 +1,23 @@
1
1
  "use strict";
2
2
  import { ACError } from "@aeriajs/types";
3
- import { ObjectId } from "mongodb";
4
- import { left, right, isLeft } from "@aeriajs/common";
5
- const internalCheckImmutability = async (props, context) => {
6
- const {
7
- propertyName = "",
8
- parentId,
9
- childId,
10
- payload
11
- } = props;
12
- const { description } = context;
13
- const source = "what" in payload ? payload.what : payload.filters;
14
- const property = description.properties[propertyName];
15
- if (!property) {
16
- return right(props.payload);
17
- }
18
- const immutable = parentId && (description.immutable === true || Array.isArray(description.immutable) && description.immutable.includes(propertyName));
19
- const currentDocument = await context.collection.model.findOne({
20
- _id: new ObjectId(parentId)
21
- });
22
- if (!currentDocument) {
23
- return left(ACError.ImmutabilityParentNotFound);
24
- }
25
- if (childId) {
26
- if (Array.isArray(currentDocument[propertyName]) && !currentDocument[propertyName].some((child) => child.toString() === childId) || !Array.isArray(currentDocument[propertyName]) && currentDocument[propertyName] && currentDocument[propertyName] !== childId.toString()) {
27
- return left(ACError.ImmutabilityIncorrectChild);
28
- }
29
- }
30
- const fulfilled = currentDocument[propertyName] && (typeof currentDocument[propertyName] === "object" && !Object.keys(currentDocument[propertyName]).length);
31
- if (immutable && fulfilled && (property.inline || currentDocument[propertyName].toString() !== source[propertyName])) {
32
- return left(ACError.ImmutabilityTargetImmutable);
33
- }
34
- return right(props.payload);
35
- };
3
+ import { left, right } from "@aeriajs/common";
36
4
  export const checkImmutability = async (props, context) => {
37
- if (!props.parentId) {
5
+ if (!context.description.immutable) {
38
6
  return right(props.payload);
39
7
  }
40
- for (const propertyName of Object.keys(props.payload)) {
41
- const result = await internalCheckImmutability({
42
- ...props,
43
- propertyName
44
- }, context);
45
- if (isLeft(result)) {
46
- return result;
8
+ const docId = "filters" in props.payload ? props.payload.filters._id : props.payload.what._id;
9
+ if (docId) {
10
+ if (typeof context.description.immutable === "function") {
11
+ const doc = await context.collection.model.findOne({
12
+ _id: docId
13
+ });
14
+ if (!doc) {
15
+ return left(ACError.ResourceNotFound);
16
+ }
17
+ const isImmutable = await context.description.immutable(doc);
18
+ return isImmutable ? left(ACError.TargetImmutable) : right(props.payload);
47
19
  }
20
+ return left(ACError.TargetImmutable);
48
21
  }
49
- return internalCheckImmutability(props, context);
22
+ return right(props.payload);
50
23
  };
@@ -1,5 +1,5 @@
1
1
  import type { RouteContext, RateLimitingParams } from '@aeriajs/types';
2
- import { RateLimitingErrors } from '@aeriajs/types';
2
+ import { HTTPStatus, RateLimitingError } from '@aeriajs/types';
3
3
  export declare const getOrCreateUsageEntry: (params: RateLimitingParams, context: RouteContext) => Promise<import("@aeriajs/types").WithId<Omit<import("@aeriajs/types").PackReferences<import("@aeriajs/types").SchemaWithId<{
4
4
  readonly $id: "resourceUsage";
5
5
  readonly required: readonly ["usage"];
@@ -34,7 +34,7 @@ export declare const getOrCreateUsageEntry: (params: RateLimitingParams, context
34
34
  };
35
35
  };
36
36
  }>>, "_id">>>;
37
- export declare const limitRate: (params: RateLimitingParams, context: RouteContext) => Promise<import("@aeriajs/types").Left<RateLimitingErrors.LimitReached> | import("@aeriajs/types").Right<import("@aeriajs/types").PackReferences<{} & Omit<Readonly<import("@aeriajs/types").FilterReadonlyProperties<{
37
+ export declare const limitRate: (params: RateLimitingParams, context: RouteContext) => Promise<import("@aeriajs/types").PackReferences<{} & Omit<Readonly<import("@aeriajs/types").FilterReadonlyProperties<{
38
38
  readonly hits: {
39
39
  readonly type: "integer";
40
40
  };
@@ -54,4 +54,8 @@ export declare const limitRate: (params: RateLimitingParams, context: RouteConte
54
54
  points: number;
55
55
  last_reach: Date;
56
56
  last_maximum_reach: Date;
57
- }, never>>>>;
57
+ }, never>> | import("@aeriajs/types").EndpointError<{
58
+ readonly code: RateLimitingError.LimitReached;
59
+ } & {
60
+ httpStatus: HTTPStatus.TooManyRequests;
61
+ }>>;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.limitRate = exports.getOrCreateUsageEntry = void 0;
4
4
  const types_1 = require("@aeriajs/types");
5
- const common_1 = require("@aeriajs/common");
6
5
  const buildEntryFilter = (params, context) => {
7
6
  if (params.strategy === 'ip') {
8
7
  const address = context.response.socket.remoteAddress;
@@ -43,7 +42,9 @@ const limitRate = async (params, context) => {
43
42
  if ('scale' in params) {
44
43
  const now = new Date();
45
44
  if (params.scale > now.getTime() / 1000 - resource.last_reach.getTime() / 1000) {
46
- return (0, common_1.left)(types_1.RateLimitingErrors.LimitReached);
45
+ return context.error(types_1.HTTPStatus.TooManyRequests, {
46
+ code: types_1.RateLimitingError.LimitReached,
47
+ });
47
48
  }
48
49
  }
49
50
  }
@@ -61,6 +62,9 @@ const limitRate = async (params, context) => {
61
62
  }, {
62
63
  returnDocument: 'after',
63
64
  });
64
- return (0, common_1.right)(newEntry.usage[resourceName]);
65
+ if (!newEntry) {
66
+ throw new Error();
67
+ }
68
+ return newEntry.usage[resourceName];
65
69
  };
66
70
  exports.limitRate = limitRate;
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
- import { RateLimitingErrors } from "@aeriajs/types";
3
- import { left, right } from "@aeriajs/common";
2
+ import { HTTPStatus, RateLimitingError } from "@aeriajs/types";
4
3
  const buildEntryFilter = (params, context) => {
5
4
  if (params.strategy === "ip") {
6
5
  const address = context.response.socket.remoteAddress;
@@ -44,7 +43,9 @@ export const limitRate = async (params, context) => {
44
43
  if ("scale" in params) {
45
44
  const now = /* @__PURE__ */ new Date();
46
45
  if (params.scale > now.getTime() / 1e3 - resource.last_reach.getTime() / 1e3) {
47
- return left(RateLimitingErrors.LimitReached);
46
+ return context.error(HTTPStatus.TooManyRequests, {
47
+ code: RateLimitingError.LimitReached
48
+ });
48
49
  }
49
50
  }
50
51
  }
@@ -66,5 +67,8 @@ export const limitRate = async (params, context) => {
66
67
  returnDocument: "after"
67
68
  }
68
69
  );
69
- return right(newEntry.usage[resourceName]);
70
+ if (!newEntry) {
71
+ throw new Error();
72
+ }
73
+ return newEntry.usage[resourceName];
70
74
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aeriajs/security",
3
- "version": "0.0.87",
3
+ "version": "0.0.89",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -28,9 +28,9 @@
28
28
  "mongodb": "^6.5.0"
29
29
  },
30
30
  "peerDependencies": {
31
- "@aeriajs/core": "^0.0.87",
32
- "@aeriajs/common": "^0.0.53",
33
- "@aeriajs/types": "^0.0.50",
31
+ "@aeriajs/core": "^0.0.89",
32
+ "@aeriajs/common": "^0.0.55",
33
+ "@aeriajs/types": "^0.0.52",
34
34
  "mongodb": "^6.5.0"
35
35
  },
36
36
  "scripts": {