@intlayer/backend 3.0.3 → 3.1.0
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/cjs/controllers/dictionary.controller.cjs +50 -18
- package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
- package/dist/cjs/controllers/organization.controller.cjs +71 -12
- package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
- package/dist/cjs/controllers/project.controller.cjs +117 -31
- package/dist/cjs/controllers/project.controller.cjs.map +1 -1
- package/dist/cjs/controllers/projectAccessKey.controller.cjs +30 -10
- package/dist/cjs/controllers/projectAccessKey.controller.cjs.map +1 -1
- package/dist/cjs/controllers/sessionAuth.controller.cjs +16 -7
- package/dist/cjs/controllers/sessionAuth.controller.cjs.map +1 -1
- package/dist/cjs/controllers/user.controller.cjs +9 -17
- package/dist/cjs/controllers/user.controller.cjs.map +1 -1
- package/dist/cjs/export.cjs.map +1 -1
- package/dist/cjs/index.cjs +3 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/middlewares/oAuth2.middleware.cjs +10 -0
- package/dist/cjs/middlewares/oAuth2.middleware.cjs.map +1 -1
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs +49 -7
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs.map +1 -1
- package/dist/cjs/{middlewares/admin.middleware.cjs → models/plan.moddel.cjs} +9 -22
- package/dist/cjs/models/plan.moddel.cjs.map +1 -0
- package/dist/cjs/schemas/plans.schema.cjs +62 -0
- package/dist/cjs/schemas/plans.schema.cjs.map +1 -0
- package/dist/cjs/schemas/project.schema.cjs +14 -1
- package/dist/cjs/schemas/project.schema.cjs.map +1 -1
- package/dist/cjs/schemas/user.schema.cjs +4 -0
- package/dist/cjs/schemas/user.schema.cjs.map +1 -1
- package/dist/cjs/services/dictionary.service.cjs.map +1 -1
- package/dist/cjs/services/oAuth2.service.cjs +16 -8
- package/dist/cjs/services/oAuth2.service.cjs.map +1 -1
- package/dist/cjs/services/organization.service.cjs +8 -0
- package/dist/cjs/services/organization.service.cjs.map +1 -1
- package/dist/cjs/services/plans.service.cjs +72 -0
- package/dist/cjs/services/plans.service.cjs.map +1 -0
- package/dist/cjs/services/project.service.cjs +8 -2
- package/dist/cjs/services/project.service.cjs.map +1 -1
- package/dist/cjs/services/projectAccessKey.service.cjs +42 -10
- package/dist/cjs/services/projectAccessKey.service.cjs.map +1 -1
- package/dist/cjs/services/sessionAuth.service.cjs.map +1 -1
- package/dist/cjs/services/subscription.service.cjs +118 -0
- package/dist/cjs/services/subscription.service.cjs.map +1 -0
- package/dist/cjs/services/user.service.cjs.map +1 -1
- package/dist/cjs/types/dictionary.types.cjs.map +1 -1
- package/dist/cjs/types/organization.types.cjs.map +1 -1
- package/dist/cjs/types/plan.types.cjs +17 -0
- package/dist/cjs/types/plan.types.cjs.map +1 -0
- package/dist/cjs/types/project.types.cjs.map +1 -1
- package/dist/cjs/types/user.types.cjs.map +1 -1
- package/dist/cjs/utils/errors/ErrorHandler.cjs +1 -1
- package/dist/cjs/utils/errors/ErrorHandler.cjs.map +1 -1
- package/dist/cjs/utils/errors/errorCodes.cjs +222 -1
- package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
- package/dist/cjs/utils/mapper/organization.cjs.map +1 -1
- package/dist/cjs/utils/mapper/project.cjs +19 -3
- package/dist/cjs/utils/mapper/project.cjs.map +1 -1
- package/dist/cjs/utils/mapper/user.cjs.map +1 -1
- package/dist/cjs/utils/plan.cjs +70 -0
- package/dist/cjs/utils/plan.cjs.map +1 -0
- package/dist/cjs/webhooks/stripe.cjs +94 -0
- package/dist/cjs/webhooks/stripe.cjs.map +1 -0
- package/dist/esm/controllers/dictionary.controller.mjs +50 -18
- package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
- package/dist/esm/controllers/organization.controller.mjs +71 -12
- package/dist/esm/controllers/organization.controller.mjs.map +1 -1
- package/dist/esm/controllers/project.controller.mjs +117 -31
- package/dist/esm/controllers/project.controller.mjs.map +1 -1
- package/dist/esm/controllers/projectAccessKey.controller.mjs +30 -10
- package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
- package/dist/esm/controllers/sessionAuth.controller.mjs +16 -7
- package/dist/esm/controllers/sessionAuth.controller.mjs.map +1 -1
- package/dist/esm/controllers/user.controller.mjs +9 -17
- package/dist/esm/controllers/user.controller.mjs.map +1 -1
- package/dist/esm/export.mjs.map +1 -1
- package/dist/esm/index.mjs +6 -4
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/middlewares/oAuth2.middleware.mjs +10 -0
- package/dist/esm/middlewares/oAuth2.middleware.mjs.map +1 -1
- package/dist/esm/middlewares/sessionAuth.middleware.mjs +48 -6
- package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
- package/dist/esm/models/plan.moddel.mjs +7 -0
- package/dist/esm/models/plan.moddel.mjs.map +1 -0
- package/dist/esm/schemas/plans.schema.mjs +38 -0
- package/dist/esm/schemas/plans.schema.mjs.map +1 -0
- package/dist/esm/schemas/project.schema.mjs +13 -1
- package/dist/esm/schemas/project.schema.mjs.map +1 -1
- package/dist/esm/schemas/user.schema.mjs +4 -0
- package/dist/esm/schemas/user.schema.mjs.map +1 -1
- package/dist/esm/services/dictionary.service.mjs.map +1 -1
- package/dist/esm/services/oAuth2.service.mjs +16 -8
- package/dist/esm/services/oAuth2.service.mjs.map +1 -1
- package/dist/esm/services/organization.service.mjs +7 -0
- package/dist/esm/services/organization.service.mjs.map +1 -1
- package/dist/esm/services/plans.service.mjs +44 -0
- package/dist/esm/services/plans.service.mjs.map +1 -0
- package/dist/esm/services/project.service.mjs +8 -2
- package/dist/esm/services/project.service.mjs.map +1 -1
- package/dist/esm/services/projectAccessKey.service.mjs +42 -10
- package/dist/esm/services/projectAccessKey.service.mjs.map +1 -1
- package/dist/esm/services/sessionAuth.service.mjs.map +1 -1
- package/dist/esm/services/subscription.service.mjs +95 -0
- package/dist/esm/services/subscription.service.mjs.map +1 -0
- package/dist/esm/services/user.service.mjs.map +1 -1
- package/dist/esm/types/plan.types.mjs +1 -0
- package/dist/esm/types/plan.types.mjs.map +1 -0
- package/dist/esm/utils/errors/ErrorHandler.mjs +1 -1
- package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
- package/dist/esm/utils/errors/errorCodes.mjs +222 -1
- package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
- package/dist/esm/utils/mapper/organization.mjs.map +1 -1
- package/dist/esm/utils/mapper/project.mjs +17 -2
- package/dist/esm/utils/mapper/project.mjs.map +1 -1
- package/dist/esm/utils/mapper/user.mjs.map +1 -1
- package/dist/esm/utils/plan.mjs +45 -0
- package/dist/esm/utils/plan.mjs.map +1 -0
- package/dist/esm/webhooks/stripe.mjs +70 -0
- package/dist/esm/webhooks/stripe.mjs.map +1 -0
- package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
- package/dist/types/controllers/organization.controller.d.ts.map +1 -1
- package/dist/types/controllers/project.controller.d.ts +9 -7
- package/dist/types/controllers/project.controller.d.ts.map +1 -1
- package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
- package/dist/types/controllers/sessionAuth.controller.d.ts +4 -4
- package/dist/types/controllers/sessionAuth.controller.d.ts.map +1 -1
- package/dist/types/controllers/user.controller.d.ts.map +1 -1
- package/dist/types/export.d.ts +1 -0
- package/dist/types/export.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/middlewares/oAuth2.middleware.d.ts.map +1 -1
- package/dist/types/middlewares/sessionAuth.middleware.d.ts +13 -7
- package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
- package/dist/types/models/dictionary.model.d.ts +1 -1
- package/dist/types/models/oAuth2.model.d.ts +1 -1
- package/dist/types/models/organization.model.d.ts +1 -1
- package/dist/types/models/plan.moddel.d.ts +11 -0
- package/dist/types/models/plan.moddel.d.ts.map +1 -0
- package/dist/types/models/project.model.d.ts +1 -1
- package/dist/types/schemas/dictionary.schema.d.ts +2 -2
- package/dist/types/schemas/oAuth2.schema.d.ts +2 -2
- package/dist/types/schemas/organization.schema.d.ts +2 -2
- package/dist/types/schemas/plans.schema.d.ts +16 -0
- package/dist/types/schemas/plans.schema.d.ts.map +1 -0
- package/dist/types/schemas/project.schema.d.ts +12 -3
- package/dist/types/schemas/project.schema.d.ts.map +1 -1
- package/dist/types/schemas/user.schema.d.ts +2 -2
- package/dist/types/schemas/user.schema.d.ts.map +1 -1
- package/dist/types/services/dictionary.service.d.ts +9 -9
- package/dist/types/services/dictionary.service.d.ts.map +1 -1
- package/dist/types/services/oAuth2.service.d.ts +7 -5
- package/dist/types/services/oAuth2.service.d.ts.map +1 -1
- package/dist/types/services/organization.service.d.ts +12 -6
- package/dist/types/services/organization.service.d.ts.map +1 -1
- package/dist/types/services/plans.service.d.ts +35 -0
- package/dist/types/services/plans.service.d.ts.map +1 -0
- package/dist/types/services/project.service.d.ts +6 -6
- package/dist/types/services/project.service.d.ts.map +1 -1
- package/dist/types/services/projectAccessKey.service.d.ts +4 -4
- package/dist/types/services/projectAccessKey.service.d.ts.map +1 -1
- package/dist/types/services/sessionAuth.service.d.ts +9 -9
- package/dist/types/services/sessionAuth.service.d.ts.map +1 -1
- package/dist/types/services/subscription.service.d.ts +7 -0
- package/dist/types/services/subscription.service.d.ts.map +1 -0
- package/dist/types/services/user.service.d.ts +11 -19
- package/dist/types/services/user.service.d.ts.map +1 -1
- package/dist/types/types/dictionary.types.d.ts +2 -2
- package/dist/types/types/dictionary.types.d.ts.map +1 -1
- package/dist/types/types/organization.types.d.ts +2 -2
- package/dist/types/types/organization.types.d.ts.map +1 -1
- package/dist/types/types/plan.types.d.ts +19 -0
- package/dist/types/types/plan.types.d.ts.map +1 -0
- package/dist/types/types/project.types.d.ts +13 -2
- package/dist/types/types/project.types.d.ts.map +1 -1
- package/dist/types/types/user.types.d.ts +2 -1
- package/dist/types/types/user.types.d.ts.map +1 -1
- package/dist/types/utils/errors/errorCodes.d.ts +221 -0
- package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
- package/dist/types/utils/mapper/organization.d.ts +1 -1
- package/dist/types/utils/mapper/organization.d.ts.map +1 -1
- package/dist/types/utils/mapper/project.d.ts +10 -1
- package/dist/types/utils/mapper/project.d.ts.map +1 -1
- package/dist/types/utils/mapper/user.d.ts +1 -1
- package/dist/types/utils/mapper/user.d.ts.map +1 -1
- package/dist/types/utils/plan.d.ts +17 -0
- package/dist/types/utils/plan.d.ts.map +1 -0
- package/dist/types/webhooks/stripe.d.ts +3 -0
- package/dist/types/webhooks/stripe.d.ts.map +1 -0
- package/package.json +27 -25
- package/dist/cjs/middlewares/admin.middleware.cjs.map +0 -1
- package/dist/esm/middlewares/admin.middleware.mjs +0 -20
- package/dist/esm/middlewares/admin.middleware.mjs.map +0 -1
|
@@ -44,14 +44,18 @@ var import_getDictionaryFiltersAndPagination = require('./../utils/filtersAndPag
|
|
|
44
44
|
var import_dictionary = require('./../utils/mapper/dictionary.cjs');
|
|
45
45
|
var import_responseData = require('./../utils/responseData.cjs');
|
|
46
46
|
const getDictionaries = async (req, res, _next) => {
|
|
47
|
-
const { user, project } = res.locals;
|
|
47
|
+
const { user, project, dictionaryRights } = res.locals;
|
|
48
48
|
const { filters, pageSize, skip, page, getNumberOfPages } = (0, import_getDictionaryFiltersAndPagination.getDictionaryFiltersAndPagination)(req);
|
|
49
49
|
if (!project) {
|
|
50
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
50
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
if (!user) {
|
|
54
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
54
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (!dictionaryRights?.read) {
|
|
58
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_READ");
|
|
55
59
|
return;
|
|
56
60
|
}
|
|
57
61
|
try {
|
|
@@ -79,9 +83,13 @@ const getDictionaries = async (req, res, _next) => {
|
|
|
79
83
|
}
|
|
80
84
|
};
|
|
81
85
|
const getDictionariesKeys = async (_req, res, _next) => {
|
|
82
|
-
const { project } = res.locals;
|
|
86
|
+
const { project, dictionaryRights } = res.locals;
|
|
83
87
|
if (!project) {
|
|
84
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
88
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!dictionaryRights?.read) {
|
|
92
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_READ");
|
|
85
93
|
return;
|
|
86
94
|
}
|
|
87
95
|
try {
|
|
@@ -99,15 +107,19 @@ const getDictionariesKeys = async (_req, res, _next) => {
|
|
|
99
107
|
}
|
|
100
108
|
};
|
|
101
109
|
const getDictionaryByKey = async (req, res, _next) => {
|
|
102
|
-
const { project, user } = res.locals;
|
|
110
|
+
const { project, user, dictionaryRights } = res.locals;
|
|
103
111
|
const { dictionaryKey } = req.params;
|
|
104
112
|
const { version } = req.query;
|
|
105
113
|
if (!project) {
|
|
106
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
114
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
107
115
|
return;
|
|
108
116
|
}
|
|
109
117
|
if (!user) {
|
|
110
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
118
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (!dictionaryRights?.read) {
|
|
122
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_READ");
|
|
111
123
|
return;
|
|
112
124
|
}
|
|
113
125
|
try {
|
|
@@ -134,24 +146,28 @@ const getDictionaryByKey = async (req, res, _next) => {
|
|
|
134
146
|
}
|
|
135
147
|
};
|
|
136
148
|
const addDictionary = async (req, res, _next) => {
|
|
137
|
-
const { project, user } = res.locals;
|
|
149
|
+
const { project, user, dictionaryRights } = res.locals;
|
|
138
150
|
const dictionaryData = req.body;
|
|
139
151
|
if (!dictionaryData) {
|
|
140
152
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_DATA_NOT_FOUND");
|
|
141
153
|
return;
|
|
142
154
|
}
|
|
143
155
|
if (!project) {
|
|
144
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
156
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
145
157
|
return;
|
|
146
158
|
}
|
|
147
159
|
if (!user) {
|
|
148
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
160
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
149
161
|
return;
|
|
150
162
|
}
|
|
151
163
|
if (!dictionaryData.projectIds.includes(String(project._id))) {
|
|
152
164
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_PROJECT_MISMATCH");
|
|
153
165
|
return;
|
|
154
166
|
}
|
|
167
|
+
if (!dictionaryRights?.admin) {
|
|
168
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_ADMIN");
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
155
171
|
const dictionary = {
|
|
156
172
|
key: dictionaryData.key,
|
|
157
173
|
title: dictionaryData.title,
|
|
@@ -175,7 +191,7 @@ const addDictionary = async (req, res, _next) => {
|
|
|
175
191
|
}
|
|
176
192
|
};
|
|
177
193
|
const pushDictionaries = async (req, res, _next) => {
|
|
178
|
-
const { project, user } = res.locals;
|
|
194
|
+
const { project, user, dictionaryRights } = res.locals;
|
|
179
195
|
const dictionaryData = req.body.dictionaries;
|
|
180
196
|
const dictionariesKeys = dictionaryData.map((dictionary) => dictionary.key);
|
|
181
197
|
if (typeof dictionaryData === "object" && Array.isArray(dictionaryData) && dictionaryData.length === 0) {
|
|
@@ -186,11 +202,19 @@ const pushDictionaries = async (req, res, _next) => {
|
|
|
186
202
|
return;
|
|
187
203
|
}
|
|
188
204
|
if (!project) {
|
|
189
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
205
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
190
206
|
return;
|
|
191
207
|
}
|
|
192
208
|
if (!user) {
|
|
193
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
209
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (!dictionaryRights?.write) {
|
|
213
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_WRITE");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (!dictionaryRights?.admin) {
|
|
217
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_ADMIN");
|
|
194
218
|
return;
|
|
195
219
|
}
|
|
196
220
|
try {
|
|
@@ -270,14 +294,14 @@ const pushDictionaries = async (req, res, _next) => {
|
|
|
270
294
|
}
|
|
271
295
|
};
|
|
272
296
|
const updateDictionary = async (req, res, _next) => {
|
|
273
|
-
const { project } = res.locals;
|
|
297
|
+
const { project, dictionaryRights } = res.locals;
|
|
274
298
|
const dictionaryData = req.body;
|
|
275
299
|
if (!dictionaryData) {
|
|
276
300
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_DATA_NOT_FOUND");
|
|
277
301
|
return;
|
|
278
302
|
}
|
|
279
303
|
if (!project) {
|
|
280
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
304
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
281
305
|
return;
|
|
282
306
|
}
|
|
283
307
|
if (!dictionaryData.projectIds?.includes(String(project._id))) {
|
|
@@ -288,6 +312,10 @@ const updateDictionary = async (req, res, _next) => {
|
|
|
288
312
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_ID_NOT_FOUND");
|
|
289
313
|
return;
|
|
290
314
|
}
|
|
315
|
+
if (!dictionaryRights?.write) {
|
|
316
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_WRITE");
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
291
319
|
try {
|
|
292
320
|
const updatedDictionary = await dictionaryService.updateDictionaryById(
|
|
293
321
|
dictionaryData._id,
|
|
@@ -305,14 +333,18 @@ const updateDictionary = async (req, res, _next) => {
|
|
|
305
333
|
}
|
|
306
334
|
};
|
|
307
335
|
const deleteDictionary = async (req, res, _next) => {
|
|
308
|
-
const { project } = res.locals;
|
|
336
|
+
const { project, dictionaryRights } = res.locals;
|
|
309
337
|
const { dictionaryId } = req.params;
|
|
310
338
|
if (!dictionaryId) {
|
|
311
339
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_ID_NOT_FOUND");
|
|
312
340
|
return;
|
|
313
341
|
}
|
|
314
342
|
if (!project) {
|
|
315
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
343
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (!dictionaryRights?.admin) {
|
|
347
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_ADMIN");
|
|
316
348
|
return;
|
|
317
349
|
}
|
|
318
350
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/controllers/dictionary.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { type Dictionary as LocalDictionary } from '@intlayer/core';\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport * as dictionaryService from '@services/dictionary.service';\nimport { AppError, ErrorHandler } from '@utils/errors';\nimport {\n type DictionaryFiltersParams,\n getDictionaryFiltersAndPagination,\n} from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport { mapDictionaryToAPI } from '@utils/mapper/dictionary';\nimport {\n formatPaginatedResponse,\n type ResponseData,\n type PaginatedResponse,\n formatResponse,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type {\n Dictionary,\n DictionaryAPI,\n DictionaryCreationData,\n DictionaryData,\n} from '@/types/dictionary.types';\n\nexport type GetDictionariesParams =\n FiltersAndPagination<DictionaryFiltersParams>;\nexport type GetDictionariesResult = PaginatedResponse<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaries = async (\n req: Request<GetDictionariesParams>,\n res: ResponseWithInformation<GetDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getDictionaryFiltersAndPagination(req);\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_FOUND');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n try {\n const dictionaries = await dictionaryService.findDictionaries(\n filters,\n skip,\n pageSize\n );\n const totalItems = await dictionaryService.countDictionaries(filters);\n\n const dictionariesAPI = dictionaries.map((el) =>\n mapDictionaryToAPI(el, project._id)\n );\n\n const responseData = formatPaginatedResponse<DictionaryAPI>({\n data: dictionariesAPI,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetDictionariesKeysResult = ResponseData<string[]>;\n\n/**\n * Retrieves a list of dictionaries keys based on filters and pagination.\n */\nexport const getDictionariesKeys = async (\n _req: Request,\n res: ResponseWithInformation<GetDictionariesKeysResult>,\n _next: NextFunction\n) => {\n const { project } = res.locals;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_FOUND');\n return;\n }\n\n try {\n const dictionariesKeys = await dictionaryService.getDictionariesKeys(\n project._id\n );\n\n const responseData = formatResponse<string[]>({\n data: dictionariesKeys,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetDictionaryParams = { dictionaryKey: string };\nexport type GetDictionaryQuery = { version?: number };\nexport type GetDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaryByKey = async (\n req: Request<GetDictionaryParams>,\n res: ResponseWithInformation<GetDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user } = res.locals;\n const { dictionaryKey } = req.params;\n const { version } = req.query as GetDictionaryQuery;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_FOUND');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n try {\n const dictionaries = await dictionaryService.getDictionaryByKey(\n dictionaryKey,\n project._id\n );\n\n if (!dictionaries.projectIds.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const apiResult = mapDictionaryToAPI(dictionaries, project._id, version);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AddDictionaryBody = DictionaryCreationData;\nexport type AddDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const addDictionary = async (\n req: Request<any, any, AddDictionaryBody>,\n res: ResponseWithInformation<AddDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user } = res.locals;\n const dictionaryData = req.body;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_FOUND');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n if (!dictionaryData.projectIds.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n const dictionary: DictionaryData = {\n key: dictionaryData.key,\n title: dictionaryData.title,\n description: dictionaryData.description,\n content: [dictionaryData.content],\n creatorId: user._id,\n filePath: { [String(project._id)]: dictionaryData.filePath ?? '' },\n projectIds: dictionaryData.projectIds ?? [String(project._id)],\n };\n\n try {\n const newDictionary = await dictionaryService.createDictionary(dictionary);\n\n const apiResult = mapDictionaryToAPI(newDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type PushDictionariesBody = { dictionaries: LocalDictionary[] };\ntype PushDictionariesResultData = {\n newDictionaries: string[];\n updatedDictionaries: string[];\n error: { dictionaryId: string; message: string }[];\n};\nexport type PushDictionariesResult = ResponseData<PushDictionariesResultData>;\n\n/**\n * Check each dictionaries, add the new ones and update the existing ones.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response containing the created dictionary.\n */\nexport const pushDictionaries = async (\n req: Request<any, any, PushDictionariesBody>,\n res: ResponseWithInformation<PushDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user } = res.locals;\n const dictionaryData = req.body.dictionaries;\n const dictionariesKeys = dictionaryData.map((dictionary) => dictionary.key);\n\n if (\n typeof dictionaryData === 'object' &&\n Array.isArray(dictionaryData) &&\n dictionaryData.length === 0\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARIES_NOT_PROVIDED');\n return;\n } else if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_FOUND');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n try {\n const { existingDictionariesKey, newDictionariesKey } =\n await dictionaryService.getExistingDictionaryKey(\n dictionariesKeys,\n project._id\n );\n\n const existingDictionaries = dictionaryData.filter((dictionary) =>\n existingDictionariesKey.includes(dictionary.key)\n );\n const newDictionaries = dictionaryData.filter((dictionary) =>\n newDictionariesKey.includes(dictionary.key)\n );\n\n const result: PushDictionariesResultData = {\n newDictionaries: [],\n updatedDictionaries: [],\n error: [],\n };\n\n for (const dictionaryDataEl of newDictionaries) {\n const dictionary: DictionaryData = {\n title: dictionaryDataEl.title,\n description: dictionaryDataEl.description,\n content: [dictionaryDataEl.content],\n projectIds: [String(project._id)],\n creatorId: user._id,\n filePath: { [String(project._id)]: dictionaryDataEl.filePath ?? '' },\n key: dictionaryDataEl.key,\n };\n\n try {\n const newDictionary =\n await dictionaryService.createDictionary(dictionary);\n result.newDictionaries.push(newDictionary.key);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n }\n\n if (existingDictionariesKey.length >= 0) {\n const existingDictionariesDB =\n await dictionaryService.getDictionariesByKeys(\n existingDictionariesKey,\n project._id\n );\n\n for (const dictionaryDataEl of existingDictionaries) {\n const existingDictionaryDB = existingDictionariesDB.find(\n (dictionaryDB) => dictionaryDB.key === dictionaryDataEl.key\n )!;\n\n const dictionary: DictionaryData = {\n ...existingDictionaryDB,\n ...dictionaryDataEl,\n content: [\n ...(existingDictionaryDB.content ?? []),\n dictionaryDataEl.content,\n ],\n projectIds: [String(project._id)],\n creatorId: user._id,\n filePath: { [String(project._id)]: dictionaryDataEl.filePath ?? '' },\n key: dictionaryDataEl.key,\n };\n\n try {\n const newDictionary = await dictionaryService.updateDictionaryByKey(\n dictionaryDataEl.key,\n dictionary,\n project._id\n );\n result.updatedDictionaries.push(newDictionary.key);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n }\n }\n\n const responseData = formatResponse<PushDictionariesResultData>({\n data: result,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateDictionaryBody = Partial<Dictionary>;\nexport type UpdateDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Updates an existing dictionary in the database.\n */\nexport const updateDictionary = async (\n req: Request<any, any, UpdateDictionaryBody>,\n res: ResponseWithInformation<UpdateDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const dictionaryData = req.body;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_FOUND');\n return;\n }\n\n if (!dictionaryData.projectIds?.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n if (typeof dictionaryData._id === 'undefined') {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n try {\n const updatedDictionary = await dictionaryService.updateDictionaryById(\n dictionaryData._id,\n dictionaryData\n );\n\n const apiResult = mapDictionaryToAPI(updatedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteDictionaryParam = { dictionaryId: string };\nexport type DeleteDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Deletes a dictionary from the database by its ID.\n */\nexport const deleteDictionary = async (\n req: Request<DeleteDictionaryParam>,\n res: ResponseWithInformation<DeleteDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { dictionaryId } = req.params as Partial<DeleteDictionaryParam>;\n\n if (!dictionaryId) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_FOUND');\n return;\n }\n\n try {\n const dictionaryToDelete =\n await dictionaryService.getDictionaryById(dictionaryId);\n\n if (!dictionaryToDelete.projectIds.includes(project._id)) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const deletedDictionary =\n await dictionaryService.deleteDictionaryById(dictionaryId);\n\n if (!deletedDictionary) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_NOT_FOUND', {\n dictionaryId,\n });\n return;\n }\n\n logger.info(`Dictionary deleted: ${String(deletedDictionary._id)}`);\n\n const apiResult = mapDictionaryToAPI(deletedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAAuB;AAEvB,wBAAmC;AACnC,oBAAuC;AACvC,+CAGO;AAEP,wBAAmC;AACnC,0BAKO;AAgBA,MAAM,kBAAkB,OAC7B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,MAAM,QAAQ,IAAI,IAAI;AAC9B,QAAM,EAAE,SAAS,UAAU,MAAM,MAAM,iBAAiB,QACtD,4EAAkC,GAAG;AAEvC,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,mBAAmB;AAChE;AAAA,EACF;AACA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,gBAAgB;AAC7D;AAAA,EACF;AAEA,MAAI;AACF,UAAM,eAAe,MAAM,kBAAkB;AAAA,MAC3C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,aAAa,MAAM,kBAAkB,kBAAkB,OAAO;AAEpE,UAAM,kBAAkB,aAAa;AAAA,MAAI,CAAC,WACxC,sCAAmB,IAAI,QAAQ,GAAG;AAAA,IACpC;AAEA,UAAM,mBAAe,6CAAuC;AAAA,MAC1D,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,YAAY,iBAAiB,UAAU;AAAA,MACvC;AAAA,IACF,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAOO,MAAM,sBAAsB,OACjC,MACA,KACA,UACG;AACH,QAAM,EAAE,QAAQ,IAAI,IAAI;AAExB,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,mBAAmB;AAChE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,mBAAmB,MAAM,kBAAkB;AAAA,MAC/C,QAAQ;AAAA,IACV;AAEA,UAAM,mBAAe,oCAAyB;AAAA,MAC5C,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AASO,MAAM,qBAAqB,OAChC,KACA,KACA,UACkB;AAClB,QAAM,EAAE,SAAS,KAAK,IAAI,IAAI;AAC9B,QAAM,EAAE,cAAc,IAAI,IAAI;AAC9B,QAAM,EAAE,QAAQ,IAAI,IAAI;AAExB,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,mBAAmB;AAChE;AAAA,EACF;AACA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,gBAAgB;AAC7D;AAAA,EACF;AAEA,MAAI;AACF,UAAM,eAAe,MAAM,kBAAkB;AAAA,MAC3C;AAAA,MACA,QAAQ;AAAA,IACV;AAEA,QAAI,CAAC,aAAa,WAAW,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AAC1D,iCAAa;AAAA,QACX;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,gBAAY,sCAAmB,cAAc,QAAQ,KAAK,OAAO;AAEvE,UAAM,mBAAe,oCAA8B;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAQO,MAAM,gBAAgB,OAC3B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,SAAS,KAAK,IAAI,IAAI;AAC9B,QAAM,iBAAiB,IAAI;AAE3B,MAAI,CAAC,gBAAgB;AACnB,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,mBAAmB;AAChE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,gBAAgB;AAC7D;AAAA,EACF;AAEA,MAAI,CAAC,eAAe,WAAW,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AAC5D,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,QAAM,aAA6B;AAAA,IACjC,KAAK,eAAe;AAAA,IACpB,OAAO,eAAe;AAAA,IACtB,aAAa,eAAe;AAAA,IAC5B,SAAS,CAAC,eAAe,OAAO;AAAA,IAChC,WAAW,KAAK;AAAA,IAChB,UAAU,EAAE,CAAC,OAAO,QAAQ,GAAG,CAAC,GAAG,eAAe,YAAY,GAAG;AAAA,IACjE,YAAY,eAAe,cAAc,CAAC,OAAO,QAAQ,GAAG,CAAC;AAAA,EAC/D;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,kBAAkB,iBAAiB,UAAU;AAEzE,UAAM,gBAAY,sCAAmB,eAAe,QAAQ,GAAG;AAE/D,UAAM,mBAAe,oCAA8B;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAgBO,MAAM,mBAAmB,OAC9B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,SAAS,KAAK,IAAI,IAAI;AAC9B,QAAM,iBAAiB,IAAI,KAAK;AAChC,QAAM,mBAAmB,eAAe,IAAI,CAAC,eAAe,WAAW,GAAG;AAE1E,MACE,OAAO,mBAAmB,YAC1B,MAAM,QAAQ,cAAc,KAC5B,eAAe,WAAW,GAC1B;AACA,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF,WAAW,CAAC,gBAAgB;AAC1B,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,mBAAmB;AAChE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,gBAAgB;AAC7D;AAAA,EACF;AAEA,MAAI;AACF,UAAM,EAAE,yBAAyB,mBAAmB,IAClD,MAAM,kBAAkB;AAAA,MACtB;AAAA,MACA,QAAQ;AAAA,IACV;AAEF,UAAM,uBAAuB,eAAe;AAAA,MAAO,CAAC,eAClD,wBAAwB,SAAS,WAAW,GAAG;AAAA,IACjD;AACA,UAAM,kBAAkB,eAAe;AAAA,MAAO,CAAC,eAC7C,mBAAmB,SAAS,WAAW,GAAG;AAAA,IAC5C;AAEA,UAAM,SAAqC;AAAA,MACzC,iBAAiB,CAAC;AAAA,MAClB,qBAAqB,CAAC;AAAA,MACtB,OAAO,CAAC;AAAA,IACV;AAEA,eAAW,oBAAoB,iBAAiB;AAC9C,YAAM,aAA6B;AAAA,QACjC,OAAO,iBAAiB;AAAA,QACxB,aAAa,iBAAiB;AAAA,QAC9B,SAAS,CAAC,iBAAiB,OAAO;AAAA,QAClC,YAAY,CAAC,OAAO,QAAQ,GAAG,CAAC;AAAA,QAChC,WAAW,KAAK;AAAA,QAChB,UAAU,EAAE,CAAC,OAAO,QAAQ,GAAG,CAAC,GAAG,iBAAiB,YAAY,GAAG;AAAA,QACnE,KAAK,iBAAiB;AAAA,MACxB;AAEA,UAAI;AACF,cAAM,gBACJ,MAAM,kBAAkB,iBAAiB,UAAU;AACrD,eAAO,gBAAgB,KAAK,cAAc,GAAG;AAAA,MAC/C,SAAS,OAAO;AACd,mCAAa,uBAAuB,KAAK,KAAiB;AAAA,MAC5D;AAAA,IACF;AAEA,QAAI,wBAAwB,UAAU,GAAG;AACvC,YAAM,yBACJ,MAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,QAAQ;AAAA,MACV;AAEF,iBAAW,oBAAoB,sBAAsB;AACnD,cAAM,uBAAuB,uBAAuB;AAAA,UAClD,CAAC,iBAAiB,aAAa,QAAQ,iBAAiB;AAAA,QAC1D;AAEA,cAAM,aAA6B;AAAA,UACjC,GAAG;AAAA,UACH,GAAG;AAAA,UACH,SAAS;AAAA,YACP,GAAI,qBAAqB,WAAW,CAAC;AAAA,YACrC,iBAAiB;AAAA,UACnB;AAAA,UACA,YAAY,CAAC,OAAO,QAAQ,GAAG,CAAC;AAAA,UAChC,WAAW,KAAK;AAAA,UAChB,UAAU,EAAE,CAAC,OAAO,QAAQ,GAAG,CAAC,GAAG,iBAAiB,YAAY,GAAG;AAAA,UACnE,KAAK,iBAAiB;AAAA,QACxB;AAEA,YAAI;AACF,gBAAM,gBAAgB,MAAM,kBAAkB;AAAA,YAC5C,iBAAiB;AAAA,YACjB;AAAA,YACA,QAAQ;AAAA,UACV;AACA,iBAAO,oBAAoB,KAAK,cAAc,GAAG;AAAA,QACnD,SAAS,OAAO;AACd,qCAAa,uBAAuB,KAAK,KAAiB;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAEA,UAAM,mBAAe,oCAA2C;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAQO,MAAM,mBAAmB,OAC9B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,iBAAiB,IAAI;AAE3B,MAAI,CAAC,gBAAgB;AACnB,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,mBAAmB;AAChE;AAAA,EACF;AAEA,MAAI,CAAC,eAAe,YAAY,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AAC7D,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI,OAAO,eAAe,QAAQ,aAAa;AAC7C,+BAAa,2BAA2B,KAAK,yBAAyB;AACtE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,oBAAoB,MAAM,kBAAkB;AAAA,MAChD,eAAe;AAAA,MACf;AAAA,IACF;AAEA,UAAM,gBAAY,sCAAmB,mBAAmB,QAAQ,GAAG;AAEnE,UAAM,mBAAe,oCAA8B;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAQO,MAAM,mBAAmB,OAC9B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,EAAE,aAAa,IAAI,IAAI;AAE7B,MAAI,CAAC,cAAc;AACjB,+BAAa,2BAA2B,KAAK,yBAAyB;AACtE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,mBAAmB;AAChE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,qBACJ,MAAM,kBAAkB,kBAAkB,YAAY;AAExD,QAAI,CAAC,mBAAmB,WAAW,SAAS,QAAQ,GAAG,GAAG;AACxD,iCAAa;AAAA,QACX;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,oBACJ,MAAM,kBAAkB,qBAAqB,YAAY;AAE3D,QAAI,CAAC,mBAAmB;AACtB,iCAAa,2BAA2B,KAAK,wBAAwB;AAAA,QACnE;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,yBAAO,KAAK,uBAAuB,OAAO,kBAAkB,GAAG,CAAC,EAAE;AAElE,UAAM,gBAAY,sCAAmB,mBAAmB,QAAQ,GAAG;AAEnE,UAAM,mBAAe,oCAA8B;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/controllers/dictionary.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { type Dictionary as LocalDictionary } from '@intlayer/core';\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport * as dictionaryService from '@services/dictionary.service';\nimport { AppError, ErrorHandler } from '@utils/errors';\nimport {\n type DictionaryFiltersParams,\n getDictionaryFiltersAndPagination,\n} from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport { mapDictionaryToAPI } from '@utils/mapper/dictionary';\nimport {\n formatPaginatedResponse,\n type ResponseData,\n type PaginatedResponse,\n formatResponse,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type {\n Dictionary,\n DictionaryAPI,\n DictionaryCreationData,\n DictionaryData,\n} from '@/types/dictionary.types';\n\nexport type GetDictionariesParams =\n FiltersAndPagination<DictionaryFiltersParams>;\nexport type GetDictionariesResult = PaginatedResponse<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaries = async (\n req: Request<GetDictionariesParams>,\n res: ResponseWithInformation<GetDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, dictionaryRights } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getDictionaryFiltersAndPagination(req);\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionaries = await dictionaryService.findDictionaries(\n filters,\n skip,\n pageSize\n );\n const totalItems = await dictionaryService.countDictionaries(filters);\n\n const dictionariesAPI = dictionaries.map((el) =>\n mapDictionaryToAPI(el, project._id)\n );\n\n const responseData = formatPaginatedResponse<DictionaryAPI>({\n data: dictionariesAPI,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetDictionariesKeysResult = ResponseData<string[]>;\n\n/**\n * Retrieves a list of dictionaries keys based on filters and pagination.\n */\nexport const getDictionariesKeys = async (\n _req: Request,\n res: ResponseWithInformation<GetDictionariesKeysResult>,\n _next: NextFunction\n) => {\n const { project, dictionaryRights } = res.locals;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionariesKeys = await dictionaryService.getDictionariesKeys(\n project._id\n );\n\n const responseData = formatResponse<string[]>({\n data: dictionariesKeys,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetDictionaryParams = { dictionaryKey: string };\nexport type GetDictionaryQuery = { version?: number };\nexport type GetDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaryByKey = async (\n req: Request<GetDictionaryParams>,\n res: ResponseWithInformation<GetDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const { dictionaryKey } = req.params;\n const { version } = req.query as GetDictionaryQuery;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionaries = await dictionaryService.getDictionaryByKey(\n dictionaryKey,\n project._id\n );\n\n if (!dictionaries.projectIds.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const apiResult = mapDictionaryToAPI(dictionaries, project._id, version);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AddDictionaryBody = DictionaryCreationData;\nexport type AddDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const addDictionary = async (\n req: Request<any, any, AddDictionaryBody>,\n res: ResponseWithInformation<AddDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const dictionaryData = req.body;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryData.projectIds.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n const dictionary: DictionaryData = {\n key: dictionaryData.key,\n title: dictionaryData.title,\n description: dictionaryData.description,\n content: [dictionaryData.content],\n creatorId: user._id,\n filePath: { [String(project._id)]: dictionaryData.filePath ?? '' },\n projectIds: dictionaryData.projectIds ?? [String(project._id)],\n };\n\n try {\n const newDictionary = await dictionaryService.createDictionary(dictionary);\n\n const apiResult = mapDictionaryToAPI(newDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type PushDictionariesBody = { dictionaries: LocalDictionary[] };\ntype PushDictionariesResultData = {\n newDictionaries: string[];\n updatedDictionaries: string[];\n error: { dictionaryId: string; message: string }[];\n};\nexport type PushDictionariesResult = ResponseData<PushDictionariesResultData>;\n\n/**\n * Check each dictionaries, add the new ones and update the existing ones.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response containing the created dictionary.\n */\nexport const pushDictionaries = async (\n req: Request<any, any, PushDictionariesBody>,\n res: ResponseWithInformation<PushDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const dictionaryData = req.body.dictionaries;\n const dictionariesKeys = dictionaryData.map((dictionary) => dictionary.key);\n\n if (\n typeof dictionaryData === 'object' &&\n Array.isArray(dictionaryData) &&\n dictionaryData.length === 0\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARIES_NOT_PROVIDED');\n return;\n } else if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryRights?.write) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_WRITE');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n try {\n const { existingDictionariesKey, newDictionariesKey } =\n await dictionaryService.getExistingDictionaryKey(\n dictionariesKeys,\n project._id\n );\n\n const existingDictionaries = dictionaryData.filter((dictionary) =>\n existingDictionariesKey.includes(dictionary.key)\n );\n const newDictionaries = dictionaryData.filter((dictionary) =>\n newDictionariesKey.includes(dictionary.key)\n );\n\n const result: PushDictionariesResultData = {\n newDictionaries: [],\n updatedDictionaries: [],\n error: [],\n };\n\n for (const dictionaryDataEl of newDictionaries) {\n const dictionary: DictionaryData = {\n title: dictionaryDataEl.title,\n description: dictionaryDataEl.description,\n content: [dictionaryDataEl.content],\n projectIds: [String(project._id)],\n creatorId: user._id,\n filePath: { [String(project._id)]: dictionaryDataEl.filePath ?? '' },\n key: dictionaryDataEl.key,\n };\n\n try {\n const newDictionary =\n await dictionaryService.createDictionary(dictionary);\n result.newDictionaries.push(newDictionary.key);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n }\n\n if (existingDictionariesKey.length >= 0) {\n const existingDictionariesDB =\n await dictionaryService.getDictionariesByKeys(\n existingDictionariesKey,\n project._id\n );\n\n for (const dictionaryDataEl of existingDictionaries) {\n const existingDictionaryDB = existingDictionariesDB.find(\n (dictionaryDB) => dictionaryDB.key === dictionaryDataEl.key\n )!;\n\n const dictionary: DictionaryData = {\n ...existingDictionaryDB,\n ...dictionaryDataEl,\n content: [\n ...(existingDictionaryDB.content ?? []),\n dictionaryDataEl.content,\n ],\n projectIds: [String(project._id)],\n creatorId: user._id,\n filePath: { [String(project._id)]: dictionaryDataEl.filePath ?? '' },\n key: dictionaryDataEl.key,\n };\n\n try {\n const newDictionary = await dictionaryService.updateDictionaryByKey(\n dictionaryDataEl.key,\n dictionary,\n project._id\n );\n result.updatedDictionaries.push(newDictionary.key);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n }\n }\n\n const responseData = formatResponse<PushDictionariesResultData>({\n data: result,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateDictionaryBody = Partial<Dictionary>;\nexport type UpdateDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Updates an existing dictionary in the database.\n */\nexport const updateDictionary = async (\n req: Request<any, any, UpdateDictionaryBody>,\n res: ResponseWithInformation<UpdateDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, dictionaryRights } = res.locals;\n const dictionaryData = req.body;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryData.projectIds?.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n if (typeof dictionaryData._id === 'undefined') {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n if (!dictionaryRights?.write) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_WRITE');\n return;\n }\n\n try {\n const updatedDictionary = await dictionaryService.updateDictionaryById(\n dictionaryData._id,\n dictionaryData\n );\n\n const apiResult = mapDictionaryToAPI(updatedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteDictionaryParam = { dictionaryId: string };\nexport type DeleteDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Deletes a dictionary from the database by its ID.\n */\nexport const deleteDictionary = async (\n req: Request<DeleteDictionaryParam>,\n res: ResponseWithInformation<DeleteDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, dictionaryRights } = res.locals;\n const { dictionaryId } = req.params as Partial<DeleteDictionaryParam>;\n\n if (!dictionaryId) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n try {\n const dictionaryToDelete =\n await dictionaryService.getDictionaryById(dictionaryId);\n\n if (!dictionaryToDelete.projectIds.includes(project._id)) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const deletedDictionary =\n await dictionaryService.deleteDictionaryById(dictionaryId);\n\n if (!deletedDictionary) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_NOT_FOUND', {\n dictionaryId,\n });\n return;\n }\n\n logger.info(`Dictionary deleted: ${String(deletedDictionary._id)}`);\n\n const apiResult = mapDictionaryToAPI(deletedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
|
|
@@ -42,17 +42,26 @@ module.exports = __toCommonJS(organization_controller_exports);
|
|
|
42
42
|
var import_logger = require('./../logger/index.cjs');
|
|
43
43
|
var import_sessionAuth = require('./../routes/sessionAuth.routes.cjs');
|
|
44
44
|
var import_email = require('./../services/email.service.cjs');
|
|
45
|
+
var import_plans = require('./../services/plans.service.cjs');
|
|
45
46
|
var sessionAuthService = __toESM(require('./../services/sessionAuth.service.cjs'), 1);
|
|
46
47
|
var userService = __toESM(require('./../services/user.service.cjs'), 1);
|
|
47
48
|
var import_errors = require('./../utils/errors/index.cjs');
|
|
48
49
|
var import_getOrganizationFiltersAndPagination = require('./../utils/filtersAndPagination/getOrganizationFiltersAndPagination.cjs');
|
|
50
|
+
var import_plan = require('./../utils/plan.cjs');
|
|
49
51
|
var import_responseData = require('./../utils/responseData.cjs');
|
|
50
52
|
var organizationService = __toESM(require('./../services/organization.service.cjs'), 1);
|
|
51
53
|
const getOrganizations = async (req, res, _next) => {
|
|
52
|
-
const { user } = res.locals;
|
|
54
|
+
const { user, organizationRights } = res.locals;
|
|
53
55
|
const { filters, pageSize, skip, page, getNumberOfPages } = (0, import_getOrganizationFiltersAndPagination.getOrganizationFiltersAndPagination)(req);
|
|
54
56
|
if (!user) {
|
|
55
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
57
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!organizationRights?.read) {
|
|
61
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(
|
|
62
|
+
res,
|
|
63
|
+
"ORGANIZATION_RIGHTS_NOT_READ"
|
|
64
|
+
);
|
|
56
65
|
return;
|
|
57
66
|
}
|
|
58
67
|
const restrictedFilter = {
|
|
@@ -81,7 +90,15 @@ const getOrganizations = async (req, res, _next) => {
|
|
|
81
90
|
}
|
|
82
91
|
};
|
|
83
92
|
const getOrganization = async (req, res, _next) => {
|
|
93
|
+
const { organizationRights } = res.locals;
|
|
84
94
|
const { organizationId } = req.params;
|
|
95
|
+
if (!organizationRights?.read) {
|
|
96
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(
|
|
97
|
+
res,
|
|
98
|
+
"ORGANIZATION_RIGHTS_NOT_READ"
|
|
99
|
+
);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
85
102
|
if (!organizationId) {
|
|
86
103
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_ID_NOT_FOUND");
|
|
87
104
|
return;
|
|
@@ -103,7 +120,7 @@ const addOrganization = async (req, res, _next) => {
|
|
|
103
120
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_DATA_NOT_FOUND");
|
|
104
121
|
}
|
|
105
122
|
if (!user) {
|
|
106
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
123
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
107
124
|
return;
|
|
108
125
|
}
|
|
109
126
|
try {
|
|
@@ -122,14 +139,21 @@ const addOrganization = async (req, res, _next) => {
|
|
|
122
139
|
}
|
|
123
140
|
};
|
|
124
141
|
const updateOrganization = async (req, res, _next) => {
|
|
125
|
-
const { isOrganizationAdmin, organization } = res.locals;
|
|
142
|
+
const { isOrganizationAdmin, organization, organizationRights } = res.locals;
|
|
126
143
|
const organizationFields = req.body;
|
|
127
144
|
if (!organizationFields) {
|
|
128
145
|
import_errors.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_DATA_NOT_FOUND");
|
|
129
146
|
return;
|
|
130
147
|
}
|
|
131
148
|
if (!organization) {
|
|
132
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
149
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!organizationRights?.write) {
|
|
153
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(
|
|
154
|
+
res,
|
|
155
|
+
"ORGANIZATION_RIGHTS_NOT_WRITE"
|
|
156
|
+
);
|
|
133
157
|
return;
|
|
134
158
|
}
|
|
135
159
|
if (!isOrganizationAdmin) {
|
|
@@ -155,14 +179,14 @@ const updateOrganization = async (req, res, _next) => {
|
|
|
155
179
|
}
|
|
156
180
|
};
|
|
157
181
|
const addOrganizationMember = async (req, res, _next) => {
|
|
158
|
-
const { organization, isOrganizationAdmin, user } = res.locals;
|
|
182
|
+
const { organization, isOrganizationAdmin, user, organizationRights } = res.locals;
|
|
159
183
|
const { userEmail } = req.body;
|
|
160
184
|
if (!organization) {
|
|
161
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
185
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
162
186
|
return;
|
|
163
187
|
}
|
|
164
188
|
if (!user) {
|
|
165
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
189
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
166
190
|
return;
|
|
167
191
|
}
|
|
168
192
|
if (!isOrganizationAdmin) {
|
|
@@ -172,6 +196,27 @@ const addOrganizationMember = async (req, res, _next) => {
|
|
|
172
196
|
);
|
|
173
197
|
return;
|
|
174
198
|
}
|
|
199
|
+
if (!organizationRights?.admin) {
|
|
200
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(
|
|
201
|
+
res,
|
|
202
|
+
"ORGANIZATION_RIGHTS_NOT_ADMIN"
|
|
203
|
+
);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const plan = await (0, import_plans.getPlan)({ organizationId: organization._id });
|
|
207
|
+
if (!plan) {
|
|
208
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PLAN_NOT_FOUND", {
|
|
209
|
+
organizationId: organization._id
|
|
210
|
+
});
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const planType = (0, import_plan.getPLanDetails)(plan.type);
|
|
214
|
+
if (planType.numberOfOrganizationUsers && organization.membersIds.length >= planType.numberOfOrganizationUsers) {
|
|
215
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "PLAN_USER_LIMIT_REACHED", {
|
|
216
|
+
organizationId: organization._id
|
|
217
|
+
});
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
175
220
|
try {
|
|
176
221
|
let newMember = await userService.getUserByEmail(userEmail);
|
|
177
222
|
if (!newMember) {
|
|
@@ -210,10 +255,10 @@ const addOrganizationMember = async (req, res, _next) => {
|
|
|
210
255
|
}
|
|
211
256
|
};
|
|
212
257
|
const updateOrganizationMembers = async (req, res, _next) => {
|
|
213
|
-
const { organization, isOrganizationAdmin } = res.locals;
|
|
258
|
+
const { organization, organizationRights, isOrganizationAdmin } = res.locals;
|
|
214
259
|
const { membersIds } = req.body;
|
|
215
260
|
if (!organization) {
|
|
216
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
261
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
217
262
|
return;
|
|
218
263
|
}
|
|
219
264
|
if (!isOrganizationAdmin) {
|
|
@@ -223,6 +268,13 @@ const updateOrganizationMembers = async (req, res, _next) => {
|
|
|
223
268
|
);
|
|
224
269
|
return;
|
|
225
270
|
}
|
|
271
|
+
if (!organizationRights?.write) {
|
|
272
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(
|
|
273
|
+
res,
|
|
274
|
+
"ORGANIZATION_RIGHTS_NOT_WRITE"
|
|
275
|
+
);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
226
278
|
if (membersIds?.length === 0) {
|
|
227
279
|
import_errors.ErrorHandler.handleGenericErrorResponse(
|
|
228
280
|
res,
|
|
@@ -275,9 +327,9 @@ const updateOrganizationMembers = async (req, res, _next) => {
|
|
|
275
327
|
}
|
|
276
328
|
};
|
|
277
329
|
const deleteOrganization = async (_req, res, _next) => {
|
|
278
|
-
const { isOrganizationAdmin, organization } = res.locals;
|
|
330
|
+
const { isOrganizationAdmin, organization, organizationRights } = res.locals;
|
|
279
331
|
if (!organization) {
|
|
280
|
-
import_errors.ErrorHandler.handleGenericErrorResponse(res, "
|
|
332
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
281
333
|
return;
|
|
282
334
|
}
|
|
283
335
|
if (!isOrganizationAdmin) {
|
|
@@ -287,6 +339,13 @@ const deleteOrganization = async (_req, res, _next) => {
|
|
|
287
339
|
);
|
|
288
340
|
return;
|
|
289
341
|
}
|
|
342
|
+
if (!organizationRights?.admin) {
|
|
343
|
+
import_errors.ErrorHandler.handleGenericErrorResponse(
|
|
344
|
+
res,
|
|
345
|
+
"ORGANIZATION_RIGHTS_NOT_ADMIN"
|
|
346
|
+
);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
290
349
|
try {
|
|
291
350
|
const deletedOrganization = await organizationService.deleteOrganizationById(organization._id);
|
|
292
351
|
if (!deletedOrganization) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/controllers/organization.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\nimport { sendEmail } from '@services/email.service';\nimport * as sessionAuthService from '@services/sessionAuth.service';\nimport * as userService from '@services/user.service';\nimport { AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport {\n getOrganizationFiltersAndPagination,\n type OrganizationFiltersParams,\n type OrganizationFilters,\n} from '@utils/filtersAndPagination/getOrganizationFiltersAndPagination';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type { ObjectId } from 'mongoose';\nimport { User } from 'oauth2-server';\nimport * as organizationService from '@/services/organization.service';\nimport type {\n Organization,\n OrganizationCreationData,\n} from '@/types/organization.types';\n\nexport type GetOrganizationsParams =\n FiltersAndPagination<OrganizationFiltersParams>;\nexport type GetOrganizationsResult = PaginatedResponse<Organization>;\n\n/**\n * Retrieves a list of organizations based on filters and pagination.\n */\nexport const getOrganizations = async (\n req: Request<GetOrganizationsParams>,\n res: ResponseWithInformation<GetOrganizationsResult>,\n _next: NextFunction\n) => {\n const { user } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getOrganizationFiltersAndPagination(req);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n const restrictedFilter: OrganizationFilters = {\n ...filters,\n\n membersIds: { $in: [...(filters.membersIds ?? []), String(user._id)] },\n };\n\n try {\n const organizations = await organizationService.findOrganizations(\n restrictedFilter,\n skip,\n pageSize\n );\n const totalItems = await organizationService.countOrganizations(filters);\n\n const responseData = formatPaginatedResponse<Organization>({\n data: organizations,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.status(200).json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetOrganizationParam = { organizationId: string };\nexport type GetOrganizationResult = ResponseData<Organization>;\n\n/**\n * Retrieves an organization by its ID.\n */\nexport const getOrganization = async (\n req: Request<GetOrganizationParam, any, any>,\n res: ResponseWithInformation<GetOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organizationId } = req.params as Partial<GetOrganizationParam>;\n\n if (!organizationId) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_ID_NOT_FOUND');\n return;\n }\n\n try {\n const organization =\n await organizationService.getOrganizationById(organizationId);\n\n const responseData = formatResponse<Organization>({ data: organization });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AddOrganizationBody = OrganizationCreationData;\nexport type AddOrganizationResult = ResponseData<Organization>;\n\n/**\n * Adds a new organization to the database.\n */\nexport const addOrganization = async (\n req: Request<any, any, AddOrganizationBody>,\n res: ResponseWithInformation<AddOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n const organization = req.body;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_DATA_NOT_FOUND');\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n try {\n const newOrganization = await organizationService.createOrganization(\n organization,\n user._id\n );\n\n const responseData = formatResponse<Organization>({\n data: newOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateOrganizationBody = Partial<Organization>;\nexport type UpdateOrganizationResult = ResponseData<Organization>;\n\n/**\n * Updates an existing organization in the database.\n */\nexport const updateOrganization = async (\n req: Request<undefined, undefined, UpdateOrganizationBody>,\n res: ResponseWithInformation<UpdateOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { isOrganizationAdmin, organization } = res.locals;\n const organizationFields = req.body;\n\n if (!organizationFields) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_DATA_NOT_FOUND');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_FOUND');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n try {\n const updatedOrganization =\n await organizationService.updateOrganizationById(\n organization._id,\n organizationFields\n );\n\n const responseData = formatResponse<Organization>({\n data: updatedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\ntype UserAndAdmin = { user: User; isAdmin: boolean };\n\nexport type OrganizationMemberByIdOption = {\n userId: string | ObjectId;\n isAdmin?: boolean;\n};\n\nexport type AddOrganizationMemberBody = {\n userEmail: string;\n};\nexport type AddOrganizationMemberResult = ResponseData<Organization>;\n\n/**\n * Add member to the organization in the database.\n */\nexport const addOrganizationMember = async (\n req: Request<any, any, AddOrganizationMemberBody>,\n res: ResponseWithInformation<AddOrganizationMemberResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, isOrganizationAdmin, user } = res.locals;\n const { userEmail } = req.body;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_FOUND');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n try {\n let newMember = await userService.getUserByEmail(userEmail);\n\n if (!newMember) {\n // Create user if not found\n const newUser = await userService.createUser({ email: userEmail });\n if (!newUser) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_CREATION_FAILED', {\n email: userEmail,\n });\n return;\n }\n\n newMember = newUser;\n }\n\n await sendEmail({\n type: 'invite',\n to: userEmail,\n username: newMember.email.slice(0, newMember.email.indexOf('@')),\n invitedByUsername: user.name,\n invitedByEmail: user.email,\n organizationName: organization.name,\n inviteLink: sessionAuthRoutes.loginEmailPassword.url,\n inviteFromIp: req.ip ?? '',\n inviteFromLocation: req.hostname,\n });\n\n const updatedOrganization =\n await organizationService.updateOrganizationById(organization._id, {\n ...organization,\n membersIds: [...organization.membersIds, newMember._id],\n });\n\n const responseData = formatResponse<Organization>({\n data: updatedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateOrganizationMembersBody = Partial<{\n membersIds: OrganizationMemberByIdOption[];\n}>;\nexport type UpdateOrganizationMembersResult = ResponseData<Organization>;\n\n/**\n * Update members to the organization in the database.\n */\nexport const updateOrganizationMembers = async (\n req: Request<any, any, UpdateOrganizationMembersBody>,\n res: ResponseWithInformation<UpdateOrganizationMembersResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, isOrganizationAdmin } = res.locals;\n const { membersIds } = req.body;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_FOUND');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n if (membersIds?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_MUST_HAVE_MEMBER'\n );\n return;\n }\n\n if (membersIds?.map((el) => el.isAdmin)?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_MUST_HAVE_ADMIN'\n );\n return;\n }\n\n try {\n let existingUsers: UserAndAdmin[] = [];\n\n if (membersIds) {\n const userIdList = membersIds?.map((member) => member.userId);\n const users = await userService.getUsersByIds(userIdList);\n\n if (users) {\n const userMap: UserAndAdmin[] = users.map((user) => {\n const isAdmin =\n membersIds.find(\n (member) => String(member.userId) === String(user._id)\n )?.isAdmin ?? false;\n\n return {\n user,\n isAdmin,\n };\n });\n\n existingUsers = userMap;\n }\n }\n\n const formattedMembers: ObjectId[] = existingUsers.map(\n (user) => user.user._id\n );\n const formattedAdmin: ObjectId[] = existingUsers\n .filter((el) => el.isAdmin)\n .map((user) => user.user._id);\n\n const updatedOrganization =\n await organizationService.updateOrganizationById(organization._id, {\n ...organization,\n membersIds: formattedMembers,\n adminsIds: formattedAdmin,\n });\n\n const responseData = formatResponse<Organization>({\n data: updatedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteOrganizationResult = ResponseData<Organization>;\n\n/**\n * Deletes an organization from the database by its ID.\n */\nexport const deleteOrganization = async (\n _req: Request,\n res: ResponseWithInformation,\n _next: NextFunction\n): Promise<void> => {\n const { isOrganizationAdmin, organization } = res.locals;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_FOUND');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n try {\n const deletedOrganization =\n await organizationService.deleteOrganizationById(organization._id);\n\n if (!deletedOrganization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_FOUND', {\n organizationId: organization._id,\n });\n return;\n }\n\n logger.info(`Organization deleted: ${String(deletedOrganization._id)}`);\n\n const responseData = formatResponse<Organization>({\n data: deletedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type SelectOrganizationParam = { organizationId: ObjectId | string };\nexport type SelectOrganizationResult = ResponseData<Organization>;\n\n/**\n * Select an organization.\n */\nexport const selectOrganization = async (\n req: Request<SelectOrganizationParam>,\n res: ResponseWithInformation<SelectOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organizationId } = req.params as Partial<SelectOrganizationParam>;\n\n if (!organizationId) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_ID_NOT_FOUND');\n return;\n }\n\n try {\n const organization =\n await organizationService.getOrganizationById(organizationId);\n\n sessionAuthService.setOrganizationAuth(res, organization);\n\n const responseData = formatResponse<Organization>({\n data: organization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UnselectOrganizationResult = ResponseData<null>;\n\n/**\n * Unselect an organization.\n */\nexport const unselectOrganization = (\n _req: Request,\n res: ResponseWithInformation<UnselectOrganizationResult>,\n _next: NextFunction\n): void => {\n try {\n sessionAuthService.clearOrganizationAuth(res);\n sessionAuthService.clearProjectAuth(res);\n\n const responseData = formatResponse<null>({\n data: null,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/controllers/organization.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\nimport { sendEmail } from '@services/email.service';\nimport { getPlan } from '@services/plans.service';\nimport * as sessionAuthService from '@services/sessionAuth.service';\nimport * as userService from '@services/user.service';\nimport { AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport {\n getOrganizationFiltersAndPagination,\n type OrganizationFiltersParams,\n type OrganizationFilters,\n} from '@utils/filtersAndPagination/getOrganizationFiltersAndPagination';\nimport { getPLanDetails } from '@utils/plan';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type { ObjectId } from 'mongoose';\nimport { User } from 'oauth2-server';\nimport * as organizationService from '@/services/organization.service';\nimport type {\n Organization,\n OrganizationCreationData,\n} from '@/types/organization.types';\n\nexport type GetOrganizationsParams =\n FiltersAndPagination<OrganizationFiltersParams>;\nexport type GetOrganizationsResult = PaginatedResponse<Organization>;\n\n/**\n * Retrieves a list of organizations based on filters and pagination.\n */\nexport const getOrganizations = async (\n req: Request<GetOrganizationsParams>,\n res: ResponseWithInformation<GetOrganizationsResult>,\n _next: NextFunction\n) => {\n const { user, organizationRights } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getOrganizationFiltersAndPagination(req);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organizationRights?.read) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_RIGHTS_NOT_READ'\n );\n return;\n }\n\n const restrictedFilter: OrganizationFilters = {\n ...filters,\n\n membersIds: { $in: [...(filters.membersIds ?? []), String(user._id)] },\n };\n\n try {\n const organizations = await organizationService.findOrganizations(\n restrictedFilter,\n skip,\n pageSize\n );\n const totalItems = await organizationService.countOrganizations(filters);\n\n const responseData = formatPaginatedResponse<Organization>({\n data: organizations,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.status(200).json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetOrganizationParam = { organizationId: string };\nexport type GetOrganizationResult = ResponseData<Organization>;\n\n/**\n * Retrieves an organization by its ID.\n */\nexport const getOrganization = async (\n req: Request<GetOrganizationParam, any, any>,\n res: ResponseWithInformation<GetOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organizationRights } = res.locals;\n const { organizationId } = req.params as Partial<GetOrganizationParam>;\n\n if (!organizationRights?.read) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_RIGHTS_NOT_READ'\n );\n return;\n }\n\n if (!organizationId) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_ID_NOT_FOUND');\n return;\n }\n\n try {\n const organization =\n await organizationService.getOrganizationById(organizationId);\n\n const responseData = formatResponse<Organization>({ data: organization });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AddOrganizationBody = OrganizationCreationData;\nexport type AddOrganizationResult = ResponseData<Organization>;\n\n/**\n * Adds a new organization to the database.\n */\nexport const addOrganization = async (\n req: Request<any, any, AddOrganizationBody>,\n res: ResponseWithInformation<AddOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n const organization = req.body;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_DATA_NOT_FOUND');\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n try {\n const newOrganization = await organizationService.createOrganization(\n organization,\n user._id\n );\n\n const responseData = formatResponse<Organization>({\n data: newOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateOrganizationBody = Partial<Organization>;\nexport type UpdateOrganizationResult = ResponseData<Organization>;\n\n/**\n * Updates an existing organization in the database.\n */\nexport const updateOrganization = async (\n req: Request<undefined, undefined, UpdateOrganizationBody>,\n res: ResponseWithInformation<UpdateOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { isOrganizationAdmin, organization, organizationRights } = res.locals;\n const organizationFields = req.body;\n\n if (!organizationFields) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_DATA_NOT_FOUND');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!organizationRights?.write) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_RIGHTS_NOT_WRITE'\n );\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n try {\n const updatedOrganization =\n await organizationService.updateOrganizationById(\n organization._id,\n organizationFields\n );\n\n const responseData = formatResponse<Organization>({\n data: updatedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\ntype UserAndAdmin = { user: User; isAdmin: boolean };\n\nexport type OrganizationMemberByIdOption = {\n userId: string | ObjectId;\n isAdmin?: boolean;\n};\n\nexport type AddOrganizationMemberBody = {\n userEmail: string;\n};\nexport type AddOrganizationMemberResult = ResponseData<Organization>;\n\n/**\n * Add member to the organization in the database.\n */\nexport const addOrganizationMember = async (\n req: Request<any, any, AddOrganizationMemberBody>,\n res: ResponseWithInformation<AddOrganizationMemberResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, isOrganizationAdmin, user, organizationRights } =\n res.locals;\n const { userEmail } = req.body;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n if (!organizationRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_RIGHTS_NOT_ADMIN'\n );\n return;\n }\n\n const plan = await getPlan({ organizationId: organization._id });\n\n if (!plan) {\n ErrorHandler.handleGenericErrorResponse(res, 'PLAN_NOT_FOUND', {\n organizationId: organization._id,\n });\n return;\n }\n\n const planType = getPLanDetails(plan.type);\n\n if (\n planType.numberOfOrganizationUsers &&\n organization.membersIds.length >= planType.numberOfOrganizationUsers\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'PLAN_USER_LIMIT_REACHED', {\n organizationId: organization._id,\n });\n return;\n }\n\n try {\n let newMember = await userService.getUserByEmail(userEmail);\n\n if (!newMember) {\n // Create user if not found\n const newUser = await userService.createUser({ email: userEmail });\n if (!newUser) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_CREATION_FAILED', {\n email: userEmail,\n });\n return;\n }\n\n newMember = newUser;\n }\n\n await sendEmail({\n type: 'invite',\n to: userEmail,\n username: newMember.email.slice(0, newMember.email.indexOf('@')),\n invitedByUsername: user.name,\n invitedByEmail: user.email,\n organizationName: organization.name,\n inviteLink: sessionAuthRoutes.loginEmailPassword.url,\n inviteFromIp: req.ip ?? '',\n inviteFromLocation: req.hostname,\n });\n\n const updatedOrganization =\n await organizationService.updateOrganizationById(organization._id, {\n ...organization,\n membersIds: [...organization.membersIds, newMember._id],\n });\n\n const responseData = formatResponse<Organization>({\n data: updatedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateOrganizationMembersBody = Partial<{\n membersIds: OrganizationMemberByIdOption[];\n}>;\nexport type UpdateOrganizationMembersResult = ResponseData<Organization>;\n\n/**\n * Update members to the organization in the database.\n */\nexport const updateOrganizationMembers = async (\n req: Request<any, any, UpdateOrganizationMembersBody>,\n res: ResponseWithInformation<UpdateOrganizationMembersResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, organizationRights, isOrganizationAdmin } = res.locals;\n const { membersIds } = req.body;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n if (!organizationRights?.write) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_RIGHTS_NOT_WRITE'\n );\n return;\n }\n\n if (membersIds?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_MUST_HAVE_MEMBER'\n );\n return;\n }\n\n if (membersIds?.map((el) => el.isAdmin)?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_MUST_HAVE_ADMIN'\n );\n return;\n }\n\n try {\n let existingUsers: UserAndAdmin[] = [];\n\n if (membersIds) {\n const userIdList = membersIds?.map((member) => member.userId);\n const users = await userService.getUsersByIds(userIdList);\n\n if (users) {\n const userMap: UserAndAdmin[] = users.map((user) => {\n const isAdmin =\n membersIds.find(\n (member) => String(member.userId) === String(user._id)\n )?.isAdmin ?? false;\n\n return {\n user,\n isAdmin,\n };\n });\n\n existingUsers = userMap;\n }\n }\n\n const formattedMembers: ObjectId[] = existingUsers.map(\n (user) => user.user._id\n );\n const formattedAdmin: ObjectId[] = existingUsers\n .filter((el) => el.isAdmin)\n .map((user) => user.user._id);\n\n const updatedOrganization =\n await organizationService.updateOrganizationById(organization._id, {\n ...organization,\n membersIds: formattedMembers,\n adminsIds: formattedAdmin,\n });\n\n const responseData = formatResponse<Organization>({\n data: updatedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteOrganizationResult = ResponseData<Organization>;\n\n/**\n * Deletes an organization from the database by its ID.\n */\nexport const deleteOrganization = async (\n _req: Request,\n res: ResponseWithInformation,\n _next: NextFunction\n): Promise<void> => {\n const { isOrganizationAdmin, organization, organizationRights } = res.locals;\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n return;\n }\n\n if (!organizationRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'ORGANIZATION_RIGHTS_NOT_ADMIN'\n );\n return;\n }\n\n try {\n const deletedOrganization =\n await organizationService.deleteOrganizationById(organization._id);\n\n if (!deletedOrganization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_FOUND', {\n organizationId: organization._id,\n });\n return;\n }\n\n logger.info(`Organization deleted: ${String(deletedOrganization._id)}`);\n\n const responseData = formatResponse<Organization>({\n data: deletedOrganization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type SelectOrganizationParam = { organizationId: ObjectId | string };\nexport type SelectOrganizationResult = ResponseData<Organization>;\n\n/**\n * Select an organization.\n */\nexport const selectOrganization = async (\n req: Request<SelectOrganizationParam>,\n res: ResponseWithInformation<SelectOrganizationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organizationId } = req.params as Partial<SelectOrganizationParam>;\n\n if (!organizationId) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_ID_NOT_FOUND');\n return;\n }\n\n try {\n const organization =\n await organizationService.getOrganizationById(organizationId);\n\n sessionAuthService.setOrganizationAuth(res, organization);\n\n const responseData = formatResponse<Organization>({\n data: organization,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UnselectOrganizationResult = ResponseData<null>;\n\n/**\n * Unselect an organization.\n */\nexport const unselectOrganization = (\n _req: Request,\n res: ResponseWithInformation<UnselectOrganizationResult>,\n _next: NextFunction\n): void => {\n try {\n sessionAuthService.clearOrganizationAuth(res);\n sessionAuthService.clearProjectAuth(res);\n\n const responseData = formatResponse<null>({\n data: null,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
|