@internetderdinge/api 1.229.32 → 1.229.39

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.
Files changed (54) hide show
  1. package/dist/src/accounts/accounts.route.js +18 -5
  2. package/dist/src/admin/adminSearch.controller.js +0 -19
  3. package/dist/src/admin/adminSearch.route.js +5 -5
  4. package/dist/src/devices/devices.controller.js +4 -6
  5. package/dist/src/devices/devices.route.js +14 -14
  6. package/dist/src/devices/devices.validation.js +15 -54
  7. package/dist/src/email/email.service.js +6 -6
  8. package/dist/src/index.js +5 -1
  9. package/dist/src/iotdevice/iotdevice.route.js +3 -1
  10. package/dist/src/iotdevice/iotdevice.service.js +5 -5
  11. package/dist/src/iotdevice/iotdevice.validation.js +12 -4
  12. package/dist/src/middlewares/validateAdminOrSupport.js +20 -0
  13. package/dist/src/organizations/organizations.controller.js +17 -6
  14. package/dist/src/organizations/organizations.route.js +2 -1
  15. package/dist/src/users/users.model.js +4 -2
  16. package/dist/src/users/users.route.js +2 -2
  17. package/dist/src/users/users.service.js +26 -10
  18. package/dist/src/users/users.validation.js +60 -61
  19. package/dist/src/utils/buildRouterAndDocs.js +7 -4
  20. package/dist/src/utils/zValidations.js +7 -0
  21. package/package.json +5 -2
  22. package/scripts/release-and-sync-paperless.mjs +21 -2
  23. package/scripts/release-version.mjs +21 -2
  24. package/src/accounts/accounts.route.ts +21 -5
  25. package/src/admin/adminSearch.controller.ts +0 -35
  26. package/src/admin/adminSearch.route.ts +8 -6
  27. package/src/admin/adminSearch.service.ts +6 -10
  28. package/src/devices/devices.controller.ts +4 -12
  29. package/src/devices/devices.route.ts +14 -15
  30. package/src/devices/devices.validation.ts +20 -54
  31. package/src/email/email.service.ts +15 -7
  32. package/src/index.ts +5 -1
  33. package/src/iotdevice/iotdevice.route.ts +3 -1
  34. package/src/iotdevice/iotdevice.service.ts +8 -7
  35. package/src/iotdevice/iotdevice.validation.ts +12 -4
  36. package/src/middlewares/validateAdminOrSupport.ts +34 -0
  37. package/src/organizations/organizations.controller.ts +38 -7
  38. package/src/organizations/organizations.route.ts +3 -1
  39. package/src/users/users.model.ts +7 -3
  40. package/src/users/users.route.ts +3 -2
  41. package/src/users/users.service.ts +50 -14
  42. package/src/users/users.validation.ts +62 -60
  43. package/src/utils/buildRouterAndDocs.ts +14 -5
  44. package/src/utils/zValidations.ts +8 -0
  45. package/dist/src/pdf/pdf.controller.js +0 -24
  46. package/dist/src/pdf/pdf.route.js +0 -22
  47. package/dist/src/pdf/pdf.schemas.js +0 -6
  48. package/dist/src/pdf/pdf.service.js +0 -64
  49. package/dist/src/pdf/pdf.validation.js +0 -27
  50. package/src/pdf/pdf.controller.ts +0 -35
  51. package/src/pdf/pdf.route.ts +0 -28
  52. package/src/pdf/pdf.schemas.ts +0 -7
  53. package/src/pdf/pdf.service.ts +0 -103
  54. package/src/pdf/pdf.validation.ts +0 -30
@@ -9,6 +9,7 @@ import {
9
9
  zUpdate,
10
10
  zDelete,
11
11
  zPagination,
12
+ zTypeFilter,
12
13
  } from "../utils/zValidations.js";
13
14
 
14
15
  extendZodWithOpenApi(z);
@@ -73,9 +74,9 @@ export const getEventsSchema = {
73
74
  }),
74
75
  query: z
75
76
  .object({
76
- DateStart: z.string(),
77
- DateEnd: z.string(),
78
- TypeFilter: z.string().optional(),
77
+ DateStart: z.string().datetime().optional(),
78
+ DateEnd: z.string().datetime().optional(),
79
+ TypeFilter: zTypeFilter,
79
80
  })
80
81
  .openapi({ description: "Fetch device events in a time range" }),
81
82
  };
@@ -112,53 +113,6 @@ export const createDeviceSchema = {
112
113
  };
113
114
  export const deleteDeviceSchema = zDelete("deviceId");
114
115
  export const getDeviceSchema = zGet("deviceId");
115
- export const ledLightSchema = {
116
- params: z.object({
117
- deviceId: zObjectId.openapi({ description: "Device ObjectId" }),
118
- }),
119
- body: z
120
- .object({
121
- led: z.array(z.tuple([z.number().int(), z.number().int()])),
122
- timeout: z.number().int(),
123
- })
124
- .openapi({
125
- description: "LED light configuration for device",
126
- example: {
127
- led: [
128
- [0, 0],
129
- [1, 0],
130
- [2, 0],
131
- [3, 0],
132
- [4, 0],
133
- [5, 0],
134
- [6, 0],
135
- [7, 0],
136
- [8, 0],
137
- [9, 0],
138
- [10, 0],
139
- [11, 0],
140
- [12, 0],
141
- [13, 0],
142
- [14, 0],
143
- [15, 100],
144
- [16, 100],
145
- [17, 100],
146
- [18, 100],
147
- [19, 100],
148
- [20, 100],
149
- [21, 100],
150
- [22, 0],
151
- [23, 0],
152
- [24, 0],
153
- [25, 0],
154
- [26, 0],
155
- [27, 0],
156
- [28, 0],
157
- ],
158
- timeout: 40,
159
- },
160
- }),
161
- };
162
116
  export const pingDeviceSchema = {
163
117
  params: z.object({
164
118
  deviceId: zObjectIdFor("deviceId").openapi({
@@ -215,16 +169,28 @@ export const registerDeviceSchema = {
215
169
 
216
170
  export const queryDevicesSchema = {
217
171
  ...zPagination,
218
- query: zPagination.query.extend({
219
- patient: zObjectIdFor("patient").optional(),
220
- organization: zObjectIdFor("organization").optional(),
221
- }),
172
+ query: zPagination.query
173
+ .extend({
174
+ patient: zObjectIdFor("patient").optional().openapi({
175
+ description:
176
+ "Patient ObjectId. Required if organization is not provided.",
177
+ }),
178
+ organization: zObjectIdFor("organization").optional().openapi({
179
+ description:
180
+ "Organization ObjectId. Required if patient is not provided.",
181
+ }),
182
+ })
183
+ .refine((data) => data.patient || data.organization, {
184
+ message: "Either patient or organization is required",
185
+ }),
222
186
  };
187
+
223
188
  export const subscriptionSchema = {
224
189
  params: z.object({
225
190
  deviceId: zObjectId.openapi({ description: "Device ObjectId" }),
226
191
  }),
227
192
  };
193
+
228
194
  export const uploadSingleImageFromWebsiteSchema = {};
229
195
  export const updateDeviceSchema = {
230
196
  ...zUpdate("deviceId"),
@@ -54,11 +54,15 @@ const actionButton = ({
54
54
  </table>`;
55
55
  };
56
56
 
57
- interface SendEmailParams {
57
+ export interface SendEmailParams {
58
58
  title?: string;
59
59
  body?: string;
60
60
  url?: string;
61
61
  domain?: string;
62
+ appBaseUrl?: string;
63
+ productName?: string;
64
+ companyName?: string;
65
+ accountUrl?: string;
62
66
  image?: string;
63
67
  email: string;
64
68
  actionButtonText?: string;
@@ -69,7 +73,11 @@ export const sendEmail = async ({
69
73
  title = "Kein Titel",
70
74
  body = "Kein Inhalt",
71
75
  url = "",
72
- domain = "memo",
76
+ domain = "web",
77
+ appBaseUrl = `https://${domain}.wirewire.de`,
78
+ productName = domain,
79
+ companyName = "The Wire UG",
80
+ accountUrl = `${appBaseUrl}/account`,
73
81
  image,
74
82
  email,
75
83
  actionButtonText,
@@ -560,8 +568,8 @@ export const sendEmail = async ({
560
568
  <table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
561
569
  <tr>
562
570
  <td class="email-masthead">
563
- <a href="https://${domain}.wirewire.de" class="f-fallback email-masthead_name">
564
- ${domain === "memo" ? "ANABOX smart" : "paperlesspaper"}
571
+ <a href="${appBaseUrl}" class="f-fallback email-masthead_name">
572
+ ${productName}
565
573
  </a>
566
574
  </td>
567
575
  </tr>
@@ -580,7 +588,7 @@ export const sendEmail = async ({
580
588
  ${actionButton({
581
589
  link: urlStartsWithHttp(url)
582
590
  ? url
583
- : `http://${domain}.wirewire.de${url}`,
591
+ : `${appBaseUrl}${url}`,
584
592
  text: actionButtonTextWithLanguage,
585
593
  })}
586
594
  </div>
@@ -595,8 +603,8 @@ export const sendEmail = async ({
595
603
  <tr>
596
604
  <td class="content-cell" align="center">
597
605
  <p class="f-fallback sub align-center">
598
- ${domain === "web" ? "The Wire UG" : "wirewire GmbH"}
599
- <a href="http://${domain}.wirewire.de/account">Account</a>
606
+ ${companyName}
607
+ <a href="${accountUrl}">Account</a>
600
608
 
601
609
  ${config.env !== "production" ? `<br/><br/>Environment: ${config.env}` : ""}
602
610
  </p>
package/src/index.ts CHANGED
@@ -13,12 +13,16 @@ export {
13
13
  export { initI18n } from "../src/i18n/i18n";
14
14
  export { default as i18n } from "../src/i18n/i18n";
15
15
  export { default as usersRoute } from "../src/users/users.route";
16
+ export * from "../src/users/users.route";
16
17
  export { default as usersService } from "../src/users/users.service";
18
+ export * from "../src/users/users.service";
19
+ export * from "../src/users/users.validation";
17
20
  export { default as accountsRoute } from "../src/accounts/accounts.route";
18
21
  export { default as adminSearchRoute } from "../src/admin/adminSearch.route";
19
22
  export { default as accountsService } from "../src/accounts/accounts.service";
20
23
  export { auth0 } from "../src/accounts/auth0.service";
21
24
  export { default as organizationsRoute } from "../src/organizations/organizations.route";
25
+ export * from "../src/organizations/organizations.controller";
22
26
  export { default as organizationsService } from "../src/organizations/organizations.service";
23
27
  export { default as Organization } from "../src/organizations/organizations.model";
24
28
  export { default as devicesRoute } from "../src/devices/devices.route";
@@ -37,11 +41,11 @@ export {
37
41
  shadowAlarmGet,
38
42
  shadowAlarmUpdate,
39
43
  } from "../src/iotdevice/iotdevice.service";
40
- export { default as pdfRoute } from "../src/pdf/pdf.route";
41
44
  export { default as tokensRoute } from "../src/tokens/tokens.route";
42
45
  export * from "../src/tokens/tokens.service";
43
46
  export { default as Token } from "../src/tokens/tokens.model";
44
47
  export { User } from "../src/users/users.model";
48
+ export * from "../src/users/users.model";
45
49
  export { isAdmin, validateAdmin } from "../src/middlewares/validateAdmin";
46
50
  export { sendEmail } from "../src/email/email.service";
47
51
  export { default as catchAsync } from "../src/utils/catchAsync";
@@ -62,6 +62,7 @@ export const iotdeviceRouteSpecs: RouteSpec[] = [
62
62
  requestSchema: getEventsSchema,
63
63
  responseSchema: eventResponseSchema.array(),
64
64
  handler: getEvents,
65
+ privateDocs: true,
65
66
  summary: "Get events for a device",
66
67
  description: "Fetches event records for the specified device by its ID.",
67
68
  },
@@ -147,9 +148,10 @@ export const iotdeviceRouteSpecs: RouteSpec[] = [
147
148
  requestSchema: apiStatusRequestSchema,
148
149
  responseSchema: apiStatusSchema,
149
150
  handler: getApiStatus,
151
+ privateDocs: true,
150
152
  summary: "Get API status by kind",
151
153
  description:
152
- "Retrieves the IoT API status information for a given status kind to monitor system health or performance. Can be accessed without authentication for monitoring purposes.",
154
+ "Retrieves the IoT API status information for a given status kind to monitor system health or performance. Can be accessed without authentication for uptime monitoring purposes.",
153
155
  },
154
156
  {
155
157
  method: "get",
@@ -39,12 +39,17 @@ const iotDataClient = new IoTDataPlaneClient({
39
39
  */
40
40
  export const getEvents = async (params: {
41
41
  DeviceId: string;
42
- DateStart: string;
43
- DateEnd: string;
42
+ DateStart?: string;
43
+ DateEnd?: string;
44
44
  TypeFilter?: string;
45
45
  createdAt?: string;
46
46
  }): Promise<any> => {
47
47
  const accessToken = await getAuth0Token();
48
+ // Keep the requested start date, but never query events before the device existed.
49
+ const dateStart =
50
+ params.createdAt && new Date(params.DateStart) < new Date(params.createdAt)
51
+ ? params.createdAt
52
+ : params.DateStart;
48
53
  try {
49
54
  const response: AxiosResponse = await axios.get(
50
55
  `${process.env.IOT_API_URL}getevent`,
@@ -52,11 +57,7 @@ export const getEvents = async (params: {
52
57
  headers: { Authorization: `Bearer ${accessToken}` },
53
58
  params: {
54
59
  DeviceId: params.DeviceId,
55
- DateStart: !params.createdAt
56
- ? params.DateStart
57
- : params.DateStart < params.createdAt
58
- ? params.DateStart
59
- : params.createdAt,
60
+ DateStart: dateStart,
60
61
  DateEnd: params.DateEnd,
61
62
  TypeFilter: params.TypeFilter,
62
63
  },
@@ -1,7 +1,7 @@
1
1
  import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
2
2
  import { z } from 'zod';
3
3
  import { objectId } from '../validations/custom.validation';
4
- import { zGet, zObjectId, zPagination } from '../utils/zValidations';
4
+ import { zGet, zObjectId, zPagination, zTypeFilter } from '../utils/zValidations';
5
5
 
6
6
  extendZodWithOpenApi(z);
7
7
 
@@ -31,9 +31,17 @@ export const getEventsSchema = {
31
31
  deviceId: zObjectId.openapi({ description: 'Device ObjectId' }),
32
32
  }),
33
33
  query: z.object({
34
- DateStart: z.string().openapi({ description: 'Start date (ISO‐string)', example: '2025-05-01T00:00:00Z' }),
35
- DateEnd: z.string().openapi({ description: 'End date (ISO‐string)', example: '2025-05-31T23:59:59Z' }),
36
- TypeFilter: z.string().openapi({ description: 'Optional type filter', example: '' }).optional().default(''),
34
+ DateStart: z
35
+ .string()
36
+ .datetime()
37
+ .openapi({ description: 'Start date (ISO‐string)', example: '2025-05-01T00:00:00Z' })
38
+ .optional(),
39
+ DateEnd: z
40
+ .string()
41
+ .datetime()
42
+ .openapi({ description: 'End date (ISO‐string)', example: '2025-05-31T23:59:59Z' })
43
+ .optional(),
44
+ TypeFilter: zTypeFilter.default(''),
37
45
  }),
38
46
  };
39
47
  export const updateEntrySchema = {};
@@ -0,0 +1,34 @@
1
+ import httpStatus from "http-status";
2
+ import ApiError from "../utils/ApiError";
3
+ import type { Request, Response, NextFunction } from "express";
4
+
5
+ const ROLES_CLAIM = "https://memo.wirewire.de/roles";
6
+
7
+ const isAdminOrSupport = (user: Record<string, any> | undefined): boolean => {
8
+ if (!user) return false;
9
+
10
+ const roles = user[ROLES_CLAIM];
11
+
12
+ return Array.isArray(roles)
13
+ ? roles.includes("admin") || roles.includes("support")
14
+ : false;
15
+ };
16
+
17
+ const validateAdminOrSupport = async (
18
+ req: Request,
19
+ res: Response,
20
+ next: NextFunction,
21
+ ): Promise<void> => {
22
+ if (isAdminOrSupport(req.auth)) {
23
+ next();
24
+ } else {
25
+ next(
26
+ new ApiError(
27
+ httpStatus.FORBIDDEN,
28
+ "User is not part of the admin or support group (validateAdminOrSupport)",
29
+ ),
30
+ );
31
+ }
32
+ };
33
+
34
+ export { isAdminOrSupport, validateAdminOrSupport };
@@ -12,18 +12,49 @@ import { filterOptions } from "../utils/filterOptions.js";
12
12
 
13
13
  const ObjectId = mongoose.Types.ObjectId;
14
14
 
15
+ export type CreateOrganizationOwnerUserParams = {
16
+ organization: any;
17
+ owner: string;
18
+ request: Request;
19
+ };
20
+
21
+ export type CreateOrganizationOwnerUserHook = (
22
+ params: CreateOrganizationOwnerUserParams,
23
+ ) => Record<string, any>;
24
+
25
+ let createOrganizationOwnerUserHook: CreateOrganizationOwnerUserHook | null =
26
+ null;
27
+
28
+ export const setCreateOrganizationOwnerUserHook = (
29
+ hook?: CreateOrganizationOwnerUserHook,
30
+ ): void => {
31
+ createOrganizationOwnerUserHook = hook ?? null;
32
+ };
33
+
34
+ const createOrganizationOwnerUserBody = (
35
+ params: CreateOrganizationOwnerUserParams,
36
+ ) => ({
37
+ organization: params.organization._id,
38
+ owner: params.owner,
39
+ role: "admin",
40
+ status: "accept",
41
+ ...(createOrganizationOwnerUserHook
42
+ ? createOrganizationOwnerUserHook(params)
43
+ : {}),
44
+ });
45
+
15
46
  export const createOrganization = catchAsync(
16
47
  async (req: Request, res: Response): Promise<void> => {
17
48
  const organization = await organizationsService.createOrganization(
18
49
  req.body,
19
50
  );
20
- const user = await usersService.createUser({
21
- organization: organization._id,
22
- owner: res.req.auth.sub,
23
- role: "admin",
24
- category: "relative",
25
- status: "accept",
26
- });
51
+ const user = await usersService.createUser(
52
+ createOrganizationOwnerUserBody({
53
+ organization,
54
+ owner: res.req.auth.sub,
55
+ request: req,
56
+ }),
57
+ );
27
58
  res.status(httpStatus.CREATED).send(organization);
28
59
  },
29
60
  );
@@ -92,7 +92,9 @@ export const organizationsRouteSpecs: RouteSpec[] = [
92
92
  responseSchema: organizationResponseSchema,
93
93
  handler: updateOrganization,
94
94
  summary: "Update an organization by ID",
95
- description: "Updates the details of a specific organization by its ID.",
95
+ privateDocs: true,
96
+ description:
97
+ "LEGACY: Updates the details of a specific organization by its ID.",
96
98
  },
97
99
  {
98
100
  method: "delete",
@@ -14,7 +14,6 @@ export interface IUser {
14
14
  inviteCode?: string;
15
15
  email?: string;
16
16
  role: (typeof roles)[number];
17
- category: string;
18
17
  status?: string;
19
18
  meta?: Record<string, any>;
20
19
  }
@@ -27,7 +26,7 @@ export interface IUserModel extends Model<IUserDocument> {
27
26
  isEmailTaken(email: string, excludeUserId?: Types.ObjectId): Promise<boolean>;
28
27
  }
29
28
 
30
- const userSchema = new Schema<IUserDocument, IUserModel>(
29
+ export const userSchema = new Schema<IUserDocument, IUserModel>(
31
30
  {
32
31
  name: { type: String, trim: true },
33
32
  avatar: { type: String },
@@ -37,7 +36,6 @@ const userSchema = new Schema<IUserDocument, IUserModel>(
37
36
  inviteCode: { type: String },
38
37
  email: { type: String },
39
38
  role: { type: String, default: "patient" /* , enum: Object.keys(roles) */ },
40
- category: { type: String, default: "patient" },
41
39
  status: { type: String },
42
40
  meta: { type: Schema.Types.Mixed },
43
41
  },
@@ -59,6 +57,12 @@ userSchema.virtual("organizationData", {
59
57
  userSchema.plugin(toJSON);
60
58
  userSchema.plugin(paginate);
61
59
 
60
+ export const extendUserSchema = (
61
+ definition: Parameters<typeof userSchema.add>[0],
62
+ ): void => {
63
+ userSchema.add(definition);
64
+ };
65
+
62
66
  /**
63
67
  * Check if email is taken
64
68
  * @param {string} email - The user's email
@@ -45,7 +45,6 @@ export const userRouteSpecs: RouteSpec[] = [
45
45
  handler: userController.createUser,
46
46
  summary: "Create a new user",
47
47
  description: "Creates a new user within the current organization.",
48
- memoOnly: true,
49
48
  },
50
49
  {
51
50
  method: "get",
@@ -137,7 +136,9 @@ export const userRouteSpecs: RouteSpec[] = [
137
136
  responseSchema: updateUserResponseSchema,
138
137
  handler: userController.updateUser,
139
138
  summary: "Update a user by ID",
140
- description: "Replaces a user’s full record with the provided data.",
139
+ privateDocs: true,
140
+ description:
141
+ "LEGACY: Replaces a user’s full record with the provided data. (Replaced by PATCH /:userId)",
141
142
  },
142
143
  {
143
144
  method: "patch",
@@ -7,6 +7,7 @@ import ApiError from "../utils/ApiError.js";
7
7
  import auth0Service from "../accounts/auth0.service";
8
8
  import organizationsService from "../organizations/organizations.service";
9
9
  import { sendEmail } from "../email/email.service";
10
+ import type { SendEmailParams } from "../email/email.service";
10
11
  import i18n from "../i18n/i18n";
11
12
 
12
13
  export type UpdateTimesByIdHook = (
@@ -21,6 +22,27 @@ export const setUpdateTimesByIdHook = (hook?: UpdateTimesByIdHook): void => {
21
22
  updateTimesByIdHook = hook ?? null;
22
23
  };
23
24
 
25
+ export type BuildInviteEmailParams = {
26
+ auth: { sub: string };
27
+ user: IUserDocument;
28
+ inviteCode: string;
29
+ email: string;
30
+ organization: any;
31
+ lng: string;
32
+ };
33
+
34
+ export type BuildInviteEmailHook = (
35
+ params: BuildInviteEmailParams,
36
+ ) => Partial<SendEmailParams>;
37
+
38
+ let buildInviteEmailHook: BuildInviteEmailHook | null = null;
39
+
40
+ export const setBuildInviteEmailHook = (
41
+ hook?: BuildInviteEmailHook,
42
+ ): void => {
43
+ buildInviteEmailHook = hook ?? null;
44
+ };
45
+
24
46
  /**
25
47
  * Create a new user
26
48
  */
@@ -100,14 +122,13 @@ export const getByIdWithAuth0 = async (id: string): Promise<any | null> => {
100
122
  return json;
101
123
  };
102
124
 
103
- /**
104
- * Get all users in a given category (and optional organization)
105
- */
106
- export const getUsersByCategory = async (
107
- category: string,
125
+ export const getUsersByAppField = async (
126
+ appName: string,
127
+ fieldName: string,
128
+ value: unknown,
108
129
  organization?: string,
109
130
  ): Promise<IUserDocument[]> => {
110
- const filter: any = { category };
131
+ const filter: any = { [`apps.${appName}.${fieldName}`]: value };
111
132
  if (organization) filter.organization = organization;
112
133
  return User.find(filter);
113
134
  };
@@ -182,21 +203,35 @@ export const sendInviteEmail = async (params: {
182
203
  const auth0User = await auth0Service.getUserById(auth.sub);
183
204
  const lng = auth0User.data?.app_metadata?.language as string | "en";
184
205
 
185
- const title = `${i18n.t("Invite to ", { lng })}${
186
- organization.kind === "private-wirewire" ? "paperlesspaper" : "ANABOX smart"
187
- }`;
188
206
  const body = i18n.t(
189
207
  "You have been invited to join the group. Click on the link to accept the invitation.",
190
208
  { lng },
191
209
  );
192
-
193
- await sendEmail({
194
- title,
210
+ const baseEmail: SendEmailParams = {
211
+ title: `${i18n.t("Invite to ", { lng })}${
212
+ organization?.name || "Application"
213
+ }`,
195
214
  body,
196
215
  url: `/${user.organization}/invite/${inviteCode}`,
197
216
  actionButtonText: "Accept invite",
198
- domain: organization.kind === "private-wirewire" ? "web" : "memo",
217
+ domain: "web",
218
+ productName: organization?.name || "Application",
199
219
  email,
220
+ lng,
221
+ };
222
+
223
+ await sendEmail({
224
+ ...baseEmail,
225
+ ...(buildInviteEmailHook
226
+ ? buildInviteEmailHook({
227
+ auth,
228
+ user,
229
+ inviteCode,
230
+ email,
231
+ organization,
232
+ lng,
233
+ })
234
+ : {}),
200
235
  });
201
236
  };
202
237
 
@@ -384,7 +419,7 @@ export default {
384
419
  createCurrentUser,
385
420
  getById,
386
421
  getByIdWithAuth0,
387
- getUsersByCategory,
422
+ getUsersByAppField,
388
423
  getUsersByOrganization,
389
424
  getUsersByOrganizationAndId,
390
425
  getUsersByOwner,
@@ -407,6 +442,7 @@ export default {
407
442
  populateAuth0User,
408
443
  populateAuth0Users,
409
444
  setUpdateTimesByIdHook,
445
+ setBuildInviteEmailHook,
410
446
  };
411
447
 
412
448
  export type UserService = typeof import("./users.service");