@yrpri/api 9.0.231 → 9.0.233
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/agents/managers/subscriptionManager.js +2 -2
- package/controllers/allOurIdeas.js +1 -1
- package/controllers/communities.cjs +282 -91
- package/controllers/domains.cjs +54 -8
- package/controllers/groups.cjs +51 -6
- package/controllers/points.cjs +4 -9
- package/controllers/posts.cjs +7 -9
- package/controllers/ratings.cjs +3 -6
- package/models/point.cjs +31 -3
- package/models/post.cjs +2 -3
- package/package.json +32 -67
- package/services/engine/allOurIdeas/aiHelper.d.ts +7 -4
- package/services/engine/allOurIdeas/aiHelper.js +34 -19
- package/services/engine/allOurIdeas/explainAnswersAssistant.d.ts +1 -1
- package/services/engine/allOurIdeas/explainAnswersAssistant.js +3 -9
- package/services/engine/moderation/fraud/CreateFraudAuditReport.cjs +35 -11
- package/services/engine/moderation/fraud/CreateFraudAuditReport.d.cts +21 -0
- package/services/engine/moderation/fraud/FraudBase.cjs +38 -18
- package/services/engine/moderation/fraud/FraudBase.d.cts +2 -0
- package/services/engine/moderation/fraud/FraudDeleteBase.cjs +48 -29
- package/services/engine/moderation/fraud/FraudDeleteBase.d.cts +8 -6
- package/services/engine/moderation/fraud/FraudDeleteEndorsements.cjs +5 -4
- package/services/engine/moderation/fraud/FraudDeleteEndorsements.d.cts +2 -2
- package/services/engine/moderation/fraud/FraudDeletePointQualities.cjs +3 -2
- package/services/engine/moderation/fraud/FraudDeletePointQualities.d.cts +1 -1
- package/services/engine/moderation/fraud/FraudDeletePoints.cjs +3 -2
- package/services/engine/moderation/fraud/FraudDeletePoints.d.cts +1 -1
- package/services/engine/moderation/fraud/FraudDeletePosts.cjs +3 -2
- package/services/engine/moderation/fraud/FraudDeleteRatings.cjs +61 -4
- package/services/engine/moderation/fraud/FraudGetBase.cjs +44 -20
- package/services/engine/moderation/fraud/FraudGetBase.d.cts +5 -0
- package/services/engine/moderation/fraud/FraudGetEndorsements.cjs +4 -13
- package/services/engine/moderation/fraud/FraudGetEndorsements.d.cts +1 -1
- package/services/engine/moderation/fraud/FraudGetPointQualities.cjs +3 -0
- package/services/engine/moderation/fraud/FraudGetPointQualities.d.cts +1 -1
- package/services/engine/moderation/fraud/FraudGetPoints.cjs +3 -0
- package/services/engine/moderation/fraud/FraudGetPoints.d.cts +1 -1
- package/services/engine/moderation/fraud/FraudGetPosts.cjs +17 -16
- package/services/engine/moderation/fraud/FraudGetPosts.d.cts +3 -3
- package/services/engine/moderation/fraud/FraudGetRatings.cjs +62 -30
- package/services/engine/moderation/fraud/FraudGetRatings.d.cts +4 -1
- package/services/engine/moderation/fraud/FraudRequestValidation.cjs +143 -0
- package/services/engine/moderation/fraud/FraudRequestValidation.d.cts +21 -0
- package/services/engine/moderation/fraud/FraudScannerNotifier.cjs +59 -35
- package/services/engine/moderation/fraud/FraudScannerNotifier.d.cts +20 -1
- package/services/llms/baseChatBot.d.ts +2 -0
- package/services/llms/baseChatBot.js +25 -9
- package/services/llms/imageGeneration/chatGptImageGenerator.d.ts +2 -2
- package/services/llms/imageGeneration/chatGptImageGenerator.js +13 -10
- package/services/llms/imageGeneration/collectionImageGenerator.js +31 -13
- package/services/llms/imageGeneration/dalleImageGenerator.d.ts +2 -2
- package/services/llms/imageGeneration/dalleImageGenerator.js +28 -16
- package/services/llms/imageGeneration/fluxImageGenerator.d.ts +2 -2
- package/services/llms/imageGeneration/fluxImageGenerator.js +9 -3
- package/services/llms/imageGeneration/iImageGenerator.d.ts +8 -1
- package/services/llms/imageGeneration/imageModelConfig.cjs +319 -0
- package/services/llms/imageGeneration/imageModelConfig.d.cts +79 -0
- package/services/llms/imageGeneration/imagenImageGenerator.d.ts +2 -3
- package/services/llms/imageGeneration/imagenImageGenerator.js +10 -10
- package/tests/fraudManagement.test.cjs +470 -0
- package/tests/fraudManagement.test.d.cts +1 -0
- package/tests/imageModelConfig.test.cjs +144 -0
- package/tests/imageModelConfig.test.d.cts +1 -0
- package/utils/ai_image_generation_guard.cjs +268 -0
- package/utils/ai_image_generation_guard.d.cts +34 -0
- package/utils/fingerprint_data.cjs +32 -0
- package/utils/fingerprint_data.d.cts +6 -0
- package/utils/recount_utils.cjs +53 -37
- package/utils/recount_utils.d.cts +7 -7
|
@@ -11,6 +11,16 @@ const formatWorksheet = (worksheet) => {
|
|
|
11
11
|
worksheet.getRow(1).font = { bold: true };
|
|
12
12
|
// worksheet.properties.defaultRowHeight = 20;
|
|
13
13
|
};
|
|
14
|
+
const sanitizeWorksheetName = (name) => {
|
|
15
|
+
const sanitizedName = String(name || "Fraud Audit")
|
|
16
|
+
.replace(/[\\/\*\?:\[\]]/g, " ")
|
|
17
|
+
.replace(/\s+/g, " ")
|
|
18
|
+
.trim()
|
|
19
|
+
.substring(0, 31)
|
|
20
|
+
.trim()
|
|
21
|
+
.replace(/^'+|'+$/g, "");
|
|
22
|
+
return sanitizedName.trim() || "Fraud Audit";
|
|
23
|
+
};
|
|
14
24
|
class FraudAuditReport {
|
|
15
25
|
constructor(workPackage) {
|
|
16
26
|
this.workPackage = workPackage;
|
|
@@ -100,7 +110,7 @@ class FraudAuditReport {
|
|
|
100
110
|
return items;
|
|
101
111
|
}
|
|
102
112
|
async getPostItems(ids) {
|
|
103
|
-
return await
|
|
113
|
+
return await models.Post.unscoped().findAll({
|
|
104
114
|
attributes: ["id", "created_at", "group_id", "user_id", "user_agent", "ip_address", "data"],
|
|
105
115
|
where: {
|
|
106
116
|
id: {
|
|
@@ -133,7 +143,7 @@ class FraudAuditReport {
|
|
|
133
143
|
this.workBook = new Excel.Workbook();
|
|
134
144
|
this.workBook.creator = "Your Priorities Report - Automated";
|
|
135
145
|
this.workBook.created = new Date();
|
|
136
|
-
this.worksheet = this.workBook.addWorksheet(`Community Users ${this.workPackage.community.id} ${this.workPackage.userName}`);
|
|
146
|
+
this.worksheet = this.workBook.addWorksheet(sanitizeWorksheetName(`Community Users ${this.workPackage.community.id} ${this.workPackage.userName}`));
|
|
137
147
|
this.worksheet.columns = [
|
|
138
148
|
{ header: "Type", key: "collectionType", width: 20 },
|
|
139
149
|
{ header: "Method", key: "selectedMethod", width: 20 },
|
|
@@ -159,7 +169,7 @@ class FraudAuditReport {
|
|
|
159
169
|
}
|
|
160
170
|
if (['pointQualities'].indexOf(originalWorkPackage.collectionType) !== -1) {
|
|
161
171
|
this.worksheet.columns = this.worksheet.columns.concat([
|
|
162
|
-
{ header: "Point Id", key: "
|
|
172
|
+
{ header: "Point Id", key: "pointId", width: 20 },
|
|
163
173
|
]);
|
|
164
174
|
}
|
|
165
175
|
this.worksheet.columns = this.worksheet.columns.concat([
|
|
@@ -176,8 +186,8 @@ class FraudAuditReport {
|
|
|
176
186
|
communityName +
|
|
177
187
|
"_" +
|
|
178
188
|
dateString +
|
|
179
|
-
".
|
|
180
|
-
this.workPackage.fileEnding = "
|
|
189
|
+
".xlsx";
|
|
190
|
+
this.workPackage.fileEnding = "xlsx";
|
|
181
191
|
}
|
|
182
192
|
async getCommunity() {
|
|
183
193
|
this.workPackage.community = await models.Community.findOne({
|
|
@@ -240,8 +250,8 @@ class FraudAuditReport {
|
|
|
240
250
|
dateDeleted: this.workPackage.auditReportData.date,
|
|
241
251
|
id: item.id,
|
|
242
252
|
date: item.created_at,
|
|
243
|
-
userId: item.User.id,
|
|
244
|
-
email: item.User.email,
|
|
253
|
+
userId: item.User ? item.User.id : item.user_id,
|
|
254
|
+
email: item.User ? item.User.email : "",
|
|
245
255
|
ipAddress: item.ip_address,
|
|
246
256
|
userAgent: item.user_agent,
|
|
247
257
|
};
|
|
@@ -250,14 +260,14 @@ class FraudAuditReport {
|
|
|
250
260
|
row.browserId = item.data.browserId;
|
|
251
261
|
}
|
|
252
262
|
if (['posts', 'pointQualities'].indexOf(originalWorkPackage.collectionType) === -1) {
|
|
253
|
-
row.postId = item.Post.id;
|
|
254
|
-
row.postName = item.Post.name;
|
|
263
|
+
row.postId = item.Post ? item.Post.id : item.post_id;
|
|
264
|
+
row.postName = item.Post ? item.Post.name : "";
|
|
255
265
|
}
|
|
256
266
|
if (['endorsements', 'pointQualities', 'ratings'].indexOf(originalWorkPackage.collectionType) !== -1) {
|
|
257
267
|
row.value = item.value;
|
|
258
268
|
}
|
|
259
269
|
if (['pointQualities'].indexOf(originalWorkPackage.collectionType) !== -1) {
|
|
260
|
-
row.pointId = item.Point.id;
|
|
270
|
+
row.pointId = item.Point ? item.Point.id : item.point_id;
|
|
261
271
|
}
|
|
262
272
|
this.worksheet.addRow(row);
|
|
263
273
|
}
|
|
@@ -272,6 +282,7 @@ class FraudAuditReport {
|
|
|
272
282
|
}
|
|
273
283
|
});
|
|
274
284
|
if (auditReport && auditReport.data) {
|
|
285
|
+
this.validateAuditReportCommunity(auditReport);
|
|
275
286
|
this.workPackage.auditReportData = auditReport.data;
|
|
276
287
|
await this.getCommunity();
|
|
277
288
|
this.setupFilename();
|
|
@@ -296,6 +307,17 @@ class FraudAuditReport {
|
|
|
296
307
|
}
|
|
297
308
|
});
|
|
298
309
|
}
|
|
310
|
+
validateAuditReportCommunity(auditReport) {
|
|
311
|
+
const auditCommunityId = auditReport &&
|
|
312
|
+
auditReport.data &&
|
|
313
|
+
auditReport.data.workPackage &&
|
|
314
|
+
auditReport.data.workPackage.communityId;
|
|
315
|
+
if (auditCommunityId === undefined ||
|
|
316
|
+
auditCommunityId === null ||
|
|
317
|
+
String(auditCommunityId) !== String(this.workPackage.communityId)) {
|
|
318
|
+
throw new Error("Fraud audit report does not belong to this community");
|
|
319
|
+
}
|
|
320
|
+
}
|
|
299
321
|
}
|
|
300
322
|
const createFraudAuditReport = async (workPackage, done) => {
|
|
301
323
|
return await new Promise(async (resolve, reject) => {
|
|
@@ -310,5 +332,7 @@ const createFraudAuditReport = async (workPackage, done) => {
|
|
|
310
332
|
});
|
|
311
333
|
};
|
|
312
334
|
module.exports = {
|
|
313
|
-
createFraudAuditReport
|
|
335
|
+
createFraudAuditReport,
|
|
336
|
+
FraudAuditReport,
|
|
337
|
+
sanitizeWorksheetName
|
|
314
338
|
};
|
|
@@ -1 +1,22 @@
|
|
|
1
1
|
export function createFraudAuditReport(workPackage: any, done: any): Promise<any>;
|
|
2
|
+
export class FraudAuditReport {
|
|
3
|
+
constructor(workPackage: any);
|
|
4
|
+
workPackage: any;
|
|
5
|
+
exportedData: Excel.Buffer | null;
|
|
6
|
+
items: any;
|
|
7
|
+
workBook: Excel.Workbook | null;
|
|
8
|
+
worksheet: Excel.Worksheet | null;
|
|
9
|
+
getPointQualityItems(ids: any): Promise<(import("sequelize").Model<YpPointQuality, Partial<YpPointQuality>> & YpPointQuality)[]>;
|
|
10
|
+
getPostDependedItems(model: any, ids: any): Promise<any>;
|
|
11
|
+
getPostItems(ids: any): Promise<(import("sequelize").Model<YpPostData, Partial<YpPostData>> & YpPostData)[]>;
|
|
12
|
+
setupXls(): Promise<void>;
|
|
13
|
+
setupFilename(): void;
|
|
14
|
+
getCommunity(): Promise<void>;
|
|
15
|
+
uploadToS3(): Promise<any>;
|
|
16
|
+
setupItems(): Promise<void>;
|
|
17
|
+
populateXls(): Promise<void>;
|
|
18
|
+
createReport(): Promise<any>;
|
|
19
|
+
validateAuditReportCommunity(auditReport: any): void;
|
|
20
|
+
}
|
|
21
|
+
export function sanitizeWorksheetName(name: any): string;
|
|
22
|
+
import Excel = require("exceljs");
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const _ = require("lodash");
|
|
3
3
|
const moment = require("moment");
|
|
4
4
|
const log = require("../../../../utils/logger.cjs");
|
|
5
|
+
const { normalizeFingerprintValue, } = require("../../../../utils/fingerprint_data.cjs");
|
|
5
6
|
class FraudBase {
|
|
6
7
|
constructor(workPackage) {
|
|
7
8
|
this.workPackage = workPackage;
|
|
@@ -38,6 +39,21 @@ class FraudBase {
|
|
|
38
39
|
return -item.count;
|
|
39
40
|
});
|
|
40
41
|
}
|
|
42
|
+
isDebugFraudDetectionCountAll() {
|
|
43
|
+
return process.env.DEBUG_FRAUD_DETECTION_COUNT_ALL === "true" &&
|
|
44
|
+
this.workPackage.type === "get-items";
|
|
45
|
+
}
|
|
46
|
+
getDebugTopItems(topItems) {
|
|
47
|
+
_.forEach(topItems, topItem => {
|
|
48
|
+
_.forEach(topItem.items, item => {
|
|
49
|
+
item.dataValues = item.dataValues || {};
|
|
50
|
+
if (!item.dataValues.confidenceScore) {
|
|
51
|
+
item.dataValues.confidenceScore = "0%";
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
return topItems;
|
|
56
|
+
}
|
|
41
57
|
getTopDataByIp() {
|
|
42
58
|
return this.getTopItems(this.groupTopDataByIp(), "byIpAddress");
|
|
43
59
|
}
|
|
@@ -141,7 +157,7 @@ class FraudBase {
|
|
|
141
157
|
for (let i = 0; i < items.length; i++) {
|
|
142
158
|
const item = items[i];
|
|
143
159
|
const hasData = item.data ? Object.keys(item.data).length === 0 : false;
|
|
144
|
-
if (hasData && !item.data.browserId && moment(item.created_at) > this.getStartFingerprintMoment()) {
|
|
160
|
+
if (hasData && !normalizeFingerprintValue(item.data.browserId) && moment(item.created_at) > this.getStartFingerprintMoment()) {
|
|
145
161
|
if (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) {
|
|
146
162
|
item.dataValues.confidenceScore = `50%`;
|
|
147
163
|
}
|
|
@@ -180,50 +196,54 @@ class FraudBase {
|
|
|
180
196
|
groupTopDataByIpFingerprintPostId() {
|
|
181
197
|
const filtered = _.filter(this.items, (item) => {
|
|
182
198
|
return item.data &&
|
|
183
|
-
item.data.browserFingerprint
|
|
184
|
-
item.data.browserFingerprint !== "undefined";
|
|
199
|
+
normalizeFingerprintValue(item.data.browserFingerprint);
|
|
185
200
|
});
|
|
186
201
|
return _.groupBy(filtered, (item) => {
|
|
187
|
-
return item.ip_address + ":" + item.post_id + ":" + item.data.browserFingerprint;
|
|
202
|
+
return item.ip_address + ":" + item.post_id + ":" + normalizeFingerprintValue(item.data.browserFingerprint);
|
|
188
203
|
});
|
|
189
204
|
}
|
|
190
205
|
groupTopDataByIpFingerprintPointId() {
|
|
191
206
|
const filtered = _.filter(this.items, (item) => {
|
|
192
207
|
return item.data &&
|
|
193
|
-
item.data.browserFingerprint
|
|
194
|
-
item.data.browserFingerprint !== "undefined";
|
|
208
|
+
normalizeFingerprintValue(item.data.browserFingerprint);
|
|
195
209
|
});
|
|
196
210
|
return _.groupBy(filtered, (item) => {
|
|
197
|
-
return item.ip_address + ":" + item.point_id + ":" + item.data.browserFingerprint;
|
|
211
|
+
return item.ip_address + ":" + item.point_id + ":" + normalizeFingerprintValue(item.data.browserFingerprint);
|
|
198
212
|
});
|
|
199
213
|
}
|
|
200
214
|
groupTopDataByIpFingerprint() {
|
|
201
215
|
const filtered = _.filter(this.items, (item) => {
|
|
202
216
|
return item.data &&
|
|
203
|
-
item.data.browserFingerprint
|
|
204
|
-
item.data.browserFingerprint !== "undefined";
|
|
217
|
+
normalizeFingerprintValue(item.data.browserFingerprint);
|
|
205
218
|
});
|
|
206
219
|
return _.groupBy(filtered, (item) => {
|
|
207
|
-
return item.ip_address + ":" + item.data.browserFingerprint;
|
|
220
|
+
return item.ip_address + ":" + normalizeFingerprintValue(item.data.browserFingerprint);
|
|
208
221
|
});
|
|
209
222
|
}
|
|
210
223
|
groupTopDataByNoFingerprints() {
|
|
211
224
|
const filtered = _.filter(this.items, item => {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
225
|
+
item.data = item.data || {};
|
|
226
|
+
const missingFingerprint = !normalizeFingerprintValue(item.data.browserFingerprint) ||
|
|
227
|
+
!normalizeFingerprintValue(item.data.browserId);
|
|
228
|
+
if (this.isDebugFraudDetectionCountAll()) {
|
|
229
|
+
return missingFingerprint;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
return missingFingerprint &&
|
|
233
|
+
moment(item.created_at).valueOf() > this.getStartFingerprintMoment();
|
|
234
|
+
}
|
|
216
235
|
});
|
|
217
236
|
const scoreHundred = (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) ? "50%" : "100%";
|
|
218
237
|
const scoreNinety = (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) ? "45%" : "90%";
|
|
219
238
|
const scoreSeventy = (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) ? "60%" : "70%";
|
|
220
239
|
_.forEach(filtered, item => {
|
|
221
|
-
|
|
222
|
-
|
|
240
|
+
const browserFingerprint = normalizeFingerprintValue(item.data.browserFingerprint);
|
|
241
|
+
const browserId = normalizeFingerprintValue(item.data.browserId);
|
|
242
|
+
if (!browserFingerprint && !browserId) {
|
|
223
243
|
item.dataValues.confidenceScore = scoreHundred;
|
|
224
244
|
item.dataValues.key = "bothUndefined";
|
|
225
245
|
}
|
|
226
|
-
else if (!
|
|
246
|
+
else if (!browserId) {
|
|
227
247
|
item.dataValues.confidenceScore = scoreNinety;
|
|
228
248
|
item.dataValues.key = "browserIdUndefined";
|
|
229
249
|
}
|
|
@@ -233,7 +253,7 @@ class FraudBase {
|
|
|
233
253
|
}
|
|
234
254
|
});
|
|
235
255
|
return _.groupBy(filtered, item => {
|
|
236
|
-
return item.key;
|
|
256
|
+
return item.dataValues.key;
|
|
237
257
|
});
|
|
238
258
|
}
|
|
239
259
|
}
|
|
@@ -9,6 +9,8 @@ declare class FraudBase {
|
|
|
9
9
|
getAllItems(): Promise<null>;
|
|
10
10
|
getPostIdsFromItems(topItems: any): any[];
|
|
11
11
|
setupTopItems(items: any): any[];
|
|
12
|
+
isDebugFraudDetectionCountAll(): boolean;
|
|
13
|
+
getDebugTopItems(topItems: any): any;
|
|
12
14
|
getTopDataByIp(): null;
|
|
13
15
|
getTopDataByIpUserAgentPostId(): null;
|
|
14
16
|
getTopDataByIpUserAgentPointId(): null;
|
|
@@ -12,6 +12,7 @@ class FraudDeleteBase extends FraudBase {
|
|
|
12
12
|
super(workPackage);
|
|
13
13
|
this.postsToRecount = [];
|
|
14
14
|
this.pointsToRecount = [];
|
|
15
|
+
this.deletedItemIds = [];
|
|
15
16
|
this.job = null;
|
|
16
17
|
}
|
|
17
18
|
sliceIntoChunks(arr, chunkSize) {
|
|
@@ -30,18 +31,22 @@ class FraudDeleteBase extends FraudBase {
|
|
|
30
31
|
async destroyChunkItems(chunks) {
|
|
31
32
|
log.error("Should be implemented in a sub class");
|
|
32
33
|
}
|
|
34
|
+
getUserEmail(item) {
|
|
35
|
+
return item.User && item.User.email ? item.User.email : "";
|
|
36
|
+
}
|
|
33
37
|
getAllItemsExceptOne(items) {
|
|
34
38
|
if (items.length === 1 && this.getAllowedSingleDelete()) {
|
|
35
39
|
return items;
|
|
36
40
|
}
|
|
37
41
|
else {
|
|
38
42
|
const sortedItems = _.sortBy(items, function (item) {
|
|
39
|
-
return item.date;
|
|
43
|
+
return moment(item.created_at || item.date).valueOf();
|
|
40
44
|
});
|
|
41
45
|
const finalItems = [];
|
|
42
46
|
let foundEmail = false;
|
|
43
47
|
for (let i = 0; i < sortedItems.length; i++) {
|
|
44
|
-
|
|
48
|
+
const userEmail = this.getUserEmail(sortedItems[i]);
|
|
49
|
+
if (!foundEmail && userEmail && userEmail.indexOf("_anonymous@citizens.i") === -1) {
|
|
45
50
|
foundEmail = true;
|
|
46
51
|
}
|
|
47
52
|
else {
|
|
@@ -54,27 +59,38 @@ class FraudDeleteBase extends FraudBase {
|
|
|
54
59
|
return finalItems;
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
|
-
async createAuditLog() {
|
|
62
|
+
async createAuditLog(transaction) {
|
|
58
63
|
return await new Promise(async (resolve, reject) => {
|
|
59
64
|
try {
|
|
60
65
|
const user = await models.User.findOne({
|
|
61
66
|
where: {
|
|
62
67
|
id: this.workPackage.userId,
|
|
63
68
|
},
|
|
64
|
-
attributes: ['name']
|
|
69
|
+
attributes: ['name'],
|
|
70
|
+
transaction
|
|
65
71
|
});
|
|
72
|
+
const userName = user && user.name ? user.name : "Unknown";
|
|
73
|
+
const deleteData = {
|
|
74
|
+
...this.job.internal_data,
|
|
75
|
+
requestedIdsToDelete: this.job.internal_data.idsToDelete,
|
|
76
|
+
idsToDelete: this.deletedItemIds,
|
|
77
|
+
};
|
|
66
78
|
const fraudAuditLog = await models.GeneralDataStore.create({ data: {
|
|
67
79
|
date: new Date(),
|
|
68
|
-
userName
|
|
80
|
+
userName,
|
|
69
81
|
workPackage: this.workPackage,
|
|
70
|
-
deleteData
|
|
71
|
-
} });
|
|
82
|
+
deleteData
|
|
83
|
+
} }, { transaction });
|
|
72
84
|
const community = await models.Community.findOne({
|
|
73
85
|
where: {
|
|
74
86
|
id: this.workPackage.communityId
|
|
75
87
|
},
|
|
76
|
-
attributes: ['data', 'id']
|
|
88
|
+
attributes: ['data', 'id'],
|
|
89
|
+
transaction
|
|
77
90
|
});
|
|
91
|
+
if (!community) {
|
|
92
|
+
throw new Error("Community not found for fraud audit log");
|
|
93
|
+
}
|
|
78
94
|
if (!community.data) {
|
|
79
95
|
community.data = {};
|
|
80
96
|
}
|
|
@@ -84,10 +100,10 @@ class FraudDeleteBase extends FraudBase {
|
|
|
84
100
|
community.data.fraudDeletionsAuditLogs.push({
|
|
85
101
|
logId: fraudAuditLog.id,
|
|
86
102
|
date: fraudAuditLog.data.date,
|
|
87
|
-
userName
|
|
103
|
+
userName
|
|
88
104
|
});
|
|
89
105
|
community.changed('data', true);
|
|
90
|
-
await community.save();
|
|
106
|
+
await community.save({ transaction });
|
|
91
107
|
resolve();
|
|
92
108
|
}
|
|
93
109
|
catch (error) {
|
|
@@ -109,13 +125,13 @@ class FraudDeleteBase extends FraudBase {
|
|
|
109
125
|
getTopItems(items, type) {
|
|
110
126
|
return this.setupTopItems(items);
|
|
111
127
|
}
|
|
112
|
-
async destroyAllItems(chunks) {
|
|
128
|
+
async destroyAllItems(chunks, transaction) {
|
|
113
129
|
return await new Promise(async (resolve, reject) => {
|
|
114
130
|
try {
|
|
115
131
|
const progressAdvanceForChunk = 75 / 10;
|
|
116
132
|
let progress = 25;
|
|
117
133
|
for (let c = 0; c < chunks.length; c++) {
|
|
118
|
-
await this.destroyChunkItems(chunks[c]);
|
|
134
|
+
await this.destroyChunkItems(chunks[c], transaction);
|
|
119
135
|
progress = Math.round(Math.min(80, progress += progressAdvanceForChunk));
|
|
120
136
|
await models.AcBackgroundJob.updateProgressAsync(this.workPackage.jobId, progress);
|
|
121
137
|
}
|
|
@@ -126,7 +142,7 @@ class FraudDeleteBase extends FraudBase {
|
|
|
126
142
|
}
|
|
127
143
|
});
|
|
128
144
|
}
|
|
129
|
-
async deleteData() {
|
|
145
|
+
async deleteData(transaction) {
|
|
130
146
|
return await new Promise(async (resolve, reject) => {
|
|
131
147
|
try {
|
|
132
148
|
const keys = Object.keys(this.dataToProcess);
|
|
@@ -134,7 +150,8 @@ class FraudDeleteBase extends FraudBase {
|
|
|
134
150
|
for (let c = 0; c < keys.length; c++) {
|
|
135
151
|
itemsToDelete = itemsToDelete.concat(this.getAllItemsExceptOne(this.dataToProcess[keys[c]].items));
|
|
136
152
|
}
|
|
137
|
-
|
|
153
|
+
this.deletedItemIds = itemsToDelete.map(item => item.id);
|
|
154
|
+
await this.destroyAllItems(this.sliceIntoChunks(itemsToDelete, 100), transaction);
|
|
138
155
|
resolve();
|
|
139
156
|
}
|
|
140
157
|
catch (error) {
|
|
@@ -142,7 +159,7 @@ class FraudDeleteBase extends FraudBase {
|
|
|
142
159
|
}
|
|
143
160
|
});
|
|
144
161
|
}
|
|
145
|
-
async recountPosts() {
|
|
162
|
+
async recountPosts(transaction) {
|
|
146
163
|
return await new Promise(async (resolve, reject) => {
|
|
147
164
|
recountPosts(this.postsToRecount, error => {
|
|
148
165
|
if (error) {
|
|
@@ -151,10 +168,10 @@ class FraudDeleteBase extends FraudBase {
|
|
|
151
168
|
else {
|
|
152
169
|
resolve();
|
|
153
170
|
}
|
|
154
|
-
});
|
|
171
|
+
}, transaction);
|
|
155
172
|
});
|
|
156
173
|
}
|
|
157
|
-
async recountPoints() {
|
|
174
|
+
async recountPoints(transaction) {
|
|
158
175
|
return await new Promise(async (resolve, reject) => {
|
|
159
176
|
recountPoints(this.pointsToRecount, error => {
|
|
160
177
|
if (error) {
|
|
@@ -163,10 +180,10 @@ class FraudDeleteBase extends FraudBase {
|
|
|
163
180
|
else {
|
|
164
181
|
resolve();
|
|
165
182
|
}
|
|
166
|
-
});
|
|
183
|
+
}, transaction);
|
|
167
184
|
});
|
|
168
185
|
}
|
|
169
|
-
async recountCommunity() {
|
|
186
|
+
async recountCommunity(transaction) {
|
|
170
187
|
return await new Promise(async (resolve, reject) => {
|
|
171
188
|
recountCommunity(this.workPackage.communityId, error => {
|
|
172
189
|
if (error) {
|
|
@@ -175,7 +192,7 @@ class FraudDeleteBase extends FraudBase {
|
|
|
175
192
|
else {
|
|
176
193
|
resolve();
|
|
177
194
|
}
|
|
178
|
-
});
|
|
195
|
+
}, transaction);
|
|
179
196
|
});
|
|
180
197
|
}
|
|
181
198
|
async deleteItems() {
|
|
@@ -189,15 +206,17 @@ class FraudDeleteBase extends FraudBase {
|
|
|
189
206
|
});
|
|
190
207
|
this.items = await this.getItemsById();
|
|
191
208
|
this.setupDataToProcess();
|
|
192
|
-
await
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
209
|
+
await models.sequelize.transaction(async (transaction) => {
|
|
210
|
+
await this.deleteData(transaction);
|
|
211
|
+
await this.createAuditLog(transaction);
|
|
212
|
+
if (this.postsToRecount.length > 0) {
|
|
213
|
+
await this.recountPosts(transaction);
|
|
214
|
+
}
|
|
215
|
+
if (this.pointsToRecount.length > 0) {
|
|
216
|
+
await this.recountPoints(transaction);
|
|
217
|
+
}
|
|
218
|
+
await this.recountCommunity(transaction);
|
|
219
|
+
});
|
|
201
220
|
await models.AcBackgroundJob.updateProgressAsync(this.workPackage.jobId, 100);
|
|
202
221
|
resolve();
|
|
203
222
|
}
|
|
@@ -2,20 +2,22 @@ export = FraudDeleteBase;
|
|
|
2
2
|
declare class FraudDeleteBase extends FraudBase {
|
|
3
3
|
postsToRecount: any[];
|
|
4
4
|
pointsToRecount: any[];
|
|
5
|
+
deletedItemIds: any[];
|
|
5
6
|
job: any;
|
|
6
7
|
sliceIntoChunks(arr: any, chunkSize: any): any[];
|
|
7
8
|
getItemsById(): Promise<null>;
|
|
8
9
|
destroyChunkItems(chunks: any): Promise<void>;
|
|
10
|
+
getUserEmail(item: any): any;
|
|
9
11
|
getAllItemsExceptOne(items: any): any;
|
|
10
|
-
createAuditLog(): Promise<any>;
|
|
12
|
+
createAuditLog(transaction: any): Promise<any>;
|
|
11
13
|
getAllowedSingleDelete(): boolean;
|
|
12
14
|
getMomentInYourPriorities(): number;
|
|
13
15
|
getTopItems(items: any, type: any): any[];
|
|
14
|
-
destroyAllItems(chunks: any): Promise<any>;
|
|
15
|
-
deleteData(): Promise<any>;
|
|
16
|
-
recountPosts(): Promise<any>;
|
|
17
|
-
recountPoints(): Promise<any>;
|
|
18
|
-
recountCommunity(): Promise<any>;
|
|
16
|
+
destroyAllItems(chunks: any, transaction: any): Promise<any>;
|
|
17
|
+
deleteData(transaction: any): Promise<any>;
|
|
18
|
+
recountPosts(transaction: any): Promise<any>;
|
|
19
|
+
recountPoints(transaction: any): Promise<any>;
|
|
20
|
+
recountCommunity(transaction: any): Promise<any>;
|
|
19
21
|
deleteItems(): Promise<any>;
|
|
20
22
|
}
|
|
21
23
|
import FraudBase = require("./FraudBase.cjs");
|
|
@@ -3,7 +3,7 @@ const _ = require("lodash");
|
|
|
3
3
|
const FraudDeleteBase = require('./FraudDeleteBase.cjs');
|
|
4
4
|
const models = require("../../../../models/index.cjs");
|
|
5
5
|
class FraudDeleteEndorsements extends FraudDeleteBase {
|
|
6
|
-
async destroyChunkItemsByModel(model, items) {
|
|
6
|
+
async destroyChunkItemsByModel(model, items, transaction) {
|
|
7
7
|
return await new Promise(async (resolve, reject) => {
|
|
8
8
|
const idsToDestroy = items.map(i => i.id);
|
|
9
9
|
try {
|
|
@@ -37,7 +37,8 @@ class FraudDeleteEndorsements extends FraudDeleteBase {
|
|
|
37
37
|
]
|
|
38
38
|
}
|
|
39
39
|
],
|
|
40
|
-
attributes: ['id']
|
|
40
|
+
attributes: ['id'],
|
|
41
|
+
transaction
|
|
41
42
|
});
|
|
42
43
|
for (let i = 0; i < items.length; i++) {
|
|
43
44
|
if (this.postsToRecount.indexOf(items[i].post_id) === -1) {
|
|
@@ -51,8 +52,8 @@ class FraudDeleteEndorsements extends FraudDeleteBase {
|
|
|
51
52
|
}
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
|
-
async destroyChunkItems(items) {
|
|
55
|
-
return this.destroyChunkItemsByModel(models.Endorsement, items);
|
|
55
|
+
async destroyChunkItems(items, transaction) {
|
|
56
|
+
return this.destroyChunkItemsByModel(models.Endorsement, items, transaction);
|
|
56
57
|
}
|
|
57
58
|
async getModelItemsById(model, getGroup) {
|
|
58
59
|
return await new Promise(async (resolve, reject) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export = FraudDeleteEndorsements;
|
|
2
2
|
declare class FraudDeleteEndorsements extends FraudDeleteBase {
|
|
3
|
-
destroyChunkItemsByModel(model: any, items: any): Promise<any>;
|
|
4
|
-
destroyChunkItems(items: any): Promise<any>;
|
|
3
|
+
destroyChunkItemsByModel(model: any, items: any, transaction: any): Promise<any>;
|
|
4
|
+
destroyChunkItems(items: any, transaction: any): Promise<any>;
|
|
5
5
|
getModelItemsById(model: any, getGroup: any): Promise<any>;
|
|
6
6
|
getItemsById(): Promise<any>;
|
|
7
7
|
}
|
|
@@ -4,7 +4,7 @@ const FraudDeleteBase = require('./FraudDeleteBase.cjs');
|
|
|
4
4
|
const models = require("../../../../models/index.cjs");
|
|
5
5
|
//TODO: Change to native JS instead of lodash
|
|
6
6
|
class FraudDeletePointQualities extends FraudDeleteBase {
|
|
7
|
-
async destroyChunkItems(items) {
|
|
7
|
+
async destroyChunkItems(items, transaction) {
|
|
8
8
|
return await new Promise(async (resolve, reject) => {
|
|
9
9
|
const idsToDestroy = items.map(i => i.id);
|
|
10
10
|
try {
|
|
@@ -44,7 +44,8 @@ class FraudDeletePointQualities extends FraudDeleteBase {
|
|
|
44
44
|
]
|
|
45
45
|
},
|
|
46
46
|
],
|
|
47
|
-
attributes: ['id']
|
|
47
|
+
attributes: ['id'],
|
|
48
|
+
transaction
|
|
48
49
|
});
|
|
49
50
|
for (let i = 0; i < items.length; i++) {
|
|
50
51
|
if (this.pointsToRecount.indexOf(items[i].Point.id) === -1) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export = FraudDeletePointQualities;
|
|
2
2
|
declare class FraudDeletePointQualities extends FraudDeleteBase {
|
|
3
|
-
destroyChunkItems(items: any): Promise<any>;
|
|
3
|
+
destroyChunkItems(items: any, transaction: any): Promise<any>;
|
|
4
4
|
getItemsById(): Promise<any>;
|
|
5
5
|
}
|
|
6
6
|
import FraudDeleteBase = require("./FraudDeleteBase.cjs");
|
|
@@ -3,7 +3,7 @@ const _ = require("lodash");
|
|
|
3
3
|
const FraudDeleteBase = require('./FraudDeleteBase.cjs');
|
|
4
4
|
const models = require("../../../../models/index.cjs");
|
|
5
5
|
class FraudDeletePointQualities extends FraudDeleteBase {
|
|
6
|
-
async destroyChunkItems(items) {
|
|
6
|
+
async destroyChunkItems(items, transaction) {
|
|
7
7
|
return await new Promise(async (resolve, reject) => {
|
|
8
8
|
const idsToDestroy = items.map(i => i.id);
|
|
9
9
|
try {
|
|
@@ -37,7 +37,8 @@ class FraudDeletePointQualities extends FraudDeleteBase {
|
|
|
37
37
|
]
|
|
38
38
|
}
|
|
39
39
|
],
|
|
40
|
-
attributes: ['id']
|
|
40
|
+
attributes: ['id'],
|
|
41
|
+
transaction
|
|
41
42
|
});
|
|
42
43
|
for (let i = 0; i < items.length; i++) {
|
|
43
44
|
if (this.postsToRecount.indexOf(items[i].Post.id) === -1) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export = FraudDeletePointQualities;
|
|
2
2
|
declare class FraudDeletePointQualities extends FraudDeleteBase {
|
|
3
|
-
destroyChunkItems(items: any): Promise<any>;
|
|
3
|
+
destroyChunkItems(items: any, transaction: any): Promise<any>;
|
|
4
4
|
getItemsById(): Promise<any>;
|
|
5
5
|
}
|
|
6
6
|
import FraudDeleteBase = require("./FraudDeleteBase.cjs");
|
|
@@ -3,7 +3,7 @@ const _ = require("lodash");
|
|
|
3
3
|
const FraudDeleteEndorsements = require('./FraudDeleteEndorsements.cjs');
|
|
4
4
|
const models = require("../../../../models/index.cjs");
|
|
5
5
|
class FraudDeletePosts extends FraudDeleteEndorsements {
|
|
6
|
-
async destroyChunkItems(items) {
|
|
6
|
+
async destroyChunkItems(items, transaction) {
|
|
7
7
|
return await new Promise(async (resolve, reject) => {
|
|
8
8
|
const idsToDestroy = items.map(i => i.id);
|
|
9
9
|
try {
|
|
@@ -31,7 +31,8 @@ class FraudDeletePosts extends FraudDeleteEndorsements {
|
|
|
31
31
|
]
|
|
32
32
|
}
|
|
33
33
|
],
|
|
34
|
-
attributes: ['id']
|
|
34
|
+
attributes: ['id'],
|
|
35
|
+
transaction
|
|
35
36
|
});
|
|
36
37
|
resolve();
|
|
37
38
|
}
|