@internetderdinge/api 1.224.2 → 1.229.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/dist/src/accounts/accounts.controller.js +89 -0
- package/dist/src/accounts/accounts.route.js +101 -0
- package/dist/src/accounts/accounts.schemas.js +12 -0
- package/dist/src/accounts/accounts.service.js +65 -0
- package/dist/src/accounts/accounts.validation.js +99 -0
- package/dist/src/accounts/auth0.service.js +188 -0
- package/dist/src/config/config.js +48 -0
- package/dist/src/config/logger.js +27 -0
- package/dist/src/config/morgan.js +16 -0
- package/dist/src/config/passport.cjs +28 -0
- package/dist/src/config/roles.js +11 -0
- package/dist/src/config/tokens.cjs +10 -0
- package/dist/src/devices/devices.controller.js +172 -0
- package/dist/src/devices/devices.model.js +94 -0
- package/dist/src/devices/devices.route.js +153 -0
- package/dist/src/devices/devices.schemas.js +84 -0
- package/dist/src/devices/devices.service.js +198 -0
- package/dist/src/devices/devices.types.js +1 -0
- package/dist/src/devices/devices.validation.js +257 -0
- package/dist/src/devicesNotifications/devicesNotifications.controller.js +69 -0
- package/dist/src/devicesNotifications/devicesNotifications.model.js +39 -0
- package/dist/src/devicesNotifications/devicesNotifications.route.js +124 -0
- package/dist/src/devicesNotifications/devicesNotifications.schemas.js +10 -0
- package/dist/src/devicesNotifications/devicesNotifications.service.js +181 -0
- package/dist/src/devicesNotifications/devicesNotifications.validation.js +46 -0
- package/dist/src/email/email.service.js +580 -0
- package/dist/src/files/upload.service.js +124 -0
- package/dist/src/i18n/i18n.js +38 -0
- package/dist/src/i18n/saveMissingLocalJsonBackend.js +53 -0
- package/dist/src/i18n/types.js +1 -0
- package/dist/src/index.js +48 -0
- package/dist/src/iotdevice/iotdevice.controller.js +96 -0
- package/dist/src/iotdevice/iotdevice.model.js +17 -0
- package/dist/src/iotdevice/iotdevice.route.js +143 -0
- package/dist/src/iotdevice/iotdevice.schemas.js +60 -0
- package/dist/src/iotdevice/iotdevice.service.js +579 -0
- package/dist/src/iotdevice/iotdevice.types.js +1 -0
- package/dist/src/iotdevice/iotdevice.validation.js +54 -0
- package/dist/src/middlewares/auth.js +75 -0
- package/dist/src/middlewares/checkJwt.cjs +17 -0
- package/dist/src/middlewares/error.js +36 -0
- package/dist/src/middlewares/mongooseValidations/ensureSameOrganization.js +13 -0
- package/dist/src/middlewares/rateLimiter.js +7 -0
- package/dist/src/middlewares/validate.js +18 -0
- package/dist/src/middlewares/validateAction.js +35 -0
- package/dist/src/middlewares/validateAdmin.js +18 -0
- package/dist/src/middlewares/validateAi.js +16 -0
- package/dist/src/middlewares/validateCurrentAuthUser.js +17 -0
- package/dist/src/middlewares/validateCurrentUser.js +20 -0
- package/dist/src/middlewares/validateDevice.js +98 -0
- package/dist/src/middlewares/validateDeviceUserOrganization.js +26 -0
- package/dist/src/middlewares/validateOrganization.js +63 -0
- package/dist/src/middlewares/validateQuerySearchUserAndOrganization.js +44 -0
- package/dist/src/middlewares/validateTokens.js +23 -0
- package/dist/src/middlewares/validateUser.js +38 -0
- package/dist/src/middlewares/validateZod.js +33 -0
- package/dist/src/models/plugins/index.js +4 -0
- package/dist/src/models/plugins/paginate.plugin.js +117 -0
- package/dist/src/models/plugins/paginateNew.plugin.js +185 -0
- package/dist/src/models/plugins/simplePopulate.js +16 -0
- package/dist/src/models/plugins/toJSON.plugin.js +35 -0
- package/dist/src/organizations/organizations.controller.js +64 -0
- package/dist/src/organizations/organizations.model.js +41 -0
- package/dist/src/organizations/organizations.route.js +98 -0
- package/dist/src/organizations/organizations.schemas.js +7 -0
- package/dist/src/organizations/organizations.service.js +59 -0
- package/dist/src/organizations/organizations.validation.js +62 -0
- package/dist/src/pdf/pdf.controller.js +24 -0
- package/dist/src/pdf/pdf.route.js +22 -0
- package/dist/src/pdf/pdf.schemas.js +6 -0
- package/dist/src/pdf/pdf.service.js +65 -0
- package/dist/src/pdf/pdf.validation.js +27 -0
- package/dist/src/tokens/tokens.controller.js +60 -0
- package/dist/src/tokens/tokens.model.js +18 -0
- package/dist/src/tokens/tokens.route.js +52 -0
- package/dist/src/tokens/tokens.schemas.js +14 -0
- package/dist/src/tokens/tokens.service.js +30 -0
- package/dist/src/tokens/tokens.validation.js +9 -0
- package/dist/src/types/routeSpec.js +1 -0
- package/dist/src/users/users.controller.js +147 -0
- package/dist/src/users/users.model.js +50 -0
- package/dist/src/users/users.route.js +137 -0
- package/dist/src/users/users.schemas.js +69 -0
- package/dist/src/users/users.service.js +295 -0
- package/dist/src/users/users.types.js +1 -0
- package/dist/src/users/users.validation.js +144 -0
- package/dist/src/utils/ApiError.js +16 -0
- package/dist/src/utils/buildRouterAndDocs.js +72 -0
- package/dist/src/utils/catchAsync.js +4 -0
- package/dist/src/utils/comparePapers.service.js +32 -0
- package/dist/src/utils/deviceUtils.js +63 -0
- package/dist/src/utils/filterOptions.js +24 -0
- package/dist/src/utils/medicationName.js +10 -0
- package/dist/src/utils/pick.js +16 -0
- package/dist/src/utils/registerOpenApi.js +28 -0
- package/dist/src/utils/urlUtils.js +15 -0
- package/dist/src/utils/userName.js +22 -0
- package/dist/src/utils/zValidations.js +124 -0
- package/dist/src/validations/auth.validation.cjs +53 -0
- package/dist/src/validations/custom.validation.js +19 -0
- package/dist/src/validations/index.cjs +3 -0
- package/package.json +15 -6
- package/scripts/release-and-sync-paperless.mjs +135 -0
- package/scripts/release-version.mjs +145 -0
- package/src/accounts/accounts.controller.ts +1 -0
- package/src/accounts/accounts.service.ts +1 -0
- package/src/accounts/accounts.validation.ts +6 -3
- package/src/accounts/auth0.service.ts +55 -28
- package/src/config/config.ts +6 -0
- package/src/config/logger.ts +15 -9
- package/src/devices/devices.controller.ts +7 -1
- package/src/devices/devices.model.ts +4 -1
- package/src/devices/devices.schemas.ts +10 -8
- package/src/devices/devices.service.ts +2 -1
- package/src/devices/devices.types.ts +1 -0
- package/src/devices/devices.validation.ts +85 -23
- package/src/devicesNotifications/devicesNotifications.controller.ts +57 -28
- package/src/devicesNotifications/devicesNotifications.model.ts +20 -12
- package/src/devicesNotifications/devicesNotifications.service.ts +35 -17
- package/src/files/upload.service.ts +52 -28
- package/src/i18n/i18n.ts +2 -2
- package/src/i18n/types.ts +1 -0
- package/src/index.ts +47 -0
- package/src/iotdevice/iotdevice.controller.ts +1 -0
- package/src/iotdevice/iotdevice.model.ts +6 -3
- package/src/iotdevice/iotdevice.route.ts +85 -76
- package/src/iotdevice/iotdevice.service.ts +5 -4
- package/src/iotdevice/iotdevice.types.ts +6 -0
- package/src/middlewares/auth.ts +2 -8
- package/src/middlewares/error.ts +26 -12
- package/src/middlewares/mongooseValidations/ensureSameOrganization.ts +4 -3
- package/src/middlewares/validateAi.ts +17 -9
- package/src/middlewares/validateDevice.ts +1 -0
- package/src/middlewares/validateDeviceUserOrganization.ts +1 -0
- package/src/middlewares/validateOrganization.ts +1 -1
- package/src/middlewares/validateQuerySearchUserAndOrganization.ts +1 -0
- package/src/middlewares/validateTokens.ts +2 -1
- package/src/middlewares/validateUser.ts +1 -0
- package/src/models/plugins/index.ts +5 -4
- package/src/models/plugins/paginate.plugin.ts +26 -16
- package/src/models/plugins/paginateNew.plugin.ts +33 -21
- package/src/models/plugins/simplePopulate.ts +8 -3
- package/src/models/plugins/toJSON.plugin.ts +12 -5
- package/src/organizations/organizations.controller.ts +1 -2
- package/src/organizations/organizations.model.ts +4 -4
- package/src/organizations/organizations.route.ts +1 -1
- package/src/organizations/organizations.service.ts +15 -6
- package/src/pdf/pdf.controller.ts +18 -1
- package/src/pdf/pdf.service.ts +25 -16
- package/src/tokens/tokens.controller.ts +6 -8
- package/src/tokens/tokens.model.ts +3 -1
- package/src/tokens/tokens.service.ts +3 -2
- package/src/types/express.d.ts +17 -0
- package/src/types/mongoose.d.ts +22 -0
- package/src/users/users.controller.ts +8 -9
- package/src/users/users.model.ts +6 -5
- package/src/users/users.route.ts +0 -1
- package/src/users/users.service.ts +16 -0
- package/src/users/users.types.ts +1 -0
- package/src/users/users.validation.ts +6 -2
- package/src/utils/ApiError.ts +8 -1
- package/src/utils/buildRouterAndDocs.ts +56 -21
- package/src/utils/catchAsync.ts +27 -3
- package/src/utils/deviceUtils.ts +109 -0
- package/src/utils/medicationName.ts +5 -4
- package/src/utils/pick.ts +5 -1
- package/src/utils/userName.ts +1 -0
- package/src/utils/zValidations.ts +78 -26
- package/tsconfig.json +13 -4
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Router } from
|
|
2
|
-
import buildRouterAndDocs from
|
|
3
|
-
import auth from
|
|
4
|
-
import { validateAdmin } from
|
|
5
|
-
import { validateDevice } from
|
|
6
|
-
import type { RouteSpec } from
|
|
1
|
+
import { Router } from "express";
|
|
2
|
+
import buildRouterAndDocs from "../utils/buildRouterAndDocs";
|
|
3
|
+
import auth from "../middlewares/auth";
|
|
4
|
+
import { validateAdmin } from "../middlewares/validateAdmin";
|
|
5
|
+
import { validateDevice } from "../middlewares/validateDevice";
|
|
6
|
+
import type { RouteSpec } from "../types/routeSpec";
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
getEventsSchema,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
shadowAlarmValidationSchema,
|
|
16
16
|
apiStatusRequestSchema,
|
|
17
17
|
// add other input schemas as needed
|
|
18
|
-
} from
|
|
18
|
+
} from "./iotdevice.validation";
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
21
|
iotDeviceResponseSchema,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
deviceStatusSchema,
|
|
27
27
|
apiStatusSchema,
|
|
28
28
|
entryResponseSchema,
|
|
29
|
-
} from
|
|
29
|
+
} from "./iotdevice.schemas";
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
getIotDevices,
|
|
@@ -40,142 +40,151 @@ import {
|
|
|
40
40
|
getApiStatus,
|
|
41
41
|
getEntry,
|
|
42
42
|
updateEntry,
|
|
43
|
-
} from
|
|
44
|
-
import { request } from
|
|
43
|
+
} from "./iotdevice.controller";
|
|
44
|
+
import { request } from "https";
|
|
45
45
|
|
|
46
46
|
export const iotdeviceRouteSpecs: RouteSpec[] = [
|
|
47
47
|
{
|
|
48
|
-
method:
|
|
49
|
-
path:
|
|
50
|
-
validate: [auth(
|
|
48
|
+
method: "get",
|
|
49
|
+
path: "/",
|
|
50
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
51
51
|
requestSchema: iotDevicesSchema,
|
|
52
52
|
responseSchema: iotDeviceResponseSchema.array(),
|
|
53
53
|
handler: getIotDevices,
|
|
54
|
-
summary:
|
|
55
|
-
description:
|
|
54
|
+
summary: "List all IoT devices",
|
|
55
|
+
description: "Retrieves a list of all registered IoT devices.",
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
|
-
method:
|
|
59
|
-
path:
|
|
60
|
-
validate: [auth(
|
|
58
|
+
method: "get",
|
|
59
|
+
path: "/events/:deviceId",
|
|
60
|
+
validate: [auth("getUsers"), validateDevice],
|
|
61
61
|
requestSchema: getEventsSchema,
|
|
62
62
|
responseSchema: eventResponseSchema.array(),
|
|
63
63
|
handler: getEvents,
|
|
64
|
-
summary:
|
|
65
|
-
description:
|
|
64
|
+
summary: "Get events for a device",
|
|
65
|
+
description: "Fetches event records for the specified device by its ID.",
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
|
-
method:
|
|
69
|
-
path:
|
|
70
|
-
validate: [auth(
|
|
68
|
+
method: "post",
|
|
69
|
+
path: "/devices",
|
|
70
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
71
71
|
requestSchema: getDeviceSchema,
|
|
72
72
|
responseSchema: deviceResponseSchema,
|
|
73
73
|
handler: getDevice,
|
|
74
|
-
summary:
|
|
75
|
-
description:
|
|
74
|
+
summary: "Fetch a single device by criteria",
|
|
75
|
+
description:
|
|
76
|
+
"Retrieves a single IoT device matching the provided criteria.",
|
|
76
77
|
},
|
|
77
78
|
{
|
|
78
|
-
method:
|
|
79
|
-
path:
|
|
80
|
-
validate: [auth(
|
|
79
|
+
method: "get",
|
|
80
|
+
path: "/device/shadowAlarmUpdate/:deviceId",
|
|
81
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
81
82
|
requestSchema: getEntrySchema,
|
|
82
83
|
responseSchema: shadowAlarmSchema,
|
|
83
84
|
handler: shadowAlarmGet,
|
|
84
|
-
summary:
|
|
85
|
-
description:
|
|
85
|
+
summary: "Get shadow alarm settings",
|
|
86
|
+
description:
|
|
87
|
+
"Fetches the shadow alarm configuration for a specific device.",
|
|
86
88
|
},
|
|
87
89
|
{
|
|
88
|
-
method:
|
|
89
|
-
path:
|
|
90
|
-
validate: [auth(
|
|
91
|
-
requestSchema: shadowAlarmSchema,
|
|
90
|
+
method: "post",
|
|
91
|
+
path: "/device/shadowAlarmUpdate/:deviceId",
|
|
92
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
93
|
+
requestSchema: { body: shadowAlarmSchema },
|
|
92
94
|
responseSchema: shadowAlarmSchema,
|
|
93
95
|
handler: shadowAlarmUpdate,
|
|
94
|
-
summary:
|
|
95
|
-
description:
|
|
96
|
+
summary: "Update shadow alarm settings",
|
|
97
|
+
description:
|
|
98
|
+
"Updates the shadow alarm configuration for a specific device.",
|
|
96
99
|
},
|
|
97
100
|
{
|
|
98
|
-
method:
|
|
99
|
-
path:
|
|
100
|
-
validate: [auth(
|
|
101
|
+
method: "get",
|
|
102
|
+
path: "/shadow/:nrfId/:shadowName",
|
|
103
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
101
104
|
requestSchema: shadowAlarmValidationSchema,
|
|
102
105
|
responseSchema: shadowAlarmSchema,
|
|
103
106
|
handler: shadowAdmin,
|
|
104
|
-
summary:
|
|
105
|
-
description:
|
|
107
|
+
summary: "Administer device shadow by nrfId and name",
|
|
108
|
+
description:
|
|
109
|
+
"Performs administrative operations on a device shadow identified by NRF ID and shadow name.",
|
|
106
110
|
},
|
|
107
111
|
{
|
|
108
|
-
method:
|
|
109
|
-
path:
|
|
110
|
-
validate: [auth(
|
|
112
|
+
method: "post",
|
|
113
|
+
path: "/ledlight/:deviceId",
|
|
114
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
111
115
|
responseSchema: pingResponseSchema,
|
|
112
116
|
handler: pingDevice,
|
|
113
|
-
summary:
|
|
114
|
-
description:
|
|
117
|
+
summary: "Ping device LED light",
|
|
118
|
+
description:
|
|
119
|
+
"Sends a ping to the device’s LED light to test its connectivity or response.",
|
|
115
120
|
},
|
|
116
121
|
{
|
|
117
|
-
method:
|
|
118
|
-
path:
|
|
119
|
-
validate: [auth(
|
|
122
|
+
method: "post",
|
|
123
|
+
path: "/ping/:deviceId",
|
|
124
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
120
125
|
requestSchema: pingDeviceSchema,
|
|
121
126
|
responseSchema: pingResponseSchema,
|
|
122
127
|
handler: pingDevice,
|
|
123
|
-
summary:
|
|
124
|
-
description:
|
|
128
|
+
summary: "Ping device",
|
|
129
|
+
description:
|
|
130
|
+
"Sends a ping command to the specified device to verify its availability.",
|
|
125
131
|
},
|
|
126
132
|
{
|
|
127
|
-
method:
|
|
128
|
-
path:
|
|
129
|
-
validate: [auth(
|
|
133
|
+
method: "get",
|
|
134
|
+
path: "/getDeviceStatus/:deviceId",
|
|
135
|
+
validate: [auth("getUsers"), validateAdmin],
|
|
130
136
|
responseSchema: deviceStatusSchema,
|
|
131
137
|
handler: getDeviceStatus,
|
|
132
|
-
summary:
|
|
133
|
-
description:
|
|
138
|
+
summary: "Get current status of a device",
|
|
139
|
+
description:
|
|
140
|
+
"Retrieves the current operational status of the specified device.",
|
|
134
141
|
},
|
|
135
142
|
{
|
|
136
|
-
method:
|
|
137
|
-
path:
|
|
143
|
+
method: "get",
|
|
144
|
+
path: "/status/:kind",
|
|
138
145
|
validate: [],
|
|
139
146
|
requestSchema: apiStatusRequestSchema,
|
|
140
147
|
responseSchema: apiStatusSchema,
|
|
141
148
|
handler: getApiStatus,
|
|
142
|
-
summary:
|
|
143
|
-
description:
|
|
149
|
+
summary: "Get API status by kind",
|
|
150
|
+
description:
|
|
151
|
+
"Retrieves the API status information for a given status kind.",
|
|
144
152
|
},
|
|
145
153
|
{
|
|
146
|
-
method:
|
|
147
|
-
path:
|
|
148
|
-
validate: [auth(
|
|
154
|
+
method: "get",
|
|
155
|
+
path: "/:deviceId",
|
|
156
|
+
validate: [auth("getUsers"), validateDevice, validateAdmin],
|
|
149
157
|
requestSchema: getEntrySchema,
|
|
150
158
|
responseSchema: entryResponseSchema,
|
|
151
159
|
handler: getEntry,
|
|
152
|
-
summary:
|
|
153
|
-
description:
|
|
160
|
+
summary: "Get one entry for a device",
|
|
161
|
+
description: "Fetches a single data entry for the specified device by ID.",
|
|
154
162
|
},
|
|
155
163
|
{
|
|
156
|
-
method:
|
|
157
|
-
path:
|
|
158
|
-
validate: [auth(
|
|
164
|
+
method: "post",
|
|
165
|
+
path: "/:deviceId",
|
|
166
|
+
validate: [auth("manageUsers"), validateDevice, validateAdmin],
|
|
159
167
|
requestSchema: updateEntrySchema,
|
|
160
168
|
responseSchema: entryResponseSchema,
|
|
161
169
|
handler: updateEntry,
|
|
162
|
-
summary:
|
|
163
|
-
description:
|
|
170
|
+
summary: "Create or replace an entry for a device",
|
|
171
|
+
description: "Creates or replaces a data entry for the specified device.",
|
|
164
172
|
},
|
|
165
173
|
{
|
|
166
|
-
method:
|
|
167
|
-
path:
|
|
168
|
-
validate: [auth(
|
|
174
|
+
method: "patch",
|
|
175
|
+
path: "/:deviceId",
|
|
176
|
+
validate: [auth("manageUsers"), validateDevice, validateAdmin],
|
|
169
177
|
requestSchema: updateEntrySchema,
|
|
170
178
|
responseSchema: entryResponseSchema,
|
|
171
179
|
handler: updateEntry,
|
|
172
|
-
summary:
|
|
173
|
-
description:
|
|
180
|
+
summary: "Update an entry for a device",
|
|
181
|
+
description:
|
|
182
|
+
"Applies a partial update to an existing data entry for the specified device.",
|
|
174
183
|
},
|
|
175
184
|
];
|
|
176
185
|
|
|
177
186
|
const router: Router = Router();
|
|
178
187
|
|
|
179
|
-
buildRouterAndDocs(router, iotdeviceRouteSpecs,
|
|
188
|
+
buildRouterAndDocs(router, iotdeviceRouteSpecs, "/iotdevice", ["IoTDevice"]);
|
|
180
189
|
|
|
181
190
|
export default router;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import httpStatus from "http-status";
|
|
2
3
|
import axios from "axios";
|
|
3
4
|
import AWS from "aws-sdk";
|
|
4
|
-
import { deviceKindHasFeature } from "
|
|
5
|
+
import { deviceKindHasFeature } from "../utils/deviceUtils";
|
|
5
6
|
import ApiError from "../utils/ApiError";
|
|
6
7
|
import { getAuth0Token } from "../accounts/auth0.service";
|
|
7
8
|
import {
|
|
@@ -11,10 +12,10 @@ import {
|
|
|
11
12
|
} from "../files/upload.service";
|
|
12
13
|
import { compareImages } from "../utils/comparePapers.service";
|
|
13
14
|
import IotDevice from "./iotdevice.model";
|
|
14
|
-
import
|
|
15
|
+
import { fileTypeFromBuffer } from "file-type";
|
|
15
16
|
|
|
16
17
|
import type { AxiosRequestConfig } from "axios";
|
|
17
|
-
import type { Device } from "../devices.model";
|
|
18
|
+
import type { Device } from "../devices/devices.model.js";
|
|
18
19
|
import type { AxiosResponse } from "axios";
|
|
19
20
|
|
|
20
21
|
import iotsdk from "aws-iot-device-sdk-v2";
|
|
@@ -507,7 +508,7 @@ export const uploadSingleImage = async ({
|
|
|
507
508
|
}
|
|
508
509
|
}
|
|
509
510
|
|
|
510
|
-
const type = await
|
|
511
|
+
const type = await fileTypeFromBuffer(buffer);
|
|
511
512
|
const fileName = `ePaperImages/${id}`;
|
|
512
513
|
|
|
513
514
|
await uploadImage({ blob: buffer, key: fileName + ".png", type });
|
package/src/middlewares/auth.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import passport from "passport";
|
|
2
3
|
import httpStatus from "http-status";
|
|
3
4
|
import { expressjwt as jwt } from "express-jwt";
|
|
@@ -8,14 +9,7 @@ import ApiError from "../utils/ApiError";
|
|
|
8
9
|
import Token from "../tokens/tokens.model";
|
|
9
10
|
import { roleRights } from "../config/roles";
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
auth?: {
|
|
13
|
-
id: string;
|
|
14
|
-
tokenId: string;
|
|
15
|
-
type: string;
|
|
16
|
-
[key: string]: any; // Additional user data
|
|
17
|
-
};
|
|
18
|
-
}
|
|
12
|
+
type AuthRequest = Request;
|
|
19
13
|
|
|
20
14
|
type VerifyCallback = (
|
|
21
15
|
req: AuthRequest,
|
package/src/middlewares/error.ts
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import mongoose from "mongoose";
|
|
3
|
+
import httpStatus from "http-status";
|
|
4
|
+
import config from "../config/config";
|
|
5
|
+
import logger from "../config/logger";
|
|
6
|
+
import ApiError from "../utils/ApiError";
|
|
6
7
|
|
|
7
|
-
import type { Request, Response, NextFunction } from
|
|
8
|
+
import type { Request, Response, NextFunction } from "express";
|
|
8
9
|
|
|
9
|
-
export const errorConverter = (
|
|
10
|
+
export const errorConverter = (
|
|
11
|
+
err: any,
|
|
12
|
+
req: Request,
|
|
13
|
+
res: Response,
|
|
14
|
+
next: NextFunction,
|
|
15
|
+
): void => {
|
|
10
16
|
let error = err;
|
|
11
17
|
if (!(error instanceof ApiError)) {
|
|
12
18
|
const statusCode =
|
|
13
|
-
error.statusCode ||
|
|
19
|
+
error.statusCode ||
|
|
20
|
+
(error instanceof mongoose.Error
|
|
21
|
+
? httpStatus.BAD_REQUEST
|
|
22
|
+
: httpStatus.INTERNAL_SERVER_ERROR);
|
|
14
23
|
const message = error.message || httpStatus[statusCode];
|
|
15
24
|
error = new ApiError(statusCode, message, false, err.stack);
|
|
16
25
|
}
|
|
@@ -18,9 +27,14 @@ export const errorConverter = (err: any, req: Request, res: Response, next: Next
|
|
|
18
27
|
};
|
|
19
28
|
|
|
20
29
|
// eslint-disable-next-line no-unused-vars
|
|
21
|
-
export const errorHandler = (
|
|
30
|
+
export const errorHandler = (
|
|
31
|
+
err: ApiError,
|
|
32
|
+
req: Request,
|
|
33
|
+
res: Response,
|
|
34
|
+
next: NextFunction,
|
|
35
|
+
): void => {
|
|
22
36
|
let { statusCode, message } = err;
|
|
23
|
-
if (config.env ===
|
|
37
|
+
if (config.env === "production" && !err.isOperational) {
|
|
24
38
|
statusCode = httpStatus.INTERNAL_SERVER_ERROR;
|
|
25
39
|
message = httpStatus[httpStatus.INTERNAL_SERVER_ERROR];
|
|
26
40
|
}
|
|
@@ -30,10 +44,10 @@ export const errorHandler = (err: ApiError, req: Request, res: Response, next: N
|
|
|
30
44
|
const response = {
|
|
31
45
|
code: statusCode,
|
|
32
46
|
message,
|
|
33
|
-
...(config.env ===
|
|
47
|
+
...(config.env === "development" && { stack: err.stack }),
|
|
34
48
|
};
|
|
35
49
|
|
|
36
|
-
if (config.env ===
|
|
50
|
+
if (config.env === "development") {
|
|
37
51
|
logger.error(err);
|
|
38
52
|
}
|
|
39
53
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
/**
|
|
2
3
|
* Throws if patient doesn’t exist or isn’t in the given org.
|
|
3
4
|
*/
|
|
@@ -7,9 +8,9 @@ export async function ensureSameOrganization(
|
|
|
7
8
|
UserModel: Model<any>,
|
|
8
9
|
) {
|
|
9
10
|
// console.log('ensureSameOrganization', patientId, organizationId);
|
|
10
|
-
const user = await UserModel.findById(patientId).select(
|
|
11
|
-
if (!user) throw new Error(
|
|
11
|
+
const user = await UserModel.findById(patientId).select("organization");
|
|
12
|
+
if (!user) throw new Error("Patient not found");
|
|
12
13
|
if (!user.organization.equals(organizationId)) {
|
|
13
|
-
throw new Error(
|
|
14
|
+
throw new Error("Patient must belong to the same organization");
|
|
14
15
|
}
|
|
15
16
|
}
|
|
@@ -1,24 +1,32 @@
|
|
|
1
|
-
import httpStatus from
|
|
2
|
-
import ApiError from
|
|
3
|
-
import
|
|
4
|
-
const { Request, Response, NextFunction } = expressPkg;
|
|
1
|
+
import httpStatus from "http-status";
|
|
2
|
+
import ApiError from "../utils/ApiError"; // keep .cjs import
|
|
3
|
+
import type { Request, Response, NextFunction } from "express";
|
|
5
4
|
|
|
6
5
|
interface User {
|
|
7
|
-
|
|
6
|
+
"https://memo.wirewire.de/roles"?: string[];
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
// you can adjust the User source if your auth payload differs
|
|
11
10
|
export const isAiRole = (user?: User): boolean => {
|
|
12
11
|
if (!user) return false;
|
|
13
|
-
return user[
|
|
12
|
+
return user["https://memo.wirewire.de/roles"]?.includes("ai") ?? false;
|
|
14
13
|
};
|
|
15
14
|
|
|
16
|
-
export const validateAiRole = async (
|
|
15
|
+
export const validateAiRole = async (
|
|
16
|
+
req: Request & { auth?: User },
|
|
17
|
+
res: Response,
|
|
18
|
+
next: NextFunction,
|
|
19
|
+
): Promise<void> => {
|
|
17
20
|
// assuming the auth payload is attached to req.auth
|
|
18
21
|
|
|
19
|
-
console.log(
|
|
22
|
+
console.log("Validating AI role for user:", req.auth);
|
|
20
23
|
if (isAiRole(req.auth)) {
|
|
21
24
|
return next();
|
|
22
25
|
}
|
|
23
|
-
return next(
|
|
26
|
+
return next(
|
|
27
|
+
new ApiError(
|
|
28
|
+
httpStatus.FORBIDDEN,
|
|
29
|
+
"User is not part of the ai group (validateAi)",
|
|
30
|
+
),
|
|
31
|
+
);
|
|
24
32
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import type { Request, Response, NextFunction } from "express";
|
|
2
3
|
import type { UserService } from "../users/users.service";
|
|
3
4
|
import userService from "../users/users.service";
|
|
4
|
-
|
|
5
5
|
import httpStatus from "http-status";
|
|
6
6
|
import ApiError from "../utils/ApiError";
|
|
7
7
|
import { isAdmin } from "./validateAdmin";
|
|
@@ -21,7 +21,8 @@ export async function validateParamsToken(
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// compare owner vs. authenticated sub
|
|
24
|
-
|
|
24
|
+
const tokenOwner = (token as { owner?: string }).owner;
|
|
25
|
+
if (!tokenOwner || tokenOwner !== res.req.auth?.sub) {
|
|
25
26
|
return next(
|
|
26
27
|
new ApiError(
|
|
27
28
|
httpStatus.FORBIDDEN,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import type {
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import type { ToJSONPlugin } from "./toJSON.plugin";
|
|
3
|
+
import type { PaginatePlugin } from "./paginate.plugin";
|
|
3
4
|
// import type { PaginateNewPlugin } from './paginateNew.plugin';
|
|
4
5
|
|
|
5
|
-
export { default as toJSON } from
|
|
6
|
-
export { default as paginate } from
|
|
6
|
+
export { default as toJSON } from "./toJSON.plugin";
|
|
7
|
+
export { default as paginate } from "./paginate.plugin";
|
|
7
8
|
// export { default as paginateNew } from './paginateNew.plugin';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
/* eslint-disable no-param-reassign */
|
|
2
|
-
import { Document, Model, Query, Types } from
|
|
3
|
+
import { Document, Model, Query, Types } from "mongoose";
|
|
3
4
|
|
|
4
5
|
export interface QueryResult<T> {
|
|
5
6
|
results: T[];
|
|
@@ -26,20 +27,26 @@ function paginate<T extends Document>(schema: any) {
|
|
|
26
27
|
options: PaginateOptions = {},
|
|
27
28
|
plugin?: PluginFunction,
|
|
28
29
|
): Promise<QueryResult<T>> {
|
|
29
|
-
let sort =
|
|
30
|
+
let sort = "";
|
|
30
31
|
if (options.sortBy) {
|
|
31
32
|
const sortingCriteria: string[] = [];
|
|
32
|
-
options.sortBy.split(
|
|
33
|
-
const [key, order] = sortOption.split(
|
|
34
|
-
sortingCriteria.push((order ===
|
|
33
|
+
options.sortBy.split(",").forEach((sortOption) => {
|
|
34
|
+
const [key, order] = sortOption.split(":");
|
|
35
|
+
sortingCriteria.push((order === "desc" ? "-" : "") + key);
|
|
35
36
|
});
|
|
36
|
-
sort = sortingCriteria.join(
|
|
37
|
+
sort = sortingCriteria.join(" ");
|
|
37
38
|
} else {
|
|
38
|
-
sort =
|
|
39
|
+
sort = "createdAt";
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
const limit =
|
|
42
|
-
|
|
42
|
+
const limit =
|
|
43
|
+
options.limit && parseInt(String(options.limit), 10) > 0
|
|
44
|
+
? parseInt(String(options.limit), 10)
|
|
45
|
+
: 10000;
|
|
46
|
+
const page =
|
|
47
|
+
options.page && parseInt(String(options.page), 10) > 0
|
|
48
|
+
? parseInt(String(options.page), 10)
|
|
49
|
+
: 1;
|
|
43
50
|
const skip = (page - 1) * limit;
|
|
44
51
|
|
|
45
52
|
let results: any[] = [];
|
|
@@ -51,7 +58,7 @@ function paginate<T extends Document>(schema: any) {
|
|
|
51
58
|
|
|
52
59
|
const fuzzyFields = options.fuzzySearch.fields;
|
|
53
60
|
const mustClauses = Object.entries(filter).map(([key, value]) => {
|
|
54
|
-
if (typeof value ===
|
|
61
|
+
if (typeof value === "string" && value.match(/^[a-fA-F0-9]{24}$/)) {
|
|
55
62
|
return { equals: { path: key, value: new Types.ObjectId(value) } };
|
|
56
63
|
}
|
|
57
64
|
return { equals: { path: key, value } };
|
|
@@ -81,7 +88,7 @@ function paginate<T extends Document>(schema: any) {
|
|
|
81
88
|
{
|
|
82
89
|
$facet: {
|
|
83
90
|
results: [],
|
|
84
|
-
totalCount: [{ $count:
|
|
91
|
+
totalCount: [{ $count: "count" }],
|
|
85
92
|
},
|
|
86
93
|
},
|
|
87
94
|
];
|
|
@@ -93,12 +100,15 @@ function paginate<T extends Document>(schema: any) {
|
|
|
93
100
|
// Regular find branch
|
|
94
101
|
const countPromise = this.countDocuments(filter).exec();
|
|
95
102
|
|
|
96
|
-
let docsPromise: any = this.find(filter)
|
|
103
|
+
let docsPromise: any = this.find(filter)
|
|
104
|
+
.sort(sort)
|
|
105
|
+
.skip(skip)
|
|
106
|
+
.limit(limit);
|
|
97
107
|
if (options.populate) {
|
|
98
|
-
options.populate.split(
|
|
108
|
+
options.populate.split(",").forEach((populateOption) => {
|
|
99
109
|
docsPromise = docsPromise.populate(
|
|
100
110
|
populateOption
|
|
101
|
-
.split(
|
|
111
|
+
.split(".")
|
|
102
112
|
.reverse()
|
|
103
113
|
.reduce((a, b) => ({ path: b, populate: a })),
|
|
104
114
|
);
|
|
@@ -117,9 +127,9 @@ function paginate<T extends Document>(schema: any) {
|
|
|
117
127
|
if (options.populate) {
|
|
118
128
|
results = await this.populate(
|
|
119
129
|
results,
|
|
120
|
-
options.populate.split(
|
|
130
|
+
options.populate.split(",").map((populateOption) =>
|
|
121
131
|
populateOption
|
|
122
|
-
.split(
|
|
132
|
+
.split(".")
|
|
123
133
|
.reverse()
|
|
124
134
|
.reduce((a, b) => ({ path: b, populate: a })),
|
|
125
135
|
),
|