@aeriajs/builtins 0.0.228 → 0.0.229
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/dist/collections/user/index.d.ts +11 -1
- package/dist/collections/user/insert.d.ts +12 -1
- package/dist/collections/user/insert.js +41 -0
- package/dist/collections/user/insert.mjs +41 -0
- package/dist/functions/describe.d.ts +3 -2
- package/dist/functions/describe.js +7 -2
- package/dist/functions/describe.mjs +8 -3
- package/dist/index.d.ts +11 -1
- package/package.json +6 -6
|
@@ -243,7 +243,17 @@ export declare const user: Omit<Collection<never>, "functions" | "description" |
|
|
|
243
243
|
} & {
|
|
244
244
|
httpStatus: import("@aeriajs/types").HTTPStatus.Forbidden;
|
|
245
245
|
}>>;
|
|
246
|
-
readonly insert: (payload: NoInfer<import("@aeriajs/types").InsertPayload<import("@aeriajs/types").SchemaWithId<import("@aeriajs/types").Description>>>, context: Omit<Context, "token">) => Promise<import("@aeriajs/types").
|
|
246
|
+
readonly insert: (payload: NoInfer<import("@aeriajs/types").InsertPayload<import("@aeriajs/types").SchemaWithId<import("@aeriajs/types").Description>>>, context: Omit<Context, "token">) => Promise<import("@aeriajs/types").Result.Error<{
|
|
247
|
+
readonly code: import("@aeriajs/types").ACError.AuthorizationError;
|
|
248
|
+
readonly message: "user is not allowed to edit other users roles";
|
|
249
|
+
} & {
|
|
250
|
+
httpStatus: import("@aeriajs/types").HTTPStatus.Forbidden;
|
|
251
|
+
}> | import("@aeriajs/types").Result.Error<{
|
|
252
|
+
readonly code: import("@aeriajs/types").ACError.AuthorizationError;
|
|
253
|
+
readonly message: "tried to set unallowed roles";
|
|
254
|
+
} & {
|
|
255
|
+
httpStatus: import("@aeriajs/types").HTTPStatus.Forbidden;
|
|
256
|
+
}> | import("@aeriajs/types").InsertReturnType<import("@aeriajs/types").SchemaWithId<import("@aeriajs/types").Description>>>;
|
|
247
257
|
readonly editProfile: (payload: Partial<import("@aeriajs/types").PackReferences<import("@aeriajs/types").SchemaWithId<{
|
|
248
258
|
readonly $id: "user";
|
|
249
259
|
readonly icon: "users";
|
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
import type { Context, SchemaWithId, InsertPayload, Description } from '@aeriajs/types';
|
|
2
|
-
|
|
2
|
+
import { HTTPStatus, ACError } from '@aeriajs/types';
|
|
3
|
+
export declare const insert: <TDescription extends Description, TInsertPayload extends InsertPayload<SchemaWithId<TDescription>>>(payload: NoInfer<TInsertPayload>, context: Context<TDescription>) => Promise<import("@aeriajs/types").Result.Error<{
|
|
4
|
+
readonly code: ACError.AuthorizationError;
|
|
5
|
+
readonly message: "user is not allowed to edit other users roles";
|
|
6
|
+
} & {
|
|
7
|
+
httpStatus: HTTPStatus.Forbidden;
|
|
8
|
+
}> | import("@aeriajs/types").Result.Error<{
|
|
9
|
+
readonly code: ACError.AuthorizationError;
|
|
10
|
+
readonly message: "tried to set unallowed roles";
|
|
11
|
+
} & {
|
|
12
|
+
httpStatus: HTTPStatus.Forbidden;
|
|
13
|
+
}> | import("@aeriajs/types").InsertReturnType<SchemaWithId<TDescription>>>;
|
|
@@ -1,9 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.insert = void 0;
|
|
4
|
+
const types_1 = require("@aeriajs/types");
|
|
5
|
+
const common_1 = require("@aeriajs/common");
|
|
4
6
|
const core_1 = require("@aeriajs/core");
|
|
5
7
|
const bcrypt = require("bcrypt");
|
|
8
|
+
const isRoleAllowed = (targetRole, context) => {
|
|
9
|
+
if (!context.config.security.rolesHierarchy || !context.token.authenticated) {
|
|
10
|
+
throw new Error;
|
|
11
|
+
}
|
|
12
|
+
for (const role of context.token.roles) {
|
|
13
|
+
if (role in context.config.security.rolesHierarchy) {
|
|
14
|
+
const hierarchy = context.config.security.rolesHierarchy[role];
|
|
15
|
+
if (!hierarchy) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (hierarchy === true || hierarchy.includes(targetRole)) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
};
|
|
6
25
|
const insert = async (payload, context) => {
|
|
26
|
+
if (!context.token.authenticated) {
|
|
27
|
+
throw new Error;
|
|
28
|
+
}
|
|
29
|
+
if ('roles' in payload.what) {
|
|
30
|
+
if (context.config.security.rolesHierarchy) {
|
|
31
|
+
if (!(0, common_1.arraysIntersect)(context.token.roles, Object.keys(context.config.security.rolesHierarchy))) {
|
|
32
|
+
return context.error(types_1.HTTPStatus.Forbidden, {
|
|
33
|
+
code: types_1.ACError.AuthorizationError,
|
|
34
|
+
message: 'user is not allowed to edit other users roles',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(payload.what.roles)) {
|
|
38
|
+
const allowed = payload.what.roles.every((role) => isRoleAllowed(role, context));
|
|
39
|
+
if (!allowed) {
|
|
40
|
+
return context.error(types_1.HTTPStatus.Forbidden, {
|
|
41
|
+
code: types_1.ACError.AuthorizationError,
|
|
42
|
+
message: 'tried to set unallowed roles',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
7
48
|
if ('password' in payload.what && typeof payload.what.password === 'string') {
|
|
8
49
|
payload.what.password = await bcrypt.hash(payload.what.password, 10);
|
|
9
50
|
}
|
|
@@ -1,7 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
import { HTTPStatus, ACError } from "@aeriajs/types";
|
|
3
|
+
import { arraysIntersect } from "@aeriajs/common";
|
|
2
4
|
import { insert as originalInsert } from "@aeriajs/core";
|
|
3
5
|
import * as bcrypt from "bcrypt";
|
|
6
|
+
const isRoleAllowed = (targetRole, context) => {
|
|
7
|
+
if (!context.config.security.rolesHierarchy || !context.token.authenticated) {
|
|
8
|
+
throw new Error();
|
|
9
|
+
}
|
|
10
|
+
for (const role of context.token.roles) {
|
|
11
|
+
if (role in context.config.security.rolesHierarchy) {
|
|
12
|
+
const hierarchy = context.config.security.rolesHierarchy[role];
|
|
13
|
+
if (!hierarchy) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (hierarchy === true || hierarchy.includes(targetRole)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
4
23
|
export const insert = async (payload, context) => {
|
|
24
|
+
if (!context.token.authenticated) {
|
|
25
|
+
throw new Error();
|
|
26
|
+
}
|
|
27
|
+
if ("roles" in payload.what) {
|
|
28
|
+
if (context.config.security.rolesHierarchy) {
|
|
29
|
+
if (!arraysIntersect(context.token.roles, Object.keys(context.config.security.rolesHierarchy))) {
|
|
30
|
+
return context.error(HTTPStatus.Forbidden, {
|
|
31
|
+
code: ACError.AuthorizationError,
|
|
32
|
+
message: "user is not allowed to edit other users roles"
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(payload.what.roles)) {
|
|
36
|
+
const allowed = payload.what.roles.every((role) => isRoleAllowed(role, context));
|
|
37
|
+
if (!allowed) {
|
|
38
|
+
return context.error(HTTPStatus.Forbidden, {
|
|
39
|
+
code: ACError.AuthorizationError,
|
|
40
|
+
message: "tried to set unallowed roles"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
5
46
|
if ("password" in payload.what && typeof payload.what.password === "string") {
|
|
6
47
|
payload.what.password = await bcrypt.hash(payload.what.password, 10);
|
|
7
48
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Description, RouteContext } from '@aeriajs/types';
|
|
1
|
+
import type { Description, RouteContext, RolesHierarchy, UserRole } from '@aeriajs/types';
|
|
2
2
|
import { Result, ACError, HTTPStatus } from '@aeriajs/types';
|
|
3
3
|
import { authenticate } from '../collections/user/authenticate.js';
|
|
4
4
|
declare const Payload: Partial<{} & Omit<Readonly<import("@aeriajs/types").FilterReadonlyProperties<{
|
|
@@ -56,9 +56,10 @@ export declare const describe: (contextOrPayload: RouteContext | typeof Payload)
|
|
|
56
56
|
readonly error: undefined;
|
|
57
57
|
readonly result: {
|
|
58
58
|
descriptions: Record<string, Description>;
|
|
59
|
-
roles?:
|
|
59
|
+
roles?: UserRole[];
|
|
60
60
|
auth?: Awaited<ReturnType<typeof authenticate>> extends Result.Either<unknown, infer Right> ? Partial<Right> : never;
|
|
61
61
|
router?: unknown;
|
|
62
|
+
rolesHierarchy?: RolesHierarchy;
|
|
62
63
|
};
|
|
63
64
|
}>;
|
|
64
65
|
export {};
|
|
@@ -33,7 +33,9 @@ const [Payload, validatePayload] = (0, validation_1.validator)({
|
|
|
33
33
|
},
|
|
34
34
|
});
|
|
35
35
|
const describe = async (contextOrPayload) => {
|
|
36
|
-
const result = {
|
|
36
|
+
const result = {
|
|
37
|
+
descriptions: {},
|
|
38
|
+
};
|
|
37
39
|
let props;
|
|
38
40
|
if ('request' in contextOrPayload) {
|
|
39
41
|
const { error, result: validatedPayload } = validatePayload(contextOrPayload.request.payload);
|
|
@@ -72,7 +74,7 @@ const describe = async (contextOrPayload) => {
|
|
|
72
74
|
const collection = typeof candidate === 'function'
|
|
73
75
|
? candidate()
|
|
74
76
|
: candidate;
|
|
75
|
-
if (!(0,
|
|
77
|
+
if (!(0, common_1.isValidCollection)(collection)) {
|
|
76
78
|
throw new Error(`The "${collectionName}" symbol exported from the entrypoint doesn't seem like a valid collection. Make sure only collections are exported from the "import('.').collections".`);
|
|
77
79
|
}
|
|
78
80
|
const { description: rawDescription } = collection;
|
|
@@ -89,6 +91,9 @@ const describe = async (contextOrPayload) => {
|
|
|
89
91
|
? userRolesProperty.items.enum
|
|
90
92
|
: [];
|
|
91
93
|
result.roles = Array.from(new Set(userRoles.concat(await (0, entrypoint_1.getAvailableRoles)())));
|
|
94
|
+
if ('config' in contextOrPayload) {
|
|
95
|
+
result.rolesHierarchy = contextOrPayload.config.security.rolesHierarchy;
|
|
96
|
+
}
|
|
92
97
|
}
|
|
93
98
|
if (props.router) {
|
|
94
99
|
result.router = await (0, core_1.getEndpoints)();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import { createContext, preloadDescription, getEndpoints
|
|
2
|
+
import { createContext, preloadDescription, getEndpoints } from "@aeriajs/core";
|
|
3
3
|
import { getCollections, getAvailableRoles } from "@aeriajs/entrypoint";
|
|
4
4
|
import { Result, ACError, HTTPStatus } from "@aeriajs/types";
|
|
5
|
-
import { serialize, endpointError } from "@aeriajs/common";
|
|
5
|
+
import { serialize, endpointError, isValidCollection } from "@aeriajs/common";
|
|
6
6
|
import { validator } from "@aeriajs/validation";
|
|
7
7
|
import { authenticate } from "../collections/user/authenticate.mjs";
|
|
8
8
|
const [Payload, validatePayload] = validator({
|
|
@@ -31,7 +31,9 @@ const [Payload, validatePayload] = validator({
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
export const describe = async (contextOrPayload) => {
|
|
34
|
-
const result = {
|
|
34
|
+
const result = {
|
|
35
|
+
descriptions: {}
|
|
36
|
+
};
|
|
35
37
|
let props;
|
|
36
38
|
if ("request" in contextOrPayload) {
|
|
37
39
|
const { error, result: validatedPayload } = validatePayload(contextOrPayload.request.payload);
|
|
@@ -78,6 +80,9 @@ export const describe = async (contextOrPayload) => {
|
|
|
78
80
|
const userRolesProperty = userCollection.description.properties.roles;
|
|
79
81
|
const userRoles = "enum" in userRolesProperty.items ? userRolesProperty.items.enum : [];
|
|
80
82
|
result.roles = Array.from(new Set(userRoles.concat(await getAvailableRoles())));
|
|
83
|
+
if ("config" in contextOrPayload) {
|
|
84
|
+
result.rolesHierarchy = contextOrPayload.config.security.rolesHierarchy;
|
|
85
|
+
}
|
|
81
86
|
}
|
|
82
87
|
if (props.router) {
|
|
83
88
|
result.router = await getEndpoints();
|
package/dist/index.d.ts
CHANGED
|
@@ -707,7 +707,17 @@ export declare const collections: {
|
|
|
707
707
|
} & {
|
|
708
708
|
httpStatus: import("@aeriajs/types").HTTPStatus.Forbidden;
|
|
709
709
|
}>>;
|
|
710
|
-
readonly insert: (payload: NoInfer<import("@aeriajs/types").InsertPayload<import("@aeriajs/types").SchemaWithId<import("@aeriajs/types").Description>>>, context: Omit<import("@aeriajs/types").Context, "token">) => Promise<import("@aeriajs/types").
|
|
710
|
+
readonly insert: (payload: NoInfer<import("@aeriajs/types").InsertPayload<import("@aeriajs/types").SchemaWithId<import("@aeriajs/types").Description>>>, context: Omit<import("@aeriajs/types").Context, "token">) => Promise<import("@aeriajs/types").Result.Error<{
|
|
711
|
+
readonly code: import("@aeriajs/types").ACError.AuthorizationError;
|
|
712
|
+
readonly message: "user is not allowed to edit other users roles";
|
|
713
|
+
} & {
|
|
714
|
+
httpStatus: import("@aeriajs/types").HTTPStatus.Forbidden;
|
|
715
|
+
}> | import("@aeriajs/types").Result.Error<{
|
|
716
|
+
readonly code: import("@aeriajs/types").ACError.AuthorizationError;
|
|
717
|
+
readonly message: "tried to set unallowed roles";
|
|
718
|
+
} & {
|
|
719
|
+
httpStatus: import("@aeriajs/types").HTTPStatus.Forbidden;
|
|
720
|
+
}> | import("@aeriajs/types").InsertReturnType<import("@aeriajs/types").SchemaWithId<import("@aeriajs/types").Description>>>;
|
|
711
721
|
readonly editProfile: (payload: Partial<import("@aeriajs/types").PackReferences<import("@aeriajs/types").SchemaWithId<{
|
|
712
722
|
readonly $id: "user";
|
|
713
723
|
readonly icon: "users";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeriajs/builtins",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.229",
|
|
4
4
|
"description": "## Installation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"mongodb": "^6.5.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@aeriajs/core": "^0.0.
|
|
59
|
-
"@aeriajs/common": "^0.0.
|
|
60
|
-
"@aeriajs/entrypoint": "^0.0.
|
|
61
|
-
"@aeriajs/types": "^0.0.
|
|
62
|
-
"@aeriajs/validation": "^0.0.
|
|
58
|
+
"@aeriajs/core": "^0.0.229",
|
|
59
|
+
"@aeriajs/common": "^0.0.131",
|
|
60
|
+
"@aeriajs/entrypoint": "^0.0.134",
|
|
61
|
+
"@aeriajs/types": "^0.0.113",
|
|
62
|
+
"@aeriajs/validation": "^0.0.146"
|
|
63
63
|
}
|
|
64
64
|
}
|