@plusscommunities/pluss-core-aws 2.0.25-auth.0 → 2.0.25-beta.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/aws/getDefaultEmailAddress.js +21 -21
- package/aws/getEmailService.js +16 -16
- package/aws/getEmailServiceInfo.js +26 -26
- package/aws/sendEmail.js +31 -31
- package/config.js +1 -1
- package/db/activity/publishActivity.js +22 -22
- package/db/analytics/checkActivityExists.js +15 -15
- package/db/analytics/logAnalyticsActivity.js +69 -37
- package/db/analytics/scheduleOldAggregation.js +14 -14
- package/db/auth/getSiteSetting.js +12 -12
- package/db/auth/getSiteUserTypes.js +16 -16
- package/db/auth/getUserAuth.js +13 -13
- package/db/automatedactions/getActionBySiteTrigger.js +9 -9
- package/db/common/deleteRef.js +21 -21
- package/db/common/editRef.js +36 -36
- package/db/common/getRef.js +23 -23
- package/db/common/getTableCount.js +18 -18
- package/db/common/indexQuery.js +17 -17
- package/db/common/indexQueryRecursive.js +20 -20
- package/db/common/scanRef.js +18 -18
- package/db/common/scanRefRecursive.js +20 -20
- package/db/common/updateAttribute.js +27 -27
- package/db/common/updateRef.js +20 -20
- package/db/linkedUsers/getLinkedBy.js +21 -21
- package/db/linkedUsers/getLinkedTo.js +21 -21
- package/db/notifications/deleteNotificationsByEntity.js +21 -21
- package/db/notifications/getNotificationSetting.js +14 -14
- package/db/notifications/publishNotifications.js +39 -39
- package/db/scheduledActions/deleteActionQueue.js +1 -1
- package/db/scheduledActions/getActionQueueByEntityId.js +10 -10
- package/db/scheduledActions/getActionQueueByEntityKey.js +9 -9
- package/db/scheduledActions/getActionQueueById.js +9 -9
- package/db/scheduledActions/getActionQueueByTriggerAt.js +14 -14
- package/db/scheduledActions/updateActionQueue.js +29 -29
- package/db/strings/getString.js +20 -20
- package/db/strings/logUpdate.js +18 -18
- package/db/templates/getTemplateById.js +1 -1
- package/db/templates/getTemplatesList.js +10 -10
- package/db/templates/updateTemplate.js +9 -9
- package/db/users/getRole.js +1 -1
- package/db/users/getUser.js +9 -9
- package/db/users/getUserByEmail.js +17 -17
- package/helper/audience/filterByAudienceType.js +27 -27
- package/helper/audience/filterOnAudienceType.js +26 -26
- package/helper/audience/getAudience.js +187 -187
- package/helper/audience/getMatchingAudienceTypes.js +21 -21
- package/helper/audience/getMatchingAudienceTypesFromPreview.js +60 -60
- package/helper/audience/getMatchingTags.js +15 -15
- package/helper/audience/isValidAudience.js +20 -20
- package/helper/auth/checkTokenBlacklist.js +17 -17
- package/helper/auth/getApiKeyFromReq.js +2 -2
- package/helper/auth/getSessionUser.js +70 -85
- package/helper/auth/getSessionUserFromReq.js +2 -2
- package/helper/auth/getSessionUserFromReqAuthKey.js +11 -11
- package/helper/auth/validateApiKey.js +32 -32
- package/helper/auth/validateMasterAuth.js +174 -174
- package/helper/auth/validateSiteAccess.js +12 -12
- package/helper/auth/validateSiteSetting.js +7 -7
- package/helper/auth/validateUserLoggedIn.js +19 -19
- package/helper/createGuid.js +5 -5
- package/helper/generateJsonResponse.js +27 -27
- package/helper/getUserPreview.js +57 -57
- package/helper/getUserPreviewFromHeader.js +17 -17
- package/helper/getUserPreviewFromReq.js +17 -17
- package/helper/hqPublishing.js +45 -0
- package/helper/index.js +28 -28
- package/helper/notifySiteConfigs.js +132 -0
- package/helper/opengraph/getOpenGraph.js +12 -12
- package/helper/rates/checkRateLimit.js +38 -38
- package/helper/requestToSource.js +10 -10
- package/helper/sendEmail.js +120 -120
- package/helper/templates/replacePlaceHolders.js +29 -29
- package/helper/time/getLocalTimestamp.js +18 -18
- package/helper/time/getSiteTimezone.js +11 -11
- package/helper/triggerAutomatedAction.js +25 -25
- package/helper/userToUserPreview.js +23 -23
- package/helper/users/getUserTypesByPermission.js +24 -24
- package/helper/users/getUsersByPermission.js +20 -20
- package/notification/prepNotification.js +144 -144
- package/notification/sendNotifications.js +166 -166
- package/package.json +35 -40
- package/templates/supportTicketEmails.js +8 -8
- package/helper/auth/context/AuthenticationContext.js +0 -50
- package/helper/auth/context/AuthenticationStrategy.js +0 -20
- package/helper/auth/context/auth0/Strategy.js +0 -12
- package/helper/auth/context/auth0/functions/decodeAccessToken.js +0 -102
- package/helper/auth/context/auth0/functions/getSessionUser.js +0 -21
- package/helper/auth/context/boltonclarke/Strategy.js +0 -10
- package/helper/auth/context/cognito/Strategy.js +0 -12
- package/helper/auth/context/cognito/functions/getSessionUser.js +0 -76
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const _ = require("lodash");
|
|
2
2
|
const getSessionUser = require("./getSessionUser");
|
|
3
3
|
const {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
validKioskActions,
|
|
5
|
+
validFormKioskActions,
|
|
6
6
|
} = require("./validKioskActions");
|
|
7
7
|
const getUserAuth = require("../../db/auth/getUserAuth");
|
|
8
8
|
const getSiteUserTypes = require("../../db/auth/getSiteUserTypes");
|
|
@@ -10,195 +10,195 @@ const { log, generateLogId } = require("../");
|
|
|
10
10
|
const validateApiKey = require("./validateApiKey");
|
|
11
11
|
|
|
12
12
|
const checkSite = (roles, site, actionType) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
const siteRole = _.find(roles, (r) => {
|
|
15
|
+
return r.site === site;
|
|
16
|
+
});
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
// Not attached to that site
|
|
19
|
+
if (!siteRole) {
|
|
20
|
+
log("validateMasterAuth", "Error:noSiteRole", "no role for that site");
|
|
21
|
+
return resolve(false);
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
// has site role - check for generic site access
|
|
25
|
+
if (actionType === "any") {
|
|
26
|
+
return resolve(true);
|
|
27
|
+
}
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
// If user is a KIOSK
|
|
30
|
+
if (siteRole.type === "KIOSK") {
|
|
31
|
+
log("validateMasterAuth", "KioskCheck", "user is kiosk");
|
|
32
|
+
console.log("user is kiosk");
|
|
33
|
+
return resolve(_.includes(validKioskActions, actionType));
|
|
34
|
+
}
|
|
35
|
+
// If user is a KIOSK
|
|
36
|
+
if (siteRole.type === "FORMKIOSK") {
|
|
37
|
+
log("validateMasterAuth", "KioskCheck", "user is kiosk");
|
|
38
|
+
return resolve(_.includes(validFormKioskActions, actionType));
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
// get userType definitions for particular site
|
|
42
|
+
getSiteUserTypes(siteRole.site === "hq" ? "hq" : site)
|
|
43
|
+
.then((res) => {
|
|
44
|
+
const roleType = _.find(res, (userType, index) => {
|
|
45
|
+
return userType.typeName === siteRole.type;
|
|
46
|
+
});
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
// Check permissions have been saved against that userType
|
|
49
|
+
if (!roleType || _.isEmpty(roleType.permissions)) {
|
|
50
|
+
log("validateMasterAuth", "Error:noUserType", roleType);
|
|
51
|
+
return resolve(false);
|
|
52
|
+
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
const hasAccess = _.some(roleType.permissions, function (o) {
|
|
55
|
+
return o === actionType;
|
|
56
|
+
});
|
|
57
|
+
log(
|
|
58
|
+
"validateMasterAuth",
|
|
59
|
+
`Permission:${siteRole.type}/${actionType}`,
|
|
60
|
+
hasAccess,
|
|
61
|
+
);
|
|
62
|
+
return resolve(hasAccess);
|
|
63
|
+
})
|
|
64
|
+
.catch((error) => {
|
|
65
|
+
log("validateMasterAuth", "Error:getSiteUserTypes", error);
|
|
66
|
+
return resolve(false);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
const checkApiKey = async (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
req,
|
|
73
|
+
actionType,
|
|
74
|
+
site,
|
|
75
|
+
plussStaffOnly,
|
|
76
|
+
options,
|
|
77
|
+
logId,
|
|
78
78
|
) => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
if (plussStaffOnly) {
|
|
81
|
+
return resolve(validateApiKey(req, actionType, "plussSpace"));
|
|
82
|
+
}
|
|
83
|
+
const promises = [];
|
|
84
|
+
site.forEach((s) => {
|
|
85
|
+
promises.push(validateApiKey(req, actionType, s));
|
|
86
|
+
});
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
Promise.all(promises).then((results) => {
|
|
89
|
+
log("validateMasterAuth", "ValidationResults", results, logId);
|
|
90
|
+
if (options && options.resolveAllSites) {
|
|
91
|
+
log("validateMasterAuth", "resolveAllSites", true, logId);
|
|
92
|
+
// check all sites individually
|
|
93
|
+
const authResult = site.map((s, i) => {
|
|
94
|
+
return { site: s, valid: results[i] };
|
|
95
|
+
});
|
|
96
|
+
log("validateMasterAuth", "AuthorisedAllSites", authResult, logId);
|
|
97
|
+
return resolve(authResult);
|
|
98
|
+
}
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
// check if any site is valid
|
|
101
|
+
const authorised = _.includes(results, true);
|
|
102
|
+
log("validateMasterAuth", "Authorised", authorised, logId);
|
|
103
|
+
return resolve(authorised);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
106
|
};
|
|
107
107
|
|
|
108
108
|
module.exports = async (req, actionType, site, plussStaffOnly, options) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
109
|
+
return new Promise(async (resolve) => {
|
|
110
|
+
const logId = generateLogId();
|
|
111
|
+
let uid = null;
|
|
112
|
+
let data = {};
|
|
113
|
+
if (!req) {
|
|
114
|
+
uid = options.userId; // allow for not using the request header
|
|
115
|
+
} else {
|
|
116
|
+
const data = JSON.parse(req.body);
|
|
117
|
+
if (!site) {
|
|
118
|
+
if (!data.site) {
|
|
119
|
+
log("validateMasterAuth", "Error:noSite", data, logId);
|
|
120
|
+
return resolve(false);
|
|
121
|
+
}
|
|
122
|
+
site = data.site;
|
|
123
|
+
}
|
|
124
|
+
if (req.headers.apikey) {
|
|
125
|
+
log("validateMasterAuth", "checkApiKey", req.headers.apikey, logId);
|
|
126
|
+
return resolve(
|
|
127
|
+
checkApiKey(
|
|
128
|
+
req,
|
|
129
|
+
actionType,
|
|
130
|
+
Array.isArray(site) ? site : [site],
|
|
131
|
+
plussStaffOnly,
|
|
132
|
+
options,
|
|
133
|
+
logId,
|
|
134
|
+
),
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (!req.headers.authkey) {
|
|
138
|
+
log("validateMasterAuth", "Error:noAuthKey", req.headers, logId);
|
|
139
|
+
return resolve(false);
|
|
140
|
+
}
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
uid = await getSessionUser(req.headers.authkey);
|
|
143
|
+
}
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
145
|
+
if (actionType == null || _.isUndefined(actionType)) {
|
|
146
|
+
log("validateMasterAuth", "Error:noActionType", null, logId);
|
|
147
|
+
return resolve(false);
|
|
148
|
+
}
|
|
149
|
+
if (!Array.isArray(site)) {
|
|
150
|
+
// support array of sites
|
|
151
|
+
site = [site];
|
|
152
|
+
}
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
154
|
+
log("validateMasterAuth", "SessionUser", uid);
|
|
155
|
+
getUserAuth(uid)
|
|
156
|
+
.then((roles) => {
|
|
157
|
+
// If user a master level admin
|
|
158
|
+
if (
|
|
159
|
+
_.some(roles, (r) => {
|
|
160
|
+
return r.type === "master";
|
|
161
|
+
})
|
|
162
|
+
) {
|
|
163
|
+
if (
|
|
164
|
+
plussStaffOnly &&
|
|
165
|
+
!_.some(roles, (r) => {
|
|
166
|
+
return r.site === "plussSpace" && r.type === "master";
|
|
167
|
+
})
|
|
168
|
+
) {
|
|
169
|
+
return resolve(false);
|
|
170
|
+
}
|
|
171
|
+
if (options && options.resolveAllSites) {
|
|
172
|
+
return resolve(
|
|
173
|
+
site.map((s, i) => {
|
|
174
|
+
return { site: s, valid: true };
|
|
175
|
+
}),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return resolve(true);
|
|
179
|
+
}
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
181
|
+
// allow for multiple sites to be checked
|
|
182
|
+
const promises = [];
|
|
183
|
+
site.forEach((s) => {
|
|
184
|
+
promises.push(checkSite(roles, s, actionType));
|
|
185
|
+
});
|
|
186
|
+
Promise.all(promises).then((results) => {
|
|
187
|
+
const authorised = _.includes(results, true);
|
|
188
|
+
if (options && options.resolveAllSites) {
|
|
189
|
+
return resolve(
|
|
190
|
+
site.map((s, i) => {
|
|
191
|
+
return { site: s, valid: results[i] };
|
|
192
|
+
}),
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
log("validateMasterAuth", "Authorised", authorised);
|
|
196
|
+
return resolve(authorised);
|
|
197
|
+
});
|
|
198
|
+
})
|
|
199
|
+
.catch((error2) => {
|
|
200
|
+
log("validateMasterAuth", "Error:getUserAuth", error2);
|
|
201
|
+
return resolve(false);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
204
|
};
|
|
@@ -2,16 +2,16 @@ const validateMasterAuth = require("./validateMasterAuth");
|
|
|
2
2
|
const validateApiKey = require("./validateApiKey");
|
|
3
3
|
|
|
4
4
|
module.exports = async (req, site) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
return new Promise(async (resolve) => {
|
|
6
|
+
if (!site) {
|
|
7
|
+
return resolve(false);
|
|
8
|
+
}
|
|
9
|
+
if (req.headers.apikey) {
|
|
10
|
+
return resolve(validateApiKey(req, "any", site));
|
|
11
|
+
}
|
|
12
|
+
if (!req.headers.authkey) {
|
|
13
|
+
return resolve(false);
|
|
14
|
+
}
|
|
15
|
+
return resolve(validateMasterAuth(req, "any", site));
|
|
16
|
+
});
|
|
17
17
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const getSiteSetting = require("../../db/auth/getSiteSetting");
|
|
2
2
|
|
|
3
3
|
module.exports = async (site, key, expectedValue) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
return new Promise(async (resolve) => {
|
|
5
|
+
if (!site) {
|
|
6
|
+
return resolve(false);
|
|
7
|
+
}
|
|
8
|
+
const siteSetting = await getSiteSetting(site, key);
|
|
9
|
+
return resolve(siteSetting === expectedValue);
|
|
10
|
+
});
|
|
11
11
|
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
const getSessionUserFromReqAuthKey = require("./getSessionUserFromReqAuthKey");
|
|
2
2
|
|
|
3
3
|
module.exports = async (req, userId) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
if (!req.headers.authkey && !req.headers.apikey) {
|
|
6
|
+
resolve(false);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
getSessionUserFromReqAuthKey(req)
|
|
11
|
+
.then((uid) => {
|
|
12
|
+
if (userId && uid !== userId) {
|
|
13
|
+
resolve(false);
|
|
14
|
+
} else {
|
|
15
|
+
resolve(true);
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
.catch((err) => {
|
|
19
|
+
console.log("authentication errored");
|
|
20
|
+
console.log(err);
|
|
21
|
+
resolve(false);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
24
|
};
|
package/helper/createGuid.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module.exports = () => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
3
|
+
var r = (Math.random() * 16) | 0,
|
|
4
|
+
v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
5
|
+
return v.toString(16);
|
|
6
|
+
});
|
|
7
7
|
};
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
const getCircularReplacer = () => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
const seen = new WeakSet();
|
|
3
|
+
return (key, value) => {
|
|
4
|
+
if (value instanceof Error) {
|
|
5
|
+
var error = {};
|
|
6
|
+
Object.getOwnPropertyNames(value).forEach((key) => {
|
|
7
|
+
error[key] = value[key];
|
|
8
|
+
});
|
|
9
|
+
return error;
|
|
10
|
+
} else if (typeof value === "object" && value !== null) {
|
|
11
|
+
if (seen.has(value)) return;
|
|
12
|
+
seen.add(value);
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
};
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
module.exports = (statusCode, body) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
if ([400, 402, 422].includes(statusCode)) console.error(body);
|
|
20
|
+
const jsonBody = JSON.stringify(
|
|
21
|
+
(body && body.error) || body,
|
|
22
|
+
getCircularReplacer(),
|
|
23
|
+
);
|
|
24
|
+
return {
|
|
25
|
+
statusCode,
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
"Access-Control-Allow-Origin": "*",
|
|
29
|
+
},
|
|
30
|
+
body: jsonBody,
|
|
31
|
+
};
|
|
32
32
|
};
|