@internetderdinge/api 1.229.2 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetderdinge/api",
3
- "version": "1.229.2",
3
+ "version": "1.229.4",
4
4
  "description": "Shared OpenIoT API modules",
5
5
  "main": "dist/src/index.js",
6
6
  "type": "module",
@@ -36,7 +36,7 @@ const getAccountById = catchAsync(
36
36
  throw new ApiError(httpStatus.NOT_FOUND, "Account not found");
37
37
  }
38
38
  res.send({
39
- ...account.data,
39
+ ...account,
40
40
  notification: entryDeviceNotifications?.settings,
41
41
  });
42
42
  },
@@ -46,7 +46,7 @@ const setDeviceToken = catchAsync(
46
46
  async (req: AuthenticatedRequest, res: Response): Promise<void> => {
47
47
  const account = await accountsService.getAccountById(req.auth.sub);
48
48
 
49
- const devices: Device[] = account.data.app_metadata.devices || [];
49
+ const devices: Device[] = account.app_metadata.devices || [];
50
50
  const alreadyExisting = devices.find((d) => d.fck === req.body.token);
51
51
  if (!alreadyExisting) {
52
52
  devices.push({ fck: req.body.token });
@@ -74,7 +74,9 @@ const updateEntry = catchAsync(
74
74
  async (req: AuthenticatedRequest, res: Response): Promise<void> => {
75
75
  const account = await accountsService.getAccountById(req.auth.sub);
76
76
 
77
- const { isSocial } = account?.data.identities[0];
77
+ console.log("account", account);
78
+
79
+ const { isSocial } = account.identities[0];
78
80
 
79
81
  const {
80
82
  given_name,
@@ -93,7 +95,7 @@ const updateEntry = catchAsync(
93
95
 
94
96
  const update = isSocial
95
97
  ? {
96
- ...account.data.app_metadata,
98
+ ...account.app_metadata,
97
99
  ...updateBody,
98
100
  ...(hasGivenName ? { first_name: trimmedGivenName } : {}),
99
101
  ...(hasFamilyName ? { last_name: trimmedFamilyName } : {}),
@@ -136,7 +138,8 @@ const deleteCurrent = catchAsync(
136
138
  const current = catchAsync(
137
139
  async (req: AuthenticatedRequest, res: Response): Promise<void> => {
138
140
  const user = await accountsService.getAccountById(req.auth.sub);
139
- res.send(user.data);
141
+ console.log("user", user);
142
+ res.send(user);
140
143
  },
141
144
  );
142
145
 
@@ -10,7 +10,7 @@ type Stock = any; // Replace with the actual Stock type if available
10
10
  * @returns {Promise<Stock>}
11
11
  */
12
12
  export const getAccountById = async (id: ObjectId): Promise<Stock> => {
13
- return auth0.users.get({ id });
13
+ return auth0.users.get(id);
14
14
  };
15
15
 
16
16
  /**
@@ -54,7 +54,7 @@ export const updateMetaDataById = async (
54
54
  updateBody: Record<string, any>,
55
55
  ): Promise<Stock> => {
56
56
  // now use the generic update and pass app_metadata
57
- return auth0.users.update({ id }, { app_metadata: updateBody });
57
+ return auth0.users.update(id, { app_metadata: updateBody });
58
58
  };
59
59
 
60
60
  /**
@@ -65,14 +65,14 @@ export const updateUserById = async (
65
65
  updateBody: Record<string, any>,
66
66
  ): Promise<Stock> => {
67
67
  // switch to the v3 ManagementClient users.update
68
- return auth0.users.update({ id }, updateBody);
68
+ return auth0.users.update(id, updateBody);
69
69
  };
70
70
 
71
71
  /**
72
72
  * Delete user by id
73
73
  */
74
74
  export const deleteById = async (userId: ObjectId): Promise<Stock> => {
75
- return auth0.users.delete({ id: userId });
75
+ return auth0.users.delete(userId);
76
76
  };
77
77
 
78
78
  export default {
@@ -35,25 +35,21 @@ export const getUsersSchema = zPagination;
35
35
 
36
36
  export const getAccountSchema = {
37
37
  params: z.object({
38
- accountId: z
39
- .string()
40
- .openapi({
41
- example:
42
- process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
43
- description: "Auth Account ID",
44
- }),
38
+ accountId: z.string().openapi({
39
+ example:
40
+ process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
41
+ description: "Auth Account ID",
42
+ }),
45
43
  }),
46
44
  };
47
45
 
48
46
  export const updateAccountSchema = {
49
47
  params: z.object({
50
- accountId: z
51
- .string()
52
- .openapi({
53
- example:
54
- process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
55
- description: "Auth Account ID",
56
- }),
48
+ accountId: z.string().openapi({
49
+ example:
50
+ process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
51
+ description: "Auth Account ID",
52
+ }),
57
53
  }),
58
54
  body: zPatchBody({
59
55
  language: z
@@ -67,9 +63,10 @@ export const updateAccountSchema = {
67
63
  .optional()
68
64
  .openapi({ example: "female", description: "Gender" }),
69
65
  email: z
70
- .string()
71
- .email()
72
- .optional()
66
+ .preprocess(
67
+ (value) => (value === "" ? undefined : value),
68
+ z.string().email().optional(),
69
+ )
73
70
  .openapi({ description: "User email address" }),
74
71
  given_name: z
75
72
  .string()
@@ -90,13 +87,11 @@ export const updateAccountSchema = {
90
87
 
91
88
  export const deleteEntrySchema = {
92
89
  params: z.object({
93
- accountId: z
94
- .string()
95
- .openapi({
96
- example:
97
- process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
98
- description: "Auth Account ID",
99
- }),
90
+ accountId: z.string().openapi({
91
+ example:
92
+ process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
93
+ description: "Auth Account ID",
94
+ }),
100
95
  }),
101
96
  };
102
97
 
@@ -21,6 +21,7 @@ let tokenManagementClient: TokenManagementClient = {
21
21
  };
22
22
 
23
23
  //if (config.env !== 'production') {
24
+ /*
24
25
  try {
25
26
  console.warn("Auth0 client: use local token from cache try");
26
27
  const token = readFileSync("./token.txt", "utf8");
@@ -28,7 +29,7 @@ try {
28
29
  tokenManagementClient = { token };
29
30
  } catch (error) {
30
31
  console.log("Auth0 Client: use new token");
31
- }
32
+ } */
32
33
  //}
33
34
 
34
35
  // IoT Api
@@ -123,12 +124,12 @@ export const getAuth0Token = async (): Promise<string> => {
123
124
  pendingTokenPromise = null;
124
125
  return cachedToken;
125
126
  }
126
- //}
127
127
 
128
+ console.warn("Auth0 Client: Requesting new token from Auth0");
128
129
  const tokenResponse =
129
130
  await auth0AuthClient.oauth.clientCredentialsGrant(grantOpts);
130
- const expiresIn = tokenResponse.data.expires_in || 3600;
131
- cachedToken = tokenResponse.data.access_token;
131
+ const expiresIn = tokenResponse.expires_in || 3600;
132
+ cachedToken = tokenResponse.access_token;
132
133
  tokenExpiresAt = now + expiresIn;
133
134
 
134
135
  // if (process.env.NODE_ENV !== 'production') {
@@ -159,6 +160,7 @@ export const getAuth0ManagementToken = async (): Promise<string> => {
159
160
 
160
161
  pendingManagementTokenPromise = (async () => {
161
162
  const fileToken = await loadTokenFromFile(MANAGEMENT_TOKEN_FILE_PATH);
163
+
162
164
  if (fileToken && fileToken.expiresAt > now + TOKEN_BUFFER_SECONDS) {
163
165
  cachedManagementToken = fileToken.token;
164
166
  managementTokenExpiresAt = fileToken.expiresAt;
@@ -166,8 +168,10 @@ export const getAuth0ManagementToken = async (): Promise<string> => {
166
168
  return cachedManagementToken;
167
169
  }
168
170
 
171
+ console.warn("Auth0 Management Client: Requesting new token from Auth0");
169
172
  const tokenResponse =
170
173
  await auth0AuthClient.oauth.clientCredentialsGrant(grantOpts);
174
+
171
175
  const expiresIn = tokenResponse.data.expires_in || 3600;
172
176
  cachedManagementToken = tokenResponse.data.access_token;
173
177
  managementTokenExpiresAt = now + expiresIn;
@@ -192,27 +196,26 @@ export const auth0 = new ManagementClient({
192
196
  });
193
197
 
194
198
  export const getUserIdByEmail = async (email: string): Promise<User[]> => {
195
- // use the users resource to look up by email
196
- return auth0.usersByEmail.getByEmail({ email });
199
+ return auth0.users.listUsersByEmail({ email });
197
200
  };
198
201
 
199
202
  export const sendVerificationEmail = async (userID: string): Promise<any> => {
200
- return auth0.jobs.verifyEmail({ user_id: userID });
203
+ return auth0.tickets.verifyEmail({ user_id: userID });
201
204
  };
202
205
 
203
206
  export const getUserById = async (userId: string): Promise<User> => {
204
- return auth0.users.get({ id: userId });
207
+ return auth0.users.get(userId);
205
208
  };
206
209
 
207
210
  export const avatar = async (userId: string): Promise<User> => {
208
- return auth0.users.get({ id: userId });
211
+ return auth0.users.get(userId);
209
212
  };
210
213
 
211
214
  export const mfaEnrollAccount = async (
212
215
  userId: string,
213
216
  mfaToken: string,
214
217
  ): Promise<any> => {
215
- const ticketResponse = await auth0.guardian.createEnrollmentTicket({
218
+ const ticketResponse = await auth0.guardian.enrollments.createTicket({
216
219
  user_id: userId,
217
220
  send_mail: false,
218
221
  });
@@ -221,15 +224,15 @@ export const mfaEnrollAccount = async (
221
224
  };
222
225
 
223
226
  export const mfaDisableAccount = async (userId: string): Promise<any> => {
224
- await auth0.users.deleteAuthenticationMethods({ id: userId });
227
+ await auth0.users.authenticationMethods.deleteAll(userId);
225
228
  return { success: true };
226
229
  };
227
230
 
228
231
  export const getUsersByIds = async (postIDs: string[]): Promise<User[]> => {
229
- let q = "";
230
- postIDs.forEach((e, i) => {
231
- if (e) q = `${q} ${i >= 2 ? " OR " : ""} user_id:"${e}"`;
232
- });
232
+ const userIds = postIDs.filter(Boolean);
233
+ if (!userIds.length) return [];
234
+
235
+ const q = userIds.map((id) => `user_id:"${id}"`).join(" OR ");
233
236
 
234
237
  const params = {
235
238
  search_engine: "v3",
@@ -238,7 +241,8 @@ export const getUsersByIds = async (postIDs: string[]): Promise<User[]> => {
238
241
  page: 0,
239
242
  };
240
243
 
241
- return auth0.users.getAll(params);
244
+ const page = await auth0.users.list(params);
245
+ return page || [];
242
246
  };
243
247
 
244
248
  export default {
@@ -94,6 +94,17 @@ export const devicesRouteSpecs: RouteSpec[] = [
94
94
  {
95
95
  method: "post",
96
96
  path: "/:deviceId",
97
+ validate: [auth("manageUsers"), validateDevice, validateOrganizationUpdate],
98
+ requestSchema: updateDeviceSchema,
99
+ responseSchema: deviceResponseSchema,
100
+ handler: devicesController.updateEntry,
101
+ summary: "Update a device",
102
+ description:
103
+ "Modify the properties of an existing device identified by its ID.",
104
+ },
105
+ {
106
+ method: "delete",
107
+ path: "/:deviceId",
97
108
  handler: devicesController.deleteEntry,
98
109
  summary: "Delete a device",
99
110
  description: "Remove the specified device from the system.",
@@ -22,6 +22,8 @@ export const setDeviceToken = catchAsync(
22
22
  user: res.req.auth.sub,
23
23
  body: req.body,
24
24
  });
25
+
26
+ console.log("Setting device tokenddddd for user:", res.req.auth.sub);
25
27
  res.status(httpStatus.CREATED).send(user);
26
28
  },
27
29
  );
@@ -36,17 +36,18 @@ const verifyCallback: VerifyCallback =
36
36
  return reject(new ApiError(httpStatus.FORBIDDEN, "Forbidden"));
37
37
  }
38
38
  }
39
-
40
39
  resolve();
41
40
  };
42
41
 
43
42
  const auth = function authFactory(...requiredRights: string[]) {
43
+ console.log("Creating auth middleware with required rights:", requiredRights);
44
44
  return async function authMiddleware(
45
45
  req: AuthRequest,
46
46
  res: Response,
47
47
  next: NextFunction,
48
48
  ): Promise<void> {
49
49
  try {
50
+ console.log("Authenticating request:");
50
51
  // Check for custom token in X-API-Key header
51
52
  const apiKey = req.headers["x-api-key"] as string | undefined;
52
53
  if (apiKey && apiKey.length === 64) {
@@ -93,6 +94,7 @@ const auth = function authFactory(...requiredRights: string[]) {
93
94
  err.message || "Sorry we were unable to process your request.";
94
95
  return res.status(status).send({ message });
95
96
  }
97
+
96
98
  next();
97
99
  });
98
100
  } catch (error) {
@@ -1,20 +1,31 @@
1
- import httpStatus from 'http-status';
2
- import ApiError from '../utils/ApiError';
3
- import type { Request, Response, NextFunction } from 'express';
1
+ import httpStatus from "http-status";
2
+ import ApiError from "../utils/ApiError";
3
+ import type { Request, Response, NextFunction } from "express";
4
4
 
5
5
  const isAdmin = (user: Record<string, any> | undefined): boolean => {
6
- //return false;
6
+ return false;
7
7
  if (!user) return false;
8
8
 
9
9
  // return false; // TODO: Remove this line when the user object is properly defined
10
- return user['https://memo.wirewire.de/roles'] ? user['https://memo.wirewire.de/roles'].includes('admin') : false;
10
+ return user["https://memo.wirewire.de/roles"]
11
+ ? user["https://memo.wirewire.de/roles"].includes("admin")
12
+ : false;
11
13
  };
12
14
 
13
- const validateAdmin = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
15
+ const validateAdmin = async (
16
+ req: Request,
17
+ res: Response,
18
+ next: NextFunction,
19
+ ): Promise<void> => {
14
20
  if (isAdmin(req.auth)) {
15
21
  next();
16
22
  } else {
17
- next(new ApiError(httpStatus.FORBIDDEN, 'User is not part of the admin group (validateAdmin)'));
23
+ next(
24
+ new ApiError(
25
+ httpStatus.FORBIDDEN,
26
+ "User is not part of the admin group (validateAdmin)",
27
+ ),
28
+ );
18
29
  }
19
30
  };
20
31
 
@@ -138,7 +138,6 @@ export const userRouteSpecs: RouteSpec[] = [
138
138
  handler: userController.updateUser,
139
139
  summary: "Update a user by ID",
140
140
  description: "Replaces a user’s full record with the provided data.",
141
- memoOnly: true,
142
141
  },
143
142
  {
144
143
  method: "patch",
@@ -149,7 +148,6 @@ export const userRouteSpecs: RouteSpec[] = [
149
148
  handler: userController.updateUser,
150
149
  summary: "Partially update a user by ID",
151
150
  description: "Applies partial updates to a user’s record by ID.",
152
- memoOnly: true,
153
151
  },
154
152
  {
155
153
  method: "delete",
@@ -149,7 +149,21 @@ export const getUserByOwner = async (
149
149
  ): Promise<any | null> => {
150
150
  const user = await User.findOne({ owner, organization });
151
151
  if (!user) return null;
152
+
153
+ console.log(
154
+ "Found user for owner and organization:",
155
+ owner,
156
+ organization,
157
+ user,
158
+ );
152
159
  const auth0User = await populateAuth0User(user);
160
+
161
+ console.log(
162
+ "Found user for owner and organizationddddddd:",
163
+ owner,
164
+ organization,
165
+ user,
166
+ );
153
167
  const json = user.toJSON();
154
168
  json.auth0User = auth0User;
155
169
  return json;
@@ -71,21 +71,6 @@ export const getCurrentUserSchema = {
71
71
  export const updateUserSchema = {
72
72
  ...zUpdate("userId"),
73
73
  body: zPatchBody({
74
- password: z
75
- .string()
76
- .refine(
77
- (val) => {
78
- try {
79
- password(val);
80
- return true;
81
- } catch {
82
- return false;
83
- }
84
- },
85
- { message: "Invalid password format" },
86
- )
87
- .optional()
88
- .openapi({ description: "New user password" }),
89
74
  name: z.string().optional().openapi({ description: "User full name" }),
90
75
  timezone: z.string().optional().openapi({ description: "IANA timezone" }),
91
76
  avatar: z.string().optional().openapi({ description: "Avatar URL" }),
@@ -107,7 +92,11 @@ export const updateUserSchema = {
107
92
  .enum(["user", "admin", "patient", "onlyself"])
108
93
  .optional()
109
94
  .openapi({ description: "User role" }),
110
- inviteCode: z.string().optional().openapi({ description: "Invite code" }),
95
+ inviteCode: z
96
+ .string()
97
+ .nullable()
98
+ .optional()
99
+ .openapi({ description: "Invite code" }),
111
100
  organization: zObjectId
112
101
  .optional()
113
102
  .openapi({ description: "Organization ObjectId" }),
@@ -128,7 +117,11 @@ export const updateInviteSchema = {
128
117
  body: z.object({
129
118
  organization: zObjectId.openapi({ description: "Organization ObjectId" }),
130
119
  status: z.enum(["accepted"]).openapi({ description: "Invite status" }),
131
- inviteCode: z.string().optional().openapi({ description: "Invite code" }),
120
+ inviteCode: z
121
+ .string()
122
+ .nullable()
123
+ .optional()
124
+ .openapi({ description: "Invite code" }),
132
125
  }),
133
126
  };
134
127
 
@@ -69,8 +69,6 @@ export default function buildAiRouterAndDocs(
69
69
  };
70
70
  }
71
71
 
72
- console.log("spec.requestScbn");
73
-
74
72
  if (
75
73
  spec.responseSchema &&
76
74
  !hasRoleValidation(spec.validate) &&
@@ -5,7 +5,7 @@ import type { Patient } from "../types/patient"; // Assuming a `Patient` type ex
5
5
  const generateUserName = async (patient: Patient): Promise<string | null> => {
6
6
  if (patient.owner) {
7
7
  const auth0UserById = await getUserById(patient.owner);
8
- patient.auth0User = auth0UserById.data;
8
+ patient.auth0User = auth0UserById;
9
9
  }
10
10
 
11
11
  if (patient?.auth0User?.app_metadata?.first_name) {