@internetderdinge/api 1.229.0 → 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 +13 -3
- package/scripts/release-and-sync-paperless.mjs +135 -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 +1 -0
- 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 +1 -1
- 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 +4 -3
- 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/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,20 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import httpStatus from "http-status";
|
|
3
|
+
import {
|
|
4
|
+
SESv2Client,
|
|
5
|
+
ListSuppressedDestinationsCommand,
|
|
6
|
+
} from "@aws-sdk/client-sesv2";
|
|
7
|
+
import DeviceNotification from "./devicesNotifications.model";
|
|
8
|
+
import ApiError from "../../src/utils/ApiError";
|
|
9
|
+
import { auth0 } from "../accounts/auth0.service";
|
|
10
|
+
import type { Notification } from "./devicesNotifications.model";
|
|
11
|
+
import type { FilterQuery, PaginateOptions, QueryResult } from "mongoose";
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
14
|
* Create a user
|
|
12
15
|
* @param {Object} userBody
|
|
13
16
|
* @returns {Promise<Notification>}
|
|
14
17
|
*/
|
|
15
|
-
export const createNotificationUser = async ({
|
|
18
|
+
export const createNotificationUser = async ({
|
|
19
|
+
user,
|
|
20
|
+
}: {
|
|
21
|
+
user: string;
|
|
22
|
+
}): Promise<Notification> => {
|
|
16
23
|
const result = await DeviceNotification.findOne({ user });
|
|
17
|
-
if (result)
|
|
24
|
+
if (result)
|
|
25
|
+
throw new ApiError(
|
|
26
|
+
httpStatus.NOT_FOUND,
|
|
27
|
+
"DevicesNotifications user existing",
|
|
28
|
+
);
|
|
18
29
|
const devicesNotification = await DeviceNotification.create({ user });
|
|
19
30
|
return devicesNotification;
|
|
20
31
|
};
|
|
@@ -37,7 +48,9 @@ export const setDeviceToken = async ({
|
|
|
37
48
|
result = await createNotificationUser({ user });
|
|
38
49
|
}
|
|
39
50
|
|
|
40
|
-
result.tokens = [
|
|
51
|
+
result.tokens = [
|
|
52
|
+
...new Map(result.tokens.map((m) => [m.deviceId, m])).values(),
|
|
53
|
+
];
|
|
41
54
|
|
|
42
55
|
if (result.tokens.find((t) => t.token === token)) return result;
|
|
43
56
|
|
|
@@ -120,7 +133,7 @@ const getByUser = async (user) => {
|
|
|
120
133
|
const updateById = async (notificationId, updateBody) => {
|
|
121
134
|
const user = await getById(notificationId);
|
|
122
135
|
if (!user) {
|
|
123
|
-
throw new ApiError(httpStatus.NOT_FOUND,
|
|
136
|
+
throw new ApiError(httpStatus.NOT_FOUND, "Notification not found");
|
|
124
137
|
}
|
|
125
138
|
Object.assign(user, updateBody);
|
|
126
139
|
await user.save();
|
|
@@ -148,7 +161,7 @@ const updateByUserId = async (user, updateBody) => {
|
|
|
148
161
|
const deleteById = async (userId) => {
|
|
149
162
|
const user = await getById(userId);
|
|
150
163
|
if (!user) {
|
|
151
|
-
throw new ApiError(httpStatus.NOT_FOUND,
|
|
164
|
+
throw new ApiError(httpStatus.NOT_FOUND, "Notification not found");
|
|
152
165
|
}
|
|
153
166
|
await user.deleteOne();
|
|
154
167
|
return user;
|
|
@@ -164,17 +177,22 @@ const cleanup = async () => {
|
|
|
164
177
|
|
|
165
178
|
const auth0Users = await auth0.getUsers();
|
|
166
179
|
|
|
167
|
-
const sesV2 = new SESv2Client({ region:
|
|
180
|
+
const sesV2 = new SESv2Client({ region: "eu-central-1" });
|
|
168
181
|
const input = {
|
|
169
|
-
Reasons: [
|
|
182
|
+
Reasons: ["BOUNCE" || "COMPLAINT"],
|
|
170
183
|
PageSize: 300,
|
|
171
184
|
};
|
|
172
185
|
|
|
173
186
|
const command = new ListSuppressedDestinationsCommand(input);
|
|
174
187
|
const suppressedDestinations = await sesV2.send(command);
|
|
175
188
|
|
|
176
|
-
const suppressedEmailList =
|
|
177
|
-
|
|
189
|
+
const suppressedEmailList =
|
|
190
|
+
suppressedDestinations.SuppressedDestinationSummaries.map(
|
|
191
|
+
(a) => a.EmailAddress,
|
|
192
|
+
);
|
|
193
|
+
const suppressedEmailAuth0Users = auth0Users.filter((a) =>
|
|
194
|
+
suppressedEmailList.includes(a.email),
|
|
195
|
+
);
|
|
178
196
|
await Promise.all(
|
|
179
197
|
suppressedEmailAuth0Users.map(async (a) => {
|
|
180
198
|
updateByUserId(a.user_id, { bounceEmail: a.email });
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
|
|
3
|
+
import { Upload } from "@aws-sdk/lib-storage";
|
|
4
|
+
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
5
|
+
import multer from "multer";
|
|
6
|
+
import multerS3 from "multer-s3";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import request from "request";
|
|
8
9
|
|
|
9
10
|
type GetSignedFileUrlParams = {
|
|
10
11
|
fileName: string;
|
|
@@ -18,7 +19,7 @@ type UploadImageParams = {
|
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
const s3 = new S3Client({
|
|
21
|
-
region:
|
|
22
|
+
region: "eu-central-1",
|
|
22
23
|
credentials: {
|
|
23
24
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
|
|
24
25
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
|
|
@@ -39,7 +40,10 @@ export const getSignedFileUrl = async ({
|
|
|
39
40
|
return result;
|
|
40
41
|
};
|
|
41
42
|
|
|
42
|
-
export const uploadImage = async ({
|
|
43
|
+
export const uploadImage = async ({
|
|
44
|
+
key,
|
|
45
|
+
blob,
|
|
46
|
+
}: UploadImageParams): Promise<{ hello: string }> => {
|
|
43
47
|
const target = {
|
|
44
48
|
Bucket: process.env.AWS_S3_BUCKET_NAME!,
|
|
45
49
|
Key: key,
|
|
@@ -54,7 +58,7 @@ export const uploadImage = async ({ key, blob }: UploadImageParams): Promise<{ h
|
|
|
54
58
|
params: target,
|
|
55
59
|
});
|
|
56
60
|
|
|
57
|
-
parallelUploads3.on(
|
|
61
|
+
parallelUploads3.on("httpUploadProgress", (progress) => {
|
|
58
62
|
// console.log(progress);
|
|
59
63
|
});
|
|
60
64
|
|
|
@@ -63,14 +67,18 @@ export const uploadImage = async ({ key, blob }: UploadImageParams): Promise<{ h
|
|
|
63
67
|
console.error(e);
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
return { hello:
|
|
70
|
+
return { hello: "xx" };
|
|
67
71
|
};
|
|
68
72
|
|
|
69
|
-
export const fileFilter = (
|
|
70
|
-
|
|
73
|
+
export const fileFilter = (
|
|
74
|
+
req: Express.Request,
|
|
75
|
+
file: Express.Multer.File,
|
|
76
|
+
cb: multer.FileFilterCallback,
|
|
77
|
+
): void => {
|
|
78
|
+
if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") {
|
|
71
79
|
cb(null, true);
|
|
72
80
|
} else {
|
|
73
|
-
cb(new Error(
|
|
81
|
+
cb(new Error("Invalid file type, only JPEG and PNG is allowed!"), false);
|
|
74
82
|
}
|
|
75
83
|
};
|
|
76
84
|
|
|
@@ -79,7 +87,7 @@ export const uploadFile = multer({
|
|
|
79
87
|
s3: s3,
|
|
80
88
|
bucket: process.env.AWS_S3_BUCKET_NAME!,
|
|
81
89
|
contentType: multerS3.AUTO_CONTENT_TYPE,
|
|
82
|
-
acl:
|
|
90
|
+
acl: "public-read",
|
|
83
91
|
metadata(req, file, cb) {
|
|
84
92
|
cb(null, { fieldName: file.fieldname });
|
|
85
93
|
},
|
|
@@ -89,7 +97,10 @@ export const uploadFile = multer({
|
|
|
89
97
|
}),
|
|
90
98
|
});
|
|
91
99
|
|
|
92
|
-
const getPhoto = async (
|
|
100
|
+
const getPhoto = async (
|
|
101
|
+
photoId: string,
|
|
102
|
+
res: Express.Response,
|
|
103
|
+
): Promise<void> => {
|
|
93
104
|
try {
|
|
94
105
|
const params = {
|
|
95
106
|
Bucket: process.env.AWS_S3_BUCKET_NAME!,
|
|
@@ -98,9 +109,9 @@ const getPhoto = async (photoId: string, res: Express.Response): Promise<void> =
|
|
|
98
109
|
|
|
99
110
|
await s3
|
|
100
111
|
.getObject(params)
|
|
101
|
-
.on(
|
|
102
|
-
res.set(
|
|
103
|
-
res.set(
|
|
112
|
+
.on("httpHeaders", function (statusCode, headers) {
|
|
113
|
+
res.set("Content-Length", headers["content-length"]);
|
|
114
|
+
res.set("Content-Type", headers["content-type"]);
|
|
104
115
|
this.response.httpResponse.createUnbufferedStream().pipe(res);
|
|
105
116
|
})
|
|
106
117
|
.send();
|
|
@@ -109,20 +120,27 @@ const getPhoto = async (photoId: string, res: Express.Response): Promise<void> =
|
|
|
109
120
|
}
|
|
110
121
|
};
|
|
111
122
|
|
|
112
|
-
const download = (
|
|
123
|
+
const download = (
|
|
124
|
+
uri: string,
|
|
125
|
+
filename: string,
|
|
126
|
+
callback: () => void,
|
|
127
|
+
): void => {
|
|
113
128
|
request.head(uri, (err, res, body) => {
|
|
114
129
|
if (err) {
|
|
115
130
|
console.error(err);
|
|
116
131
|
return;
|
|
117
132
|
}
|
|
118
|
-
console.log(
|
|
119
|
-
console.log(
|
|
133
|
+
console.log("content-type:", res.headers["content-type"]);
|
|
134
|
+
console.log("content-length:", res.headers["content-length"]);
|
|
120
135
|
|
|
121
|
-
request(uri).pipe(fs.createWriteStream(filename)).on(
|
|
136
|
+
request(uri).pipe(fs.createWriteStream(filename)).on("close", callback);
|
|
122
137
|
});
|
|
123
138
|
};
|
|
124
139
|
|
|
125
|
-
const getPhotoFromUserImage = async (
|
|
140
|
+
const getPhotoFromUserImage = async (
|
|
141
|
+
photoId: string,
|
|
142
|
+
res: Express.Response,
|
|
143
|
+
): Promise<void> => {
|
|
126
144
|
try {
|
|
127
145
|
const params = {
|
|
128
146
|
Bucket: process.env.AWS_S3_BUCKET_NAME!,
|
|
@@ -131,9 +149,9 @@ const getPhotoFromUserImage = async (photoId: string, res: Express.Response): Pr
|
|
|
131
149
|
|
|
132
150
|
await s3
|
|
133
151
|
.getObject(params)
|
|
134
|
-
.on(
|
|
135
|
-
res.set(
|
|
136
|
-
res.set(
|
|
152
|
+
.on("httpHeaders", function (statusCode, headers) {
|
|
153
|
+
res.set("Content-Length", headers["content-length"]);
|
|
154
|
+
res.set("Content-Type", headers["content-type"]);
|
|
137
155
|
this.response.httpResponse.createUnbufferedStream().pipe(res);
|
|
138
156
|
})
|
|
139
157
|
.send();
|
|
@@ -142,4 +160,10 @@ const getPhotoFromUserImage = async (photoId: string, res: Express.Response): Pr
|
|
|
142
160
|
}
|
|
143
161
|
};
|
|
144
162
|
|
|
145
|
-
export default {
|
|
163
|
+
export default {
|
|
164
|
+
uploadFile,
|
|
165
|
+
uploadImage,
|
|
166
|
+
getPhoto,
|
|
167
|
+
getPhotoFromUserImage,
|
|
168
|
+
getSignedFileUrl,
|
|
169
|
+
};
|
package/src/i18n/i18n.ts
CHANGED
|
@@ -25,7 +25,7 @@ export function initI18n(options: InitI18nOptions = {}): typeof i18next {
|
|
|
25
25
|
const hasLocalesFolder = existsSync(localesFolder);
|
|
26
26
|
|
|
27
27
|
if (!i18next.isInitialized) {
|
|
28
|
-
i18next.use(Backend).init({
|
|
28
|
+
i18next.use(Backend as any).init({
|
|
29
29
|
initImmediate: false, // setting initImmediate to false, will load the resources synchronously
|
|
30
30
|
fallbackLng: "de",
|
|
31
31
|
preload: hasLocalesFolder
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Callback = (error: unknown, data?: unknown) => void;
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,54 @@
|
|
|
1
|
+
export { default as config } from "../src/config/config";
|
|
2
|
+
export { default as logger } from "../src/config/logger";
|
|
3
|
+
export { default as morgan } from "../src/config/morgan";
|
|
4
|
+
export { default as auth } from "../src/middlewares/auth";
|
|
5
|
+
export { errorConverter, errorHandler } from "../src/middlewares/error";
|
|
6
|
+
export { default as validate } from "../src/middlewares/validate";
|
|
7
|
+
export {
|
|
8
|
+
validateDevice,
|
|
9
|
+
validateDeviceIsInOrganization,
|
|
10
|
+
validateDeviceOrOrganizationQuery,
|
|
11
|
+
validateDeviceQuery,
|
|
12
|
+
} from "../src/middlewares/validateDevice";
|
|
13
|
+
export { initI18n } from "../src/i18n/i18n";
|
|
1
14
|
export { default as usersRoute } from "../src/users/users.route";
|
|
2
15
|
export { default as accountsRoute } from "../src/accounts/accounts.route";
|
|
16
|
+
export { default as accountsService } from "../src/accounts/accounts.service";
|
|
3
17
|
export { default as organizationsRoute } from "../src/organizations/organizations.route";
|
|
18
|
+
export { default as organizationsService } from "../src/organizations/organizations.service";
|
|
19
|
+
export { default as Organization } from "../src/organizations/organizations.model";
|
|
4
20
|
export { default as devicesRoute } from "../src/devices/devices.route";
|
|
21
|
+
export { default as devicesService } from "../src/devices/devices.service";
|
|
22
|
+
export { default as Device } from "../src/devices/devices.model";
|
|
23
|
+
export * from "../src/devices/devices.validation";
|
|
5
24
|
export { default as devicesNotificationsRoute } from "./devicesNotifications/devicesNotifications.route";
|
|
25
|
+
export { default as devicesNotificationsService } from "../src/devicesNotifications/devicesNotifications.service";
|
|
26
|
+
export { default as iotDevicesService } from "../src/iotdevice/iotdevice.service";
|
|
27
|
+
export { SIMILARITY_THRESHOLD } from "../src/iotdevice/iotdevice.service";
|
|
6
28
|
export { default as pdfRoute } from "../src/pdf/pdf.route";
|
|
7
29
|
export { default as tokensRoute } from "../src/tokens/tokens.route";
|
|
30
|
+
export * from "../src/tokens/tokens.service";
|
|
31
|
+
export { default as Token } from "../src/tokens/tokens.model";
|
|
32
|
+
export * as usersService from "../src/users/users.service";
|
|
33
|
+
export { User } from "../src/users/users.model";
|
|
34
|
+
export { isAdmin, validateAdmin } from "../src/middlewares/validateAdmin";
|
|
35
|
+
export { sendEmail } from "../src/email/email.service";
|
|
36
|
+
export { default as catchAsync } from "../src/utils/catchAsync";
|
|
37
|
+
export { default as buildRouterAndDocs } from "../src/utils/buildRouterAndDocs";
|
|
38
|
+
export type { RouteSpec } from "../src/utils/buildRouterAndDocs";
|
|
39
|
+
export { default as pick } from "../src/utils/pick";
|
|
40
|
+
export { paginate, toJSON } from "../src/models/plugins/index";
|
|
41
|
+
export { compareImages } from "../src/utils/comparePapers.service";
|
|
42
|
+
export { resolvePossiblyRelativeUrl } from "../src/utils/urlUtils";
|
|
43
|
+
export { getSignedFileUrl } from "../src/files/upload.service";
|
|
44
|
+
export * from "../src/utils/ApiError";
|
|
45
|
+
export * from "../src/utils/buildRouterAndDocs";
|
|
46
|
+
export * from "../src/utils/comparePapers.service";
|
|
47
|
+
export * from "../src/utils/deviceUtils";
|
|
48
|
+
export * from "../src/utils/filterOptions";
|
|
49
|
+
export * from "../src/utils/medicationName";
|
|
50
|
+
export * from "../src/utils/pick";
|
|
51
|
+
export * from "../src/utils/registerOpenApi";
|
|
52
|
+
export * from "../src/utils/urlUtils";
|
|
53
|
+
export * from "../src/utils/userName";
|
|
54
|
+
export * from "../src/utils/zValidations";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import mongoose, { Schema, Document, Model } from "mongoose";
|
|
3
|
+
import { toJSON, paginate } from "../models/plugins/index";
|
|
3
4
|
|
|
4
5
|
interface IotDeviceMeta {
|
|
5
6
|
[key: string]: any;
|
|
@@ -27,6 +28,8 @@ const iotDeviceSchema: Schema<IotDevice> = new mongoose.Schema(
|
|
|
27
28
|
iotDeviceSchema.plugin(toJSON);
|
|
28
29
|
iotDeviceSchema.plugin(paginate);
|
|
29
30
|
|
|
30
|
-
export const IotDevices: Model<IotDevice> =
|
|
31
|
+
export const IotDevices: Model<IotDevice> =
|
|
32
|
+
(mongoose.models.IotDevice as Model<IotDevice>) ||
|
|
33
|
+
mongoose.model<IotDevice>("IotDevice", iotDeviceSchema);
|
|
31
34
|
|
|
32
35
|
export default IotDevices;
|
|
@@ -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,3 +1,4 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import httpStatus from "http-status";
|
|
2
3
|
import axios from "axios";
|
|
3
4
|
import AWS from "aws-sdk";
|
|
@@ -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 });
|