@yrpri/api 9.0.230 → 9.0.232

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/controllers/allOurIdeas.js +1 -1
  2. package/controllers/communities.cjs +282 -91
  3. package/controllers/domains.cjs +54 -8
  4. package/controllers/groups.cjs +51 -6
  5. package/controllers/points.cjs +4 -9
  6. package/controllers/posts.cjs +7 -9
  7. package/controllers/ratings.cjs +3 -6
  8. package/models/point.cjs +31 -3
  9. package/models/post.cjs +2 -3
  10. package/package.json +3 -3
  11. package/services/engine/allOurIdeas/aiHelper.d.ts +7 -4
  12. package/services/engine/allOurIdeas/aiHelper.js +34 -19
  13. package/services/engine/allOurIdeas/explainAnswersAssistant.d.ts +1 -1
  14. package/services/engine/allOurIdeas/explainAnswersAssistant.js +3 -9
  15. package/services/engine/moderation/fraud/CreateFraudAuditReport.cjs +35 -11
  16. package/services/engine/moderation/fraud/CreateFraudAuditReport.d.cts +21 -0
  17. package/services/engine/moderation/fraud/FraudBase.cjs +38 -18
  18. package/services/engine/moderation/fraud/FraudBase.d.cts +2 -0
  19. package/services/engine/moderation/fraud/FraudDeleteBase.cjs +48 -29
  20. package/services/engine/moderation/fraud/FraudDeleteBase.d.cts +8 -6
  21. package/services/engine/moderation/fraud/FraudDeleteEndorsements.cjs +5 -4
  22. package/services/engine/moderation/fraud/FraudDeleteEndorsements.d.cts +2 -2
  23. package/services/engine/moderation/fraud/FraudDeletePointQualities.cjs +3 -2
  24. package/services/engine/moderation/fraud/FraudDeletePointQualities.d.cts +1 -1
  25. package/services/engine/moderation/fraud/FraudDeletePoints.cjs +3 -2
  26. package/services/engine/moderation/fraud/FraudDeletePoints.d.cts +1 -1
  27. package/services/engine/moderation/fraud/FraudDeletePosts.cjs +3 -2
  28. package/services/engine/moderation/fraud/FraudDeleteRatings.cjs +61 -4
  29. package/services/engine/moderation/fraud/FraudGetBase.cjs +44 -20
  30. package/services/engine/moderation/fraud/FraudGetBase.d.cts +5 -0
  31. package/services/engine/moderation/fraud/FraudGetEndorsements.cjs +4 -13
  32. package/services/engine/moderation/fraud/FraudGetEndorsements.d.cts +1 -1
  33. package/services/engine/moderation/fraud/FraudGetPointQualities.cjs +3 -0
  34. package/services/engine/moderation/fraud/FraudGetPointQualities.d.cts +1 -1
  35. package/services/engine/moderation/fraud/FraudGetPoints.cjs +3 -0
  36. package/services/engine/moderation/fraud/FraudGetPoints.d.cts +1 -1
  37. package/services/engine/moderation/fraud/FraudGetPosts.cjs +17 -16
  38. package/services/engine/moderation/fraud/FraudGetPosts.d.cts +3 -3
  39. package/services/engine/moderation/fraud/FraudGetRatings.cjs +62 -30
  40. package/services/engine/moderation/fraud/FraudGetRatings.d.cts +4 -1
  41. package/services/engine/moderation/fraud/FraudRequestValidation.cjs +143 -0
  42. package/services/engine/moderation/fraud/FraudRequestValidation.d.cts +21 -0
  43. package/services/engine/moderation/fraud/FraudScannerNotifier.cjs +59 -35
  44. package/services/engine/moderation/fraud/FraudScannerNotifier.d.cts +20 -1
  45. package/services/llms/baseChatBot.d.ts +2 -0
  46. package/services/llms/baseChatBot.js +25 -9
  47. package/services/llms/imageGeneration/chatGptImageGenerator.d.ts +2 -2
  48. package/services/llms/imageGeneration/chatGptImageGenerator.js +13 -10
  49. package/services/llms/imageGeneration/collectionImageGenerator.js +31 -13
  50. package/services/llms/imageGeneration/dalleImageGenerator.d.ts +2 -2
  51. package/services/llms/imageGeneration/dalleImageGenerator.js +28 -16
  52. package/services/llms/imageGeneration/fluxImageGenerator.d.ts +2 -2
  53. package/services/llms/imageGeneration/fluxImageGenerator.js +9 -3
  54. package/services/llms/imageGeneration/iImageGenerator.d.ts +8 -1
  55. package/services/llms/imageGeneration/imageModelConfig.cjs +319 -0
  56. package/services/llms/imageGeneration/imageModelConfig.d.cts +79 -0
  57. package/services/llms/imageGeneration/imagenImageGenerator.d.ts +2 -3
  58. package/services/llms/imageGeneration/imagenImageGenerator.js +10 -10
  59. package/tests/fraudManagement.test.cjs +470 -0
  60. package/tests/fraudManagement.test.d.cts +1 -0
  61. package/tests/imageModelConfig.test.cjs +144 -0
  62. package/tests/imageModelConfig.test.d.cts +1 -0
  63. package/utils/ai_image_generation_guard.cjs +268 -0
  64. package/utils/ai_image_generation_guard.d.cts +34 -0
  65. package/utils/fingerprint_data.cjs +32 -0
  66. package/utils/fingerprint_data.d.cts +6 -0
  67. package/utils/recount_utils.cjs +53 -37
  68. package/utils/recount_utils.d.cts +7 -7
@@ -39,19 +39,7 @@ class FraudGetEndorsements extends FraudGetBase {
39
39
  const itemsToAnalyse = _.sortBy(items, function (item) {
40
40
  return [item.post_id, item.user_agent];
41
41
  });
42
- let groupConfiguration;
43
- if (getGroup && items.length > 0) {
44
- const group = await models.Group.findOne({
45
- where: {
46
- id: itemsToAnalyse[0].Post.Group.id
47
- },
48
- attributes: ['configuration']
49
- });
50
- if (group) {
51
- groupConfiguration = group.configuration;
52
- }
53
- }
54
- resolve({ itemsToAnalyse, groupConfiguration });
42
+ resolve({ itemsToAnalyse });
55
43
  }
56
44
  catch (error) {
57
45
  reject(error);
@@ -66,6 +54,9 @@ class FraudGetEndorsements extends FraudGetBase {
66
54
  let topItems = this.setupTopItems(items);
67
55
  const postIds = this.getPostIdsFromItems(topItems);
68
56
  const postCount = _.uniq(postIds).length;
57
+ if (this.isDebugFraudDetectionCountAll()) {
58
+ return this.getDebugTopItems(topItems);
59
+ }
69
60
  if (type === "byIpUserAgentPostId") {
70
61
  let out = [];
71
62
  _.each(topItems, function (item) {
@@ -2,6 +2,6 @@ export = FraudGetEndorsements;
2
2
  declare class FraudGetEndorsements extends FraudGetBase {
3
3
  getAllModelItems(model: any, getGroup: any): Promise<any>;
4
4
  getAllItems(): Promise<any>;
5
- getTopItems(items: any, type: any): any[];
5
+ getTopItems(items: any, type: any): any;
6
6
  }
7
7
  import FraudGetBase = require("./FraudGetBase.cjs");
@@ -65,6 +65,9 @@ class FraudGetPointQualities extends FraudGetBase {
65
65
  let topItems = this.setupTopItems(items);
66
66
  const pointIds = this.getPointIdsFromItems(topItems);
67
67
  const pointCount = _.uniq(pointIds).length;
68
+ if (this.isDebugFraudDetectionCountAll()) {
69
+ return this.getDebugTopItems(topItems);
70
+ }
68
71
  if (type === "byIpUserAgentPointId") {
69
72
  let out = [];
70
73
  _.each(topItems, function (item) {
@@ -2,6 +2,6 @@ export = FraudGetPointQualities;
2
2
  declare class FraudGetPointQualities extends FraudGetBase {
3
3
  getAllItems(): Promise<any>;
4
4
  getPointIdsFromItems(topItems: any): any[];
5
- getTopItems(items: any, type: any): any[];
5
+ getTopItems(items: any, type: any): any;
6
6
  }
7
7
  import FraudGetBase = require("./FraudGetBase.cjs");
@@ -51,6 +51,9 @@ class FraudGetPointQualities extends FraudGetBase {
51
51
  const postIds = this.getPostIdsFromItems(topItems);
52
52
  const postCount = _.uniq(postIds).length;
53
53
  const pointMultiplier = 10;
54
+ if (this.isDebugFraudDetectionCountAll()) {
55
+ return this.getDebugTopItems(topItems);
56
+ }
54
57
  if (type === "byIpUserAgentPostId") {
55
58
  let out = [];
56
59
  _.each(topItems, function (item) {
@@ -1,6 +1,6 @@
1
1
  export = FraudGetPointQualities;
2
2
  declare class FraudGetPointQualities extends FraudGetBase {
3
3
  getAllItems(): Promise<any>;
4
- getTopItems(items: any, type: any): any[];
4
+ getTopItems(items: any, type: any): any;
5
5
  }
6
6
  import FraudGetBase = require("./FraudGetBase.cjs");
@@ -3,7 +3,7 @@ const _ = require("lodash");
3
3
  const FraudGetBase = require('./FraudGetBase.cjs');
4
4
  const models = require("../../../../models/index.cjs");
5
5
  const log = require("../../../../utils/logger.cjs");
6
- class FraudGetPoints extends FraudGetBase {
6
+ class FraudGetPosts extends FraudGetBase {
7
7
  async getAllItems() {
8
8
  return await new Promise(async (resolve, reject) => {
9
9
  try {
@@ -41,23 +41,24 @@ class FraudGetPoints extends FraudGetBase {
41
41
  }
42
42
  getTopItems(items, type) {
43
43
  let topItems = this.setupTopItems(items);
44
- const postIds = this.getPostIdsFromItems(topItems);
45
- const postCount = _.uniq(postIds).length;
46
44
  const pointMultiplier = 10;
45
+ if (this.isDebugFraudDetectionCountAll()) {
46
+ return this.getDebugTopItems(topItems);
47
+ }
47
48
  if (type === "byIpFingerprint") {
48
49
  let out = [];
49
50
  _.each(topItems, function (item) {
50
- if ((item.count / postCount) > pointMultiplier) {
51
- if ((item.count / postCount) > 5 * pointMultiplier) {
51
+ if (item.count > pointMultiplier) {
52
+ if (item.count > 5 * pointMultiplier) {
52
53
  this.setWeightedConfidenceScore(item.items, 70);
53
54
  }
54
- else if ((item.count / postCount) > 4 * pointMultiplier) {
55
+ else if (item.count > 4 * pointMultiplier) {
55
56
  this.setWeightedConfidenceScore(item.items, 60);
56
57
  }
57
- else if ((item.count / postCount) > 3 * pointMultiplier) {
58
+ else if (item.count > 3 * pointMultiplier) {
58
59
  this.setWeightedConfidenceScore(item.items, 40);
59
60
  }
60
- else if ((item.count / postCount) > 2 * pointMultiplier) {
61
+ else if (item.count > 2 * pointMultiplier) {
61
62
  this.setWeightedConfidenceScore(item.items, 20);
62
63
  }
63
64
  else {
@@ -74,23 +75,23 @@ class FraudGetPoints extends FraudGetBase {
74
75
  else if (type === "byIpAddress") {
75
76
  let out = [];
76
77
  _.each(topItems, function (item) {
77
- if ((item.count / postCount) > pointMultiplier) {
78
- if ((item.count / postCount) > 100 * pointMultiplier) {
78
+ if (item.count > pointMultiplier) {
79
+ if (item.count > 100 * pointMultiplier) {
79
80
  this.setWeightedConfidenceScore(item.items, 70);
80
81
  }
81
- else if ((item.count / postCount) > 50 * pointMultiplier) {
82
+ else if (item.count > 50 * pointMultiplier) {
82
83
  this.setWeightedConfidenceScore(item.items, 65);
83
84
  }
84
- else if ((item.count / postCount) > 25 * pointMultiplier) {
85
+ else if (item.count > 25 * pointMultiplier) {
85
86
  this.setWeightedConfidenceScore(item.items, 40);
86
87
  }
87
- else if ((item.count / postCount) > 10 * pointMultiplier) {
88
+ else if (item.count > 10 * pointMultiplier) {
88
89
  this.setWeightedConfidenceScore(item.items, 35);
89
90
  }
90
- else if ((item.count / postCount) > 5 * pointMultiplier) {
91
+ else if (item.count > 5 * pointMultiplier) {
91
92
  this.setWeightedConfidenceScore(item.items, 20);
92
93
  }
93
- else if ((item.count / postCount) > 2 * pointMultiplier) {
94
+ else if (item.count > 2 * pointMultiplier) {
94
95
  this.setWeightedConfidenceScore(item.items, 15);
95
96
  }
96
97
  else {
@@ -107,4 +108,4 @@ class FraudGetPoints extends FraudGetBase {
107
108
  }
108
109
  }
109
110
  }
110
- module.exports = FraudGetPoints;
111
+ module.exports = FraudGetPosts;
@@ -1,6 +1,6 @@
1
- export = FraudGetPoints;
2
- declare class FraudGetPoints extends FraudGetBase {
1
+ export = FraudGetPosts;
2
+ declare class FraudGetPosts extends FraudGetBase {
3
3
  getAllItems(): Promise<any>;
4
- getTopItems(items: any, type: any): any[];
4
+ getTopItems(items: any, type: any): any;
5
5
  }
6
6
  import FraudGetBase = require("./FraudGetBase.cjs");
@@ -6,38 +6,67 @@ const log = require("../../../../utils/logger.cjs");
6
6
  class FraudGetRatings extends FraudGetEndorsements {
7
7
  constructor(workPackage) {
8
8
  super(workPackage);
9
- this.groupConfiguration = null;
9
+ this.ratingDimensionCountsByGroupId = {};
10
10
  }
11
11
  async getAllItems() {
12
12
  const itemsContainer = await this.getAllModelItems(models.Rating, true);
13
- this.groupConfiguration = itemsContainer.groupConfiguration;
13
+ this.ratingDimensionCountsByGroupId = await this.getRatingDimensionCountsByGroupId(itemsContainer.itemsToAnalyse);
14
14
  return itemsContainer.itemsToAnalyse;
15
15
  }
16
+ async getRatingDimensionCountsByGroupId(items) {
17
+ const groupIds = _.uniq(items.map(item => {
18
+ return item.Post && item.Post.Group && item.Post.Group.id;
19
+ }).filter(groupId => groupId));
20
+ if (groupIds.length === 0) {
21
+ return {};
22
+ }
23
+ const groups = await models.Group.findAll({
24
+ where: {
25
+ id: groupIds
26
+ },
27
+ attributes: ['id', 'configuration']
28
+ });
29
+ return groups.reduce((countsByGroupId, group) => {
30
+ const customRatings = group.configuration && group.configuration.customRatings;
31
+ countsByGroupId[group.id] =
32
+ customRatings && typeof customRatings === "object"
33
+ ? Math.max(Object.keys(customRatings).length, 1)
34
+ : 1;
35
+ return countsByGroupId;
36
+ }, {});
37
+ }
38
+ getRatingDimensionsForItem(item) {
39
+ const groupId = item.Post && item.Post.Group && item.Post.Group.id;
40
+ return this.ratingDimensionCountsByGroupId[groupId] || 1;
41
+ }
42
+ getNormalizedRatingCount(items) {
43
+ return _.sumBy(items, item => 1 / this.getRatingDimensionsForItem(item));
44
+ }
16
45
  getTopItems(items, type) {
17
46
  let topItems = this.setupTopItems(items);
18
47
  const postIds = this.getPostIdsFromItems(topItems);
19
- const postCount = _.uniq(postIds).length;
20
- let ratingsCount = 10000000;
21
- if (this.groupConfiguration) {
22
- ratingsCount = Object.keys(this.groupConfiguration.customRatings).length;
48
+ const postCount = Math.max(_.uniq(postIds).length, 1);
49
+ if (this.isDebugFraudDetectionCountAll()) {
50
+ return this.getDebugTopItems(topItems);
23
51
  }
24
52
  if (type === "byIpUserAgentPostId") {
25
53
  let out = [];
26
54
  _.each(topItems, function (item) {
27
- if ((item.count / ratingsCount) > 1) {
28
- if ((item.count / ratingsCount) > 10) {
55
+ const ratingRatio = this.getNormalizedRatingCount(item.items);
56
+ if (ratingRatio > 1) {
57
+ if (ratingRatio > 10) {
29
58
  this.setWeightedConfidenceScore(item.items, 95);
30
59
  }
31
- else if ((item.count / ratingsCount) > 5) {
60
+ else if (ratingRatio > 5) {
32
61
  this.setWeightedConfidenceScore(item.items, 90);
33
62
  }
34
- else if ((item.count / ratingsCount) > 4) {
63
+ else if (ratingRatio > 4) {
35
64
  this.setWeightedConfidenceScore(item.items, 85);
36
65
  }
37
- else if ((item.count / ratingsCount) > 3) {
66
+ else if (ratingRatio > 3) {
38
67
  this.setWeightedConfidenceScore(item.items, 80);
39
68
  }
40
- else if ((item.count / ratingsCount) > 2) {
69
+ else if (ratingRatio > 2) {
41
70
  this.setWeightedConfidenceScore(item.items, 75);
42
71
  }
43
72
  else {
@@ -51,17 +80,18 @@ class FraudGetRatings extends FraudGetEndorsements {
51
80
  else if (type === "byIpFingerprint") {
52
81
  let out = [];
53
82
  _.each(topItems, function (item) {
54
- if ((item.count / postCount / ratingsCount) > 1) {
55
- if ((item.count / postCount / ratingsCount) > 5) {
83
+ const ratingRatio = this.getNormalizedRatingCount(item.items) / postCount;
84
+ if (ratingRatio > 1) {
85
+ if (ratingRatio > 5) {
56
86
  this.setWeightedConfidenceScore(item.items, 99);
57
87
  }
58
- else if ((item.count / postCount / ratingsCount) > 4) {
88
+ else if (ratingRatio > 4) {
59
89
  this.setWeightedConfidenceScore(item.items, 95);
60
90
  }
61
- else if ((item.count / postCount / ratingsCount) > 3) {
91
+ else if (ratingRatio > 3) {
62
92
  this.setWeightedConfidenceScore(item.items, 90);
63
93
  }
64
- else if ((item.count / postCount / ratingsCount) > 2) {
94
+ else if (ratingRatio > 2) {
65
95
  this.setWeightedConfidenceScore(item.items, 85);
66
96
  }
67
97
  else {
@@ -78,20 +108,21 @@ class FraudGetRatings extends FraudGetEndorsements {
78
108
  else if (type === "byIpFingerprintPostId") {
79
109
  let out = [];
80
110
  _.each(topItems, function (item) {
81
- if ((item.count / ratingsCount) > 1) {
82
- if ((item.count / ratingsCount) > 10) {
111
+ const ratingRatio = this.getNormalizedRatingCount(item.items);
112
+ if (ratingRatio > 1) {
113
+ if (ratingRatio > 10) {
83
114
  this.setWeightedConfidenceScore(item.items, 100);
84
115
  }
85
- else if ((item.count / ratingsCount) > 5) {
116
+ else if (ratingRatio > 5) {
86
117
  this.setWeightedConfidenceScore(item.items, 98);
87
118
  }
88
- else if ((item.count / ratingsCount) > 4) {
119
+ else if (ratingRatio > 4) {
89
120
  this.setWeightedConfidenceScore(item.items, 95);
90
121
  }
91
- else if ((item.count / ratingsCount) > 3) {
122
+ else if (ratingRatio > 3) {
92
123
  this.setWeightedConfidenceScore(item.items, 90);
93
124
  }
94
- else if ((item.count / ratingsCount) > 2) {
125
+ else if (ratingRatio > 2) {
95
126
  this.setWeightedConfidenceScore(item.items, 85);
96
127
  }
97
128
  else {
@@ -105,23 +136,24 @@ class FraudGetRatings extends FraudGetEndorsements {
105
136
  else if (type === "byIpAddress") {
106
137
  let out = [];
107
138
  _.each(topItems, function (item) {
108
- if ((item.count / postCount / ratingsCount) > 1) {
109
- if ((item.count / postCount / ratingsCount) > 100) {
139
+ const ratingRatio = this.getNormalizedRatingCount(item.items) / postCount;
140
+ if (ratingRatio > 1) {
141
+ if (ratingRatio > 100) {
110
142
  this.setWeightedConfidenceScore(item.items, 90);
111
143
  }
112
- else if ((item.count / postCount / ratingsCount) > 50) {
144
+ else if (ratingRatio > 50) {
113
145
  this.setWeightedConfidenceScore(item.items, 85);
114
146
  }
115
- else if ((item.count / postCount / ratingsCount) > 25) {
147
+ else if (ratingRatio > 25) {
116
148
  this.setWeightedConfidenceScore(item.items, 80);
117
149
  }
118
- else if ((item.count / postCount / ratingsCount) > 10) {
150
+ else if (ratingRatio > 10) {
119
151
  this.setWeightedConfidenceScore(item.items, 75);
120
152
  }
121
- else if ((item.count / postCount / ratingsCount) > 5) {
153
+ else if (ratingRatio > 5) {
122
154
  this.setWeightedConfidenceScore(item.items, 70);
123
155
  }
124
- else if ((item.count / postCount / ratingsCount) > 2) {
156
+ else if (ratingRatio > 2) {
125
157
  this.setWeightedConfidenceScore(item.items, 65);
126
158
  }
127
159
  else {
@@ -1,5 +1,8 @@
1
1
  export = FraudGetRatings;
2
2
  declare class FraudGetRatings extends FraudGetEndorsements {
3
- groupConfiguration: any;
3
+ ratingDimensionCountsByGroupId: {};
4
+ getRatingDimensionCountsByGroupId(items: any): Promise<{}>;
5
+ getRatingDimensionsForItem(item: any): any;
6
+ getNormalizedRatingCount(items: any): number;
4
7
  }
5
8
  import FraudGetEndorsements = require("./FraudGetEndorsements.cjs");
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ const MAX_FRAUD_IDS_TO_DELETE = 1000;
3
+ const validActionTypes = new Set(["get-items", "delete-one-item", "delete-items"]);
4
+ const validCollectionTypes = new Set([
5
+ "endorsements",
6
+ "ratings",
7
+ "pointQualities",
8
+ "points",
9
+ "posts",
10
+ ]);
11
+ const commonMethods = new Set([
12
+ "byIpFingerprint",
13
+ "byMissingBrowserFingerprint",
14
+ "byIpAddress",
15
+ ]);
16
+ const postMethods = new Set([
17
+ ...commonMethods,
18
+ "byIpFingerprintPostId",
19
+ "byIpUserAgentPostId",
20
+ ]);
21
+ const pointMethods = new Set([
22
+ ...commonMethods,
23
+ "byIpFingerprintPointId",
24
+ "byIpUserAgentPointId",
25
+ ]);
26
+ const normalizeIdValue = (value) => {
27
+ if (typeof value === "number") {
28
+ return Number.isSafeInteger(value) && value > 0 ? value : null;
29
+ }
30
+ else if (typeof value === "string") {
31
+ const trimmedValue = value.trim();
32
+ if (!/^[1-9]\d*$/.test(trimmedValue)) {
33
+ return null;
34
+ }
35
+ const parsedValue = Number(trimmedValue);
36
+ return Number.isSafeInteger(parsedValue) ? parsedValue : null;
37
+ }
38
+ else {
39
+ return null;
40
+ }
41
+ };
42
+ const validateIdsToDelete = (idsToDelete) => {
43
+ if (idsToDelete === undefined || idsToDelete === null) {
44
+ return { idsToDelete: [] };
45
+ }
46
+ if (!Array.isArray(idsToDelete)) {
47
+ return {
48
+ error: "invalid_ids_to_delete",
49
+ idsToDelete: [],
50
+ };
51
+ }
52
+ if (idsToDelete.length > MAX_FRAUD_IDS_TO_DELETE) {
53
+ return {
54
+ error: "too_many_ids_to_delete",
55
+ idsToDelete: [],
56
+ };
57
+ }
58
+ const seenIds = new Set();
59
+ const normalizedIds = [];
60
+ for (let i = 0; i < idsToDelete.length; i++) {
61
+ const normalizedId = normalizeIdValue(idsToDelete[i]);
62
+ if (!normalizedId) {
63
+ return {
64
+ error: "invalid_ids_to_delete",
65
+ idsToDelete: [],
66
+ };
67
+ }
68
+ if (!seenIds.has(normalizedId)) {
69
+ seenIds.add(normalizedId);
70
+ normalizedIds.push(normalizedId);
71
+ }
72
+ }
73
+ return { idsToDelete: normalizedIds };
74
+ };
75
+ const normalizeIdsToDelete = (idsToDelete) => {
76
+ return validateIdsToDelete(idsToDelete).idsToDelete;
77
+ };
78
+ const getValidMethodsForCollectionType = (collectionType) => {
79
+ if (collectionType === "pointQualities") {
80
+ return pointMethods;
81
+ }
82
+ else if (collectionType === "posts") {
83
+ return commonMethods;
84
+ }
85
+ else {
86
+ return postMethods;
87
+ }
88
+ };
89
+ const validateFraudActionRequest = ({ type, selectedMethod, collectionType, idsToDelete, }) => {
90
+ if (!validActionTypes.has(type)) {
91
+ return {
92
+ error: "invalid_fraud_action_type",
93
+ idsToDelete: [],
94
+ };
95
+ }
96
+ if (!validCollectionTypes.has(collectionType)) {
97
+ return {
98
+ error: "invalid_fraud_collection_type",
99
+ idsToDelete: [],
100
+ };
101
+ }
102
+ const validMethods = getValidMethodsForCollectionType(collectionType);
103
+ if (!validMethods.has(selectedMethod)) {
104
+ return {
105
+ error: "invalid_fraud_detection_method",
106
+ idsToDelete: [],
107
+ };
108
+ }
109
+ const idsValidation = validateIdsToDelete(idsToDelete);
110
+ const normalizedIdsToDelete = idsValidation.idsToDelete;
111
+ if (idsValidation.error) {
112
+ return idsValidation;
113
+ }
114
+ if ((type === "delete-one-item" || type === "delete-items") &&
115
+ normalizedIdsToDelete.length === 0) {
116
+ return {
117
+ error: "delete_requires_ids",
118
+ idsToDelete: normalizedIdsToDelete,
119
+ };
120
+ }
121
+ if (type === "delete-one-item" && normalizedIdsToDelete.length !== 1) {
122
+ return {
123
+ error: "single_delete_requires_one_id",
124
+ idsToDelete: normalizedIdsToDelete,
125
+ };
126
+ }
127
+ if (selectedMethod === "byMissingBrowserFingerprint" &&
128
+ (type === "delete-items" || normalizedIdsToDelete.length > 1)) {
129
+ return {
130
+ error: "bulk_delete_missing_fingerprint_disabled",
131
+ idsToDelete: normalizedIdsToDelete,
132
+ };
133
+ }
134
+ return {
135
+ idsToDelete: normalizedIdsToDelete,
136
+ };
137
+ };
138
+ module.exports = {
139
+ MAX_FRAUD_IDS_TO_DELETE,
140
+ normalizeIdsToDelete,
141
+ validateFraudActionRequest,
142
+ validateIdsToDelete,
143
+ };
@@ -0,0 +1,21 @@
1
+ export const MAX_FRAUD_IDS_TO_DELETE: 1000;
2
+ export function normalizeIdsToDelete(idsToDelete: any): number[] | never[];
3
+ export function validateFraudActionRequest({ type, selectedMethod, collectionType, idsToDelete, }: {
4
+ type: any;
5
+ selectedMethod: any;
6
+ collectionType: any;
7
+ idsToDelete: any;
8
+ }): {
9
+ error: string;
10
+ idsToDelete: number[] | never[];
11
+ } | {
12
+ idsToDelete: number[] | never[];
13
+ error?: undefined;
14
+ };
15
+ export function validateIdsToDelete(idsToDelete: any): {
16
+ error: string;
17
+ idsToDelete: never[];
18
+ } | {
19
+ idsToDelete: number[];
20
+ error?: undefined;
21
+ };
@@ -4,9 +4,11 @@ const models = require("../../../../models/index.cjs");
4
4
  const i18n = require('../../../utils/i18n.cjs');
5
5
  const deepEqual = require('deep-equal');
6
6
  const log = require("../../../../utils/logger.cjs");
7
- const FraudGetEndorsements = require("./FraudGetEndorsements");
8
- const FraudGetPointQualities = require("./FraudGetPointQualities");
9
- const FraudGetRatings = require("./FraudGetRatings");
7
+ const FraudGetEndorsements = require("./FraudGetEndorsements.cjs");
8
+ const FraudGetPointQualities = require("./FraudGetPointQualities.cjs");
9
+ const FraudGetRatings = require("./FraudGetRatings.cjs");
10
+ const FraudGetPoints = require("./FraudGetPoints.cjs");
11
+ const FraudGetPosts = require("./FraudGetPosts.cjs");
10
12
  const queue = require("../../../workers/queue.cjs");
11
13
  const Backend = require("i18next-fs-backend");
12
14
  const path = require("path");
@@ -15,8 +17,17 @@ class FraudScannerNotifier {
15
17
  constructor() {
16
18
  this.currentCommunity = null;
17
19
  this.uniqueCollectionItemsIds = {};
18
- this.collectionsToScan = ['endorsements', 'ratings', 'pointQualities'];
19
- this.scannerModels = [FraudGetEndorsements, FraudGetRatings, FraudGetPointQualities];
20
+ this.collectionsToScan = ['endorsements', 'ratings', 'pointQualities', 'points', 'posts'];
21
+ this.scannerModels = [
22
+ FraudGetEndorsements,
23
+ FraudGetRatings,
24
+ FraudGetPointQualities,
25
+ FraudGetPoints,
26
+ FraudGetPosts
27
+ ];
28
+ }
29
+ resetCounts() {
30
+ this.uniqueCollectionItemsIds = {};
20
31
  }
21
32
  getCommunityURL() {
22
33
  if (this.currentCommunity && this.currentCommunity.Domain && this.currentCommunity.Domain.domain_name) {
@@ -134,7 +145,7 @@ class FraudScannerNotifier {
134
145
  }
135
146
  getContainerOldCount(collectionType) {
136
147
  let foundCollection;
137
- if (this.currentCommunity.data.lastFraudScanResults) {
148
+ if (this.currentCommunity.data && this.currentCommunity.data.lastFraudScanResults) {
138
149
  for (let i = 0; i < this.currentCommunity.data.lastFraudScanResults.length; i++) {
139
150
  if (this.currentCommunity.data.lastFraudScanResults[i].collectionType &&
140
151
  this.currentCommunity.data.lastFraudScanResults[i].collectionType === collectionType) {
@@ -187,7 +198,7 @@ class FraudScannerNotifier {
187
198
  if (this.collectionsToScan[c] === "pointQualities") {
188
199
  methodsToScan = methodsToScan.concat(['byIpFingerprintPointId', 'byIpUserAgentPointId']);
189
200
  }
190
- else {
201
+ else if (this.collectionsToScan[c] !== "posts") {
191
202
  methodsToScan = methodsToScan.concat(['byIpFingerprintPostId', 'byIpUserAgentPostId']);
192
203
  }
193
204
  for (let m = 0; m < methodsToScan.length; m++) {
@@ -230,6 +241,7 @@ class FraudScannerNotifier {
230
241
  for (let i = 0; i < communities.length; i++) {
231
242
  log.info("Processing community: " + communities[i].name);
232
243
  this.currentCommunity = communities[i];
244
+ this.resetCounts();
233
245
  try {
234
246
  await this.scan();
235
247
  await this.notify();
@@ -249,32 +261,44 @@ class FraudScannerNotifier {
249
261
  });
250
262
  }
251
263
  }
252
- i18n
253
- .use(Backend)
254
- .init({
255
- preload: ['en', 'fr', 'sk', 'bg', 'cs', 'it', 'da', 'kl', 'es', 'sv', 'sq', 'uz', 'uk', 'ca', 'hr', 'ro', 'ru',
256
- 'ro_md', 'pt_br', 'hu', 'tr', 'is', 'nl', 'no', 'pl', 'zh_tw', 'ky'],
257
- fallbackLng: 'en',
258
- // this is the defaults
259
- backend: {
260
- // path where resources get loaded from
261
- loadPath: localesPath + '/{{lng}}/translation.json',
262
- // path to post missing resources
263
- addPath: localesPath + '/{{lng}}/translation.missing.json',
264
- // jsonIndent to use when storing json files
265
- jsonIndent: 2
266
- }
267
- }, function (err, t) {
268
- (async () => {
269
- try {
270
- const scanner = new FraudScannerNotifier();
271
- await scanner.scanAndNotify();
272
- log.info("Fraud Scanning Complete");
273
- process.exit();
274
- }
275
- catch (error) {
276
- log.error(error);
277
- process.exit();
264
+ const runFraudScannerNotifier = () => {
265
+ i18n
266
+ .use(Backend)
267
+ .init({
268
+ preload: ['en', 'fr', 'sk', 'bg', 'cs', 'it', 'da', 'kl', 'es', 'sv', 'sq', 'uz', 'uk', 'ca', 'hr', 'ro', 'ru',
269
+ 'ro_md', 'pt_br', 'hu', 'tr', 'is', 'nl', 'no', 'pl', 'zh_tw', 'ky'],
270
+ fallbackLng: 'en',
271
+ // this is the defaults
272
+ backend: {
273
+ // path where resources get loaded from
274
+ loadPath: localesPath + '/{{lng}}/translation.json',
275
+ // path to post missing resources
276
+ addPath: localesPath + '/{{lng}}/translation.missing.json',
277
+ // jsonIndent to use when storing json files
278
+ jsonIndent: 2
278
279
  }
279
- })();
280
- });
280
+ }, function (err, t) {
281
+ (async () => {
282
+ try {
283
+ if (err) {
284
+ throw err;
285
+ }
286
+ const scanner = new FraudScannerNotifier();
287
+ await scanner.scanAndNotify();
288
+ log.info("Fraud Scanning Complete");
289
+ process.exit(0);
290
+ }
291
+ catch (error) {
292
+ log.error(error);
293
+ process.exit(1);
294
+ }
295
+ })();
296
+ });
297
+ };
298
+ if (require.main === module) {
299
+ runFraudScannerNotifier();
300
+ }
301
+ module.exports = {
302
+ FraudScannerNotifier,
303
+ runFraudScannerNotifier
304
+ };