@internetderdinge/api 1.229.3 → 1.229.4
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 +7 -5
- package/dist/src/accounts/accounts.validation.js +4 -12
- package/dist/src/accounts/auth0.service.js +14 -13
- package/dist/src/devices/devices.route.js +12 -2
- package/dist/src/devicesNotifications/devicesNotifications.controller.js +1 -0
- package/dist/src/middlewares/auth.js +2 -0
- package/dist/src/middlewares/validateAdmin.js +7 -5
- package/dist/src/users/users.route.js +0 -2
- package/dist/src/users/users.service.js +2 -0
- package/dist/src/users/users.validation.js +10 -16
- package/dist/src/utils/userName.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/accounts/accounts.controller.ts +8 -5
- package/src/accounts/accounts.validation.ts +19 -24
- package/src/accounts/auth0.service.ts +9 -5
- package/src/devices/devices.route.ts +11 -0
- package/src/devicesNotifications/devicesNotifications.controller.ts +2 -0
- package/src/middlewares/auth.ts +3 -1
- package/src/middlewares/validateAdmin.ts +18 -7
- package/src/users/users.route.ts +0 -2
- package/src/users/users.service.ts +14 -0
- package/src/users/users.validation.ts +10 -17
- package/src/utils/userName.ts +1 -1
|
@@ -10,13 +10,13 @@ const getAccountById = catchAsync(async (req, res) => {
|
|
|
10
10
|
throw new ApiError(httpStatus.NOT_FOUND, "Account not found");
|
|
11
11
|
}
|
|
12
12
|
res.send({
|
|
13
|
-
...account
|
|
13
|
+
...account,
|
|
14
14
|
notification: entryDeviceNotifications?.settings,
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
17
|
const setDeviceToken = catchAsync(async (req, res) => {
|
|
18
18
|
const account = await accountsService.getAccountById(req.auth.sub);
|
|
19
|
-
const devices = account.
|
|
19
|
+
const devices = account.app_metadata.devices || [];
|
|
20
20
|
const alreadyExisting = devices.find((d) => d.fck === req.body.token);
|
|
21
21
|
if (!alreadyExisting) {
|
|
22
22
|
devices.push({ fck: req.body.token });
|
|
@@ -34,7 +34,8 @@ const avatar = catchAsync(async (req, res) => {
|
|
|
34
34
|
});
|
|
35
35
|
const updateEntry = catchAsync(async (req, res) => {
|
|
36
36
|
const account = await accountsService.getAccountById(req.auth.sub);
|
|
37
|
-
|
|
37
|
+
console.log("account", account);
|
|
38
|
+
const { isSocial } = account.identities[0];
|
|
38
39
|
const { given_name, family_name, email, notification, ...updateBody } = req.body;
|
|
39
40
|
const trimmedGivenName = typeof given_name === "string" ? given_name.trim() : undefined;
|
|
40
41
|
const trimmedFamilyName = typeof family_name === "string" ? family_name.trim() : undefined;
|
|
@@ -42,7 +43,7 @@ const updateEntry = catchAsync(async (req, res) => {
|
|
|
42
43
|
const hasFamilyName = !!trimmedFamilyName;
|
|
43
44
|
const update = isSocial
|
|
44
45
|
? {
|
|
45
|
-
...account.
|
|
46
|
+
...account.app_metadata,
|
|
46
47
|
...updateBody,
|
|
47
48
|
...(hasGivenName ? { first_name: trimmedGivenName } : {}),
|
|
48
49
|
...(hasFamilyName ? { last_name: trimmedFamilyName } : {}),
|
|
@@ -75,7 +76,8 @@ const deleteCurrent = catchAsync(async (req, res) => {
|
|
|
75
76
|
});
|
|
76
77
|
const current = catchAsync(async (req, res) => {
|
|
77
78
|
const user = await accountsService.getAccountById(req.auth.sub);
|
|
78
|
-
|
|
79
|
+
console.log("user", user);
|
|
80
|
+
res.send(user);
|
|
79
81
|
});
|
|
80
82
|
const mfaEnroll = catchAsync(async (req, res) => {
|
|
81
83
|
const { mfaEnroll } = req.body;
|
|
@@ -23,9 +23,7 @@ export const createAccountSchema = {
|
|
|
23
23
|
export const getUsersSchema = zPagination;
|
|
24
24
|
export const getAccountSchema = {
|
|
25
25
|
params: z.object({
|
|
26
|
-
accountId: z
|
|
27
|
-
.string()
|
|
28
|
-
.openapi({
|
|
26
|
+
accountId: z.string().openapi({
|
|
29
27
|
example: process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
|
|
30
28
|
description: "Auth Account ID",
|
|
31
29
|
}),
|
|
@@ -33,9 +31,7 @@ export const getAccountSchema = {
|
|
|
33
31
|
};
|
|
34
32
|
export const updateAccountSchema = {
|
|
35
33
|
params: z.object({
|
|
36
|
-
accountId: z
|
|
37
|
-
.string()
|
|
38
|
-
.openapi({
|
|
34
|
+
accountId: z.string().openapi({
|
|
39
35
|
example: process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
|
|
40
36
|
description: "Auth Account ID",
|
|
41
37
|
}),
|
|
@@ -52,9 +48,7 @@ export const updateAccountSchema = {
|
|
|
52
48
|
.optional()
|
|
53
49
|
.openapi({ example: "female", description: "Gender" }),
|
|
54
50
|
email: z
|
|
55
|
-
.string()
|
|
56
|
-
.email()
|
|
57
|
-
.optional()
|
|
51
|
+
.preprocess((value) => (value === "" ? undefined : value), z.string().email().optional())
|
|
58
52
|
.openapi({ description: "User email address" }),
|
|
59
53
|
given_name: z
|
|
60
54
|
.string()
|
|
@@ -74,9 +68,7 @@ export const updateAccountSchema = {
|
|
|
74
68
|
};
|
|
75
69
|
export const deleteEntrySchema = {
|
|
76
70
|
params: z.object({
|
|
77
|
-
accountId: z
|
|
78
|
-
.string()
|
|
79
|
-
.openapi({
|
|
71
|
+
accountId: z.string().openapi({
|
|
80
72
|
example: process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
|
|
81
73
|
description: "Auth Account ID",
|
|
82
74
|
}),
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import { AuthenticationClient, ManagementClient } from "auth0";
|
|
3
|
-
import { promises as fs
|
|
3
|
+
import { promises as fs } from "fs";
|
|
4
4
|
let tokenManagementClient = {
|
|
5
5
|
clientId: process.env.AUTH0_CLIENT_ID,
|
|
6
6
|
clientSecret: process.env.AUTH0_CLIENT_SECRET,
|
|
7
7
|
};
|
|
8
8
|
//if (config.env !== 'production') {
|
|
9
|
+
/*
|
|
9
10
|
try {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
11
|
+
console.warn("Auth0 client: use local token from cache try");
|
|
12
|
+
const token = readFileSync("./token.txt", "utf8");
|
|
13
|
+
console.warn("Auth0 client: use local token from cache");
|
|
14
|
+
tokenManagementClient = { token };
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.log("Auth0 Client: use new token");
|
|
17
|
+
} */
|
|
18
18
|
//}
|
|
19
19
|
// IoT Api
|
|
20
20
|
/*
|
|
@@ -91,10 +91,10 @@ export const getAuth0Token = async () => {
|
|
|
91
91
|
pendingTokenPromise = null;
|
|
92
92
|
return cachedToken;
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
console.warn("Auth0 Client: Requesting new token from Auth0");
|
|
95
95
|
const tokenResponse = await auth0AuthClient.oauth.clientCredentialsGrant(grantOpts);
|
|
96
|
-
const expiresIn = tokenResponse.
|
|
97
|
-
cachedToken = tokenResponse.
|
|
96
|
+
const expiresIn = tokenResponse.expires_in || 3600;
|
|
97
|
+
cachedToken = tokenResponse.access_token;
|
|
98
98
|
tokenExpiresAt = now + expiresIn;
|
|
99
99
|
// if (process.env.NODE_ENV !== 'production') {
|
|
100
100
|
await writeTokenFile(TOKEN_FILE_PATH, cachedToken, tokenExpiresAt);
|
|
@@ -123,6 +123,7 @@ export const getAuth0ManagementToken = async () => {
|
|
|
123
123
|
pendingManagementTokenPromise = null;
|
|
124
124
|
return cachedManagementToken;
|
|
125
125
|
}
|
|
126
|
+
console.warn("Auth0 Management Client: Requesting new token from Auth0");
|
|
126
127
|
const tokenResponse = await auth0AuthClient.oauth.clientCredentialsGrant(grantOpts);
|
|
127
128
|
const expiresIn = tokenResponse.data.expires_in || 3600;
|
|
128
129
|
cachedManagementToken = tokenResponse.data.access_token;
|
|
@@ -173,7 +174,7 @@ export const getUsersByIds = async (postIDs) => {
|
|
|
173
174
|
page: 0,
|
|
174
175
|
};
|
|
175
176
|
const page = await auth0.users.list(params);
|
|
176
|
-
return page
|
|
177
|
+
return page || [];
|
|
177
178
|
};
|
|
178
179
|
export default {
|
|
179
180
|
auth0,
|
|
@@ -7,9 +7,9 @@ import { validateQuerySearchUserAndOrganization } from "../middlewares/validateQ
|
|
|
7
7
|
import { validateDevice } from "../middlewares/validateDevice.js";
|
|
8
8
|
import * as devicesController from "./devices.controller.js";
|
|
9
9
|
import { resetDevice } from "./devices.controller.js";
|
|
10
|
-
import { createDeviceSchema, queryDevicesSchema, getDeviceSchema, getEventsSchema, pingDeviceSchema, registerDeviceSchema, ledLightSchema, rebootDeviceSchema, getImageSchema, updateSingleImageMetaSchema, uploadSingleImageSchema, resetDeviceSchema, } from "./devices.validation.js";
|
|
10
|
+
import { createDeviceSchema, queryDevicesSchema, getDeviceSchema, updateDeviceSchema, getEventsSchema, pingDeviceSchema, registerDeviceSchema, ledLightSchema, rebootDeviceSchema, getImageSchema, updateSingleImageMetaSchema, uploadSingleImageSchema, resetDeviceSchema, } from "./devices.validation.js";
|
|
11
11
|
import { deviceResponseSchema, devicesResponseSchema, eventResponseSchema, genericResponseSchema, imageResponseSchema, uploadResponseSchema, resetResponseSchema, } from "./devices.schemas.js";
|
|
12
|
-
import { validateOrganizationDelete, } from "../middlewares/validateAction.js";
|
|
12
|
+
import { validateOrganizationDelete, validateOrganizationUpdate, } from "../middlewares/validateAction.js";
|
|
13
13
|
export const devicesRouteSpecs = [
|
|
14
14
|
{
|
|
15
15
|
method: "post",
|
|
@@ -58,6 +58,16 @@ export const devicesRouteSpecs = [
|
|
|
58
58
|
{
|
|
59
59
|
method: "post",
|
|
60
60
|
path: "/:deviceId",
|
|
61
|
+
validate: [auth("manageUsers"), validateDevice, validateOrganizationUpdate],
|
|
62
|
+
requestSchema: updateDeviceSchema,
|
|
63
|
+
responseSchema: deviceResponseSchema,
|
|
64
|
+
handler: devicesController.updateEntry,
|
|
65
|
+
summary: "Update a device",
|
|
66
|
+
description: "Modify the properties of an existing device identified by its ID.",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
method: "delete",
|
|
70
|
+
path: "/:deviceId",
|
|
61
71
|
handler: devicesController.deleteEntry,
|
|
62
72
|
summary: "Delete a device",
|
|
63
73
|
description: "Remove the specified device from the system.",
|
|
@@ -16,6 +16,7 @@ export const setDeviceToken = catchAsync(async (req, res) => {
|
|
|
16
16
|
user: res.req.auth.sub,
|
|
17
17
|
body: req.body,
|
|
18
18
|
});
|
|
19
|
+
console.log("Setting device tokenddddd for user:", res.req.auth.sub);
|
|
19
20
|
res.status(httpStatus.CREATED).send(user);
|
|
20
21
|
});
|
|
21
22
|
export const removeDeviceToken = catchAsync(async (req, res) => {
|
|
@@ -20,8 +20,10 @@ const verifyCallback = (req, resolve, reject, requiredRights) => async (err, use
|
|
|
20
20
|
resolve();
|
|
21
21
|
};
|
|
22
22
|
const auth = function authFactory(...requiredRights) {
|
|
23
|
+
console.log("Creating auth middleware with required rights:", requiredRights);
|
|
23
24
|
return async function authMiddleware(req, res, next) {
|
|
24
25
|
try {
|
|
26
|
+
console.log("Authenticating request:");
|
|
25
27
|
// Check for custom token in X-API-Key header
|
|
26
28
|
const apiKey = req.headers["x-api-key"];
|
|
27
29
|
if (apiKey && apiKey.length === 64) {
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import httpStatus from
|
|
2
|
-
import ApiError from
|
|
1
|
+
import httpStatus from "http-status";
|
|
2
|
+
import ApiError from "../utils/ApiError";
|
|
3
3
|
const isAdmin = (user) => {
|
|
4
|
-
|
|
4
|
+
return false;
|
|
5
5
|
if (!user)
|
|
6
6
|
return false;
|
|
7
7
|
// return false; // TODO: Remove this line when the user object is properly defined
|
|
8
|
-
return user[
|
|
8
|
+
return user["https://memo.wirewire.de/roles"]
|
|
9
|
+
? user["https://memo.wirewire.de/roles"].includes("admin")
|
|
10
|
+
: false;
|
|
9
11
|
};
|
|
10
12
|
const validateAdmin = async (req, res, next) => {
|
|
11
13
|
if (isAdmin(req.auth)) {
|
|
12
14
|
next();
|
|
13
15
|
}
|
|
14
16
|
else {
|
|
15
|
-
next(new ApiError(httpStatus.FORBIDDEN,
|
|
17
|
+
next(new ApiError(httpStatus.FORBIDDEN, "User is not part of the admin group (validateAdmin)"));
|
|
16
18
|
}
|
|
17
19
|
};
|
|
18
20
|
export { isAdmin, validateAdmin };
|
|
@@ -108,7 +108,6 @@ export const userRouteSpecs = [
|
|
|
108
108
|
handler: userController.updateUser,
|
|
109
109
|
summary: "Update a user by ID",
|
|
110
110
|
description: "Replaces a user’s full record with the provided data.",
|
|
111
|
-
memoOnly: true,
|
|
112
111
|
},
|
|
113
112
|
{
|
|
114
113
|
method: "patch",
|
|
@@ -119,7 +118,6 @@ export const userRouteSpecs = [
|
|
|
119
118
|
handler: userController.updateUser,
|
|
120
119
|
summary: "Partially update a user by ID",
|
|
121
120
|
description: "Applies partial updates to a user’s record by ID.",
|
|
122
|
-
memoOnly: true,
|
|
123
121
|
},
|
|
124
122
|
{
|
|
125
123
|
method: "delete",
|
|
@@ -104,7 +104,9 @@ export const getUserByOwner = async (owner, organization) => {
|
|
|
104
104
|
const user = await User.findOne({ owner, organization });
|
|
105
105
|
if (!user)
|
|
106
106
|
return null;
|
|
107
|
+
console.log("Found user for owner and organization:", owner, organization, user);
|
|
107
108
|
const auth0User = await populateAuth0User(user);
|
|
109
|
+
console.log("Found user for owner and organizationddddddd:", owner, organization, user);
|
|
108
110
|
const json = user.toJSON();
|
|
109
111
|
json.auth0User = auth0User;
|
|
110
112
|
return json;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
|
|
4
|
-
import { password } from "../validations/custom.validation.js";
|
|
5
4
|
import { zPagination, zGet, zObjectId, zObjectIdFor, zPatchBody, zUpdate, zDelete, } from "../utils/zValidations.js";
|
|
6
5
|
extendZodWithOpenApi(z);
|
|
7
6
|
export const createUserSchema = {
|
|
@@ -55,19 +54,6 @@ export const getCurrentUserSchema = {
|
|
|
55
54
|
export const updateUserSchema = {
|
|
56
55
|
...zUpdate("userId"),
|
|
57
56
|
body: zPatchBody({
|
|
58
|
-
password: z
|
|
59
|
-
.string()
|
|
60
|
-
.refine((val) => {
|
|
61
|
-
try {
|
|
62
|
-
password(val);
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
}, { message: "Invalid password format" })
|
|
69
|
-
.optional()
|
|
70
|
-
.openapi({ description: "New user password" }),
|
|
71
57
|
name: z.string().optional().openapi({ description: "User full name" }),
|
|
72
58
|
timezone: z.string().optional().openapi({ description: "IANA timezone" }),
|
|
73
59
|
avatar: z.string().optional().openapi({ description: "Avatar URL" }),
|
|
@@ -89,7 +75,11 @@ export const updateUserSchema = {
|
|
|
89
75
|
.enum(["user", "admin", "patient", "onlyself"])
|
|
90
76
|
.optional()
|
|
91
77
|
.openapi({ description: "User role" }),
|
|
92
|
-
inviteCode: z
|
|
78
|
+
inviteCode: z
|
|
79
|
+
.string()
|
|
80
|
+
.nullable()
|
|
81
|
+
.optional()
|
|
82
|
+
.openapi({ description: "Invite code" }),
|
|
93
83
|
organization: zObjectId
|
|
94
84
|
.optional()
|
|
95
85
|
.openapi({ description: "Organization ObjectId" }),
|
|
@@ -107,7 +97,11 @@ export const updateInviteSchema = {
|
|
|
107
97
|
body: z.object({
|
|
108
98
|
organization: zObjectId.openapi({ description: "Organization ObjectId" }),
|
|
109
99
|
status: z.enum(["accepted"]).openapi({ description: "Invite status" }),
|
|
110
|
-
inviteCode: z
|
|
100
|
+
inviteCode: z
|
|
101
|
+
.string()
|
|
102
|
+
.nullable()
|
|
103
|
+
.optional()
|
|
104
|
+
.openapi({ description: "Invite code" }),
|
|
111
105
|
}),
|
|
112
106
|
};
|
|
113
107
|
export const organizationRemoveSchema = {
|
|
@@ -3,7 +3,7 @@ import { getUserById } from "../accounts/auth0.service";
|
|
|
3
3
|
const generateUserName = async (patient) => {
|
|
4
4
|
if (patient.owner) {
|
|
5
5
|
const auth0UserById = await getUserById(patient.owner);
|
|
6
|
-
patient.auth0User = auth0UserById
|
|
6
|
+
patient.auth0User = auth0UserById;
|
|
7
7
|
}
|
|
8
8
|
if (patient?.auth0User?.app_metadata?.first_name) {
|
|
9
9
|
return `${patient.auth0User.app_metadata.first_name} ${patient.auth0User.app_metadata.last_name}`;
|