abmp-npm 2.0.77 → 2.0.79

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 (101) hide show
  1. package/package.json +8 -1
  2. package/pages/Profile.js +6 -1
  3. package/public/Utils/personalDetailsUtils.js +17 -6
  4. package/.claude/skills/wix-data-query/SKILL.md +0 -167
  5. package/.claude/skills/wix-data-query/references/backup-archive.md +0 -136
  6. package/.claude/skills/wix-data-query/references/members-data-latest.md +0 -125
  7. package/.claude/skills/wix-data-query/references/recipes.md +0 -264
  8. package/.claude/worktrees/fix-save-button-disable/.husky/pre-commit +0 -19
  9. package/.claude/worktrees/fix-save-button-disable/.prettierignore +0 -7
  10. package/.claude/worktrees/fix-save-button-disable/.prettierrc.json +0 -16
  11. package/.claude/worktrees/fix-save-button-disable/README.md +0 -1
  12. package/.claude/worktrees/fix-save-button-disable/backend/README-member-contact-flows.md +0 -136
  13. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  14. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  15. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/login-email-sync.test.js +0 -49
  16. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  17. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/url-uniqueness.test.js +0 -194
  18. package/.claude/worktrees/fix-save-button-disable/backend/automations-methods.js +0 -13
  19. package/.claude/worktrees/fix-save-button-disable/backend/cms-data-methods.js +0 -251
  20. package/.claude/worktrees/fix-save-button-disable/backend/consts.js +0 -58
  21. package/.claude/worktrees/fix-save-button-disable/backend/contacts-methods.js +0 -67
  22. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/bulk-process-methods.js +0 -222
  23. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/consts.js +0 -39
  24. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/index.js +0 -5
  25. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/process-member-methods.js +0 -213
  26. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/schedule-methods.js +0 -41
  27. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/sync-to-cms-methods.js +0 -161
  28. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/utils.js +0 -151
  29. package/.claude/worktrees/fix-save-button-disable/backend/data-hooks.js +0 -29
  30. package/.claude/worktrees/fix-save-button-disable/backend/dev-only-methods.js +0 -58
  31. package/.claude/worktrees/fix-save-button-disable/backend/elevated-modules.js +0 -18
  32. package/.claude/worktrees/fix-save-button-disable/backend/forms-methods.js +0 -52
  33. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/httpFunctions.js +0 -86
  34. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/index.js +0 -3
  35. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/interests.js +0 -35
  36. package/.claude/worktrees/fix-save-button-disable/backend/index.js +0 -19
  37. package/.claude/worktrees/fix-save-button-disable/backend/jobs.js +0 -158
  38. package/.claude/worktrees/fix-save-button-disable/backend/login/generate-member-session-token.js +0 -27
  39. package/.claude/worktrees/fix-save-button-disable/backend/login/index.js +0 -8
  40. package/.claude/worktrees/fix-save-button-disable/backend/login/qa-login-methods.js +0 -54
  41. package/.claude/worktrees/fix-save-button-disable/backend/login/sso-methods.js +0 -159
  42. package/.claude/worktrees/fix-save-button-disable/backend/member-contact-orchestration.js +0 -111
  43. package/.claude/worktrees/fix-save-button-disable/backend/members-area-methods.js +0 -88
  44. package/.claude/worktrees/fix-save-button-disable/backend/members-data-methods.js +0 -789
  45. package/.claude/worktrees/fix-save-button-disable/backend/pac-api-methods.js +0 -54
  46. package/.claude/worktrees/fix-save-button-disable/backend/routers/index.js +0 -3
  47. package/.claude/worktrees/fix-save-button-disable/backend/routers/methods.js +0 -191
  48. package/.claude/worktrees/fix-save-button-disable/backend/routers/utils.js +0 -128
  49. package/.claude/worktrees/fix-save-button-disable/backend/search-filters-methods.js +0 -124
  50. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-primary-methods.js +0 -256
  51. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js +0 -160
  52. package/.claude/worktrees/fix-save-button-disable/backend/tasks/consts.js +0 -34
  53. package/.claude/worktrees/fix-save-button-disable/backend/tasks/daily-pull-check-methods.js +0 -78
  54. package/.claude/worktrees/fix-save-button-disable/backend/tasks/email-normalize-methods.js +0 -134
  55. package/.claude/worktrees/fix-save-button-disable/backend/tasks/index.js +0 -10
  56. package/.claude/worktrees/fix-save-button-disable/backend/tasks/migration-methods.js +0 -46
  57. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-configs.js +0 -251
  58. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-helpers-methods.js +0 -433
  59. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-process-methods.js +0 -606
  60. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-migration-methods.js +0 -378
  61. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-space-fix-methods.js +0 -174
  62. package/.claude/worktrees/fix-save-button-disable/backend/utils.js +0 -277
  63. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  64. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-ids.js +0 -159
  65. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-urls.js +0 -201
  66. package/.claude/worktrees/fix-save-button-disable/eslint.config.js +0 -120
  67. package/.claude/worktrees/fix-save-button-disable/index.js +0 -5
  68. package/.claude/worktrees/fix-save-button-disable/package-lock.json +0 -12160
  69. package/.claude/worktrees/fix-save-button-disable/package.json +0 -60
  70. package/.claude/worktrees/fix-save-button-disable/pages/ContactUs.js +0 -129
  71. package/.claude/worktrees/fix-save-button-disable/pages/Home.js +0 -779
  72. package/.claude/worktrees/fix-save-button-disable/pages/LearnMore.js +0 -27
  73. package/.claude/worktrees/fix-save-button-disable/pages/LoadingPage.js +0 -29
  74. package/.claude/worktrees/fix-save-button-disable/pages/Profile.js +0 -354
  75. package/.claude/worktrees/fix-save-button-disable/pages/QAPage.js +0 -39
  76. package/.claude/worktrees/fix-save-button-disable/pages/SaveAlerts.js +0 -13
  77. package/.claude/worktrees/fix-save-button-disable/pages/SelectBannerImages.js +0 -46
  78. package/.claude/worktrees/fix-save-button-disable/pages/deleteConfirm.js +0 -19
  79. package/.claude/worktrees/fix-save-button-disable/pages/index.js +0 -12
  80. package/.claude/worktrees/fix-save-button-disable/pages/personalDetails.js +0 -2486
  81. package/.claude/worktrees/fix-save-button-disable/public/Utils/homePage.js +0 -798
  82. package/.claude/worktrees/fix-save-button-disable/public/Utils/personalDetailsUtils.js +0 -25
  83. package/.claude/worktrees/fix-save-button-disable/public/Utils/sharedUtils.js +0 -235
  84. package/.claude/worktrees/fix-save-button-disable/public/consts.js +0 -113
  85. package/.claude/worktrees/fix-save-button-disable/public/index.js +0 -5
  86. package/.claude/worktrees/fix-save-button-disable/public/messages.js +0 -16
  87. package/.claude/worktrees/fix-save-button-disable/public/sso-auth-methods.js +0 -43
  88. package/.husky/pre-commit +0 -19
  89. package/.prettierignore +0 -7
  90. package/.prettierrc.json +0 -16
  91. package/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  92. package/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  93. package/backend/__tests__/login-email-sync.test.js +0 -49
  94. package/backend/__tests__/map-link.test.js +0 -115
  95. package/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  96. package/backend/__tests__/url-uniqueness.test.js +0 -194
  97. package/backend/__tests__/url-validation.test.js +0 -69
  98. package/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  99. package/dev-only-scripts/find-duplicate-ids.js +0 -159
  100. package/dev-only-scripts/find-duplicate-urls.js +0 -201
  101. package/eslint.config.js +0 -120
@@ -1,433 +0,0 @@
1
- const crypto = require('crypto');
2
-
3
- const { auth } = require('@wix/essentials');
4
- const { files } = require('@wix/media');
5
- const aws4 = require('aws4');
6
- const axios = require('axios');
7
-
8
- const elevatedGenerateFileUploadUrl = auth.elevate(files.generateFileUploadUrl);
9
-
10
- const { PAGES_PATHS } = require('../../public/consts');
11
- const { isWixHostedImage } = require('../../public/Utils/sharedUtils');
12
- const { findMemberByWixDataId, updateMember } = require('../members-data-methods');
13
- const { getSecret, getSiteBaseUrl, encodeXml, formatDateOnly } = require('../utils');
14
- async function getServerlessAuth() {
15
- const serverlessAuth = await getSecret('serverless_auth');
16
- return serverlessAuth;
17
- }
18
-
19
- function isValidImageUrl(url) {
20
- console.log('url', url);
21
- console.log('typeof url', typeof url);
22
- if (!url || typeof url !== 'string') return false;
23
-
24
- // Check for valid URL format
25
- let parsedUrl;
26
- try {
27
- parsedUrl = new URL(url);
28
- console.log('parsedUrl', parsedUrl);
29
- } catch {
30
- return false;
31
- }
32
- console.log('parsedUrl', parsedUrl);
33
- console.log('parsedUrl.protocol', parsedUrl.protocol);
34
- // Only allow HTTP and HTTPS protocols (reject blob:, data:, file:, etc.)
35
- const validProtocols = ['http:', 'https:'];
36
- if (!validProtocols.includes(parsedUrl.protocol)) {
37
- return false;
38
- }
39
-
40
- // Extract file extension from URL (handle query parameters)
41
- const urlPath = url.split('?')[0].toLowerCase();
42
- const validExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'];
43
- console.log('urlPath', urlPath);
44
- // Check if URL ends with valid extension
45
- const hasValidExtension = validExtensions.some(ext => urlPath.endsWith(ext));
46
- console.log('hasValidExtension', hasValidExtension);
47
- // Reject obviously invalid extensions
48
- const invalidExtensions = [
49
- '.pdf',
50
- '.doc',
51
- '.docx',
52
- '.txt',
53
- '.ps',
54
- '.html',
55
- '.htm',
56
- '_jpg',
57
- '_png',
58
- '_gif',
59
- ];
60
- const hasInvalidExtension = invalidExtensions.some(ext => urlPath.includes(ext));
61
- console.log('hasInvalidExtension', hasInvalidExtension);
62
- return hasValidExtension && !hasInvalidExtension;
63
- }
64
-
65
- function isValidContentType(contentType) {
66
- if (!contentType) return false;
67
-
68
- const contentTypeLower = contentType.toLowerCase();
69
-
70
- // Valid image content types
71
- const validTypes = [
72
- 'image/jpeg',
73
- 'image/jpg',
74
- 'image/png',
75
- 'image/gif',
76
- 'image/webp',
77
- 'image/bmp',
78
- ];
79
-
80
- // Explicitly reject non-image content types
81
- const invalidTypes = [
82
- 'application/pdf',
83
- 'application/msword',
84
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
85
- 'text/plain',
86
- 'text/html',
87
- 'text/htm',
88
- 'application/octet-stream',
89
- ];
90
-
91
- if (invalidTypes.some(type => contentTypeLower.includes(type))) {
92
- return false;
93
- }
94
-
95
- return validTypes.includes(contentTypeLower);
96
- }
97
- async function updateMemberRichContent(memberId) {
98
- console.log('starting to call http function for member', memberId);
99
-
100
- const member = await findMemberByWixDataId(memberId);
101
- const htmlString = member.aboutYouHtml;
102
- const raw = JSON.stringify({
103
- content: htmlString,
104
- });
105
-
106
- const requestHeaders = {
107
- 'Content-Type': 'application/json',
108
- Cookie: 'XSRF-TOKEN=1753949844|p--a7HsuVjR4',
109
- Authorization: 'Bearer ' + (await getServerlessAuth()),
110
- };
111
-
112
- try {
113
- const response = await axios.post(
114
- 'https://www.wixapis.com/data-sync/v1/abmp-content-converter',
115
- raw,
116
- {
117
- headers: requestHeaders,
118
- validateStatus: () => true,
119
- }
120
- );
121
- if (response.status >= 200 && response.status < 300) {
122
- const data = response.data;
123
- const updatedMember = {
124
- ...member,
125
- aboutYourSelf: data.richContent.richContent,
126
- aboutYouText: data.plainText.plainText,
127
- };
128
- if (data.richContent.status != 'VALID' || data.plainText.status != 'VALID') {
129
- console.error(`updateMemberRichContent faield for member: ${memberId} `, {
130
- memberId,
131
- raw,
132
- data,
133
- });
134
- }
135
- console.log('updatedMember **********', updatedMember);
136
- await updateMember(updatedMember);
137
- console.log('rich content added successfully for member with id: ', memberId);
138
- } else {
139
- console.error(`error in fetching data for member ID: ${memberId}, response: ${response}`);
140
- }
141
- } catch (error) {
142
- console.error('error in fetching data', error);
143
- }
144
- }
145
- async function updateMemberProfileImage(memberId) {
146
- try {
147
- const member = await findMemberByWixDataId(memberId);
148
- const trimmedProfileImage = member.profileImage?.trim();
149
- // Check if member has an external profile image URL
150
- if (!trimmedProfileImage || isWixHostedImage(trimmedProfileImage)) {
151
- console.log(`Member ${memberId} already has Wix-hosted image or no image`);
152
- return { success: true, message: 'No update needed' };
153
- }
154
-
155
- // Validate image URL format before attempting download
156
- if (!isValidImageUrl(trimmedProfileImage)) {
157
- console.log(`Member ${memberId} has invalid image URL format: ${trimmedProfileImage}`);
158
- return { success: true, message: 'Invalid image URL format - skipped' };
159
- }
160
-
161
- // Encode URL to handle spaces and special characters in the path
162
- const encodedImageUrl = encodeURI(trimmedProfileImage);
163
-
164
- const response = await axios.get(encodedImageUrl, {
165
- responseType: 'arraybuffer',
166
- headers: {
167
- 'User-Agent':
168
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
169
- Accept: 'image/webp,image/apng,image/*,*/*;q=0.8',
170
- 'Accept-Language': 'en-US,en;q=0.9',
171
- 'Cache-Control': 'no-cache',
172
- },
173
- timeout: 10000, // 10 second timeout
174
- });
175
- const buffer = Buffer.from(response.data);
176
- console.log('Downloaded image buffer size:', buffer.length);
177
-
178
- // Check minimum file size (1KB) to avoid empty/corrupted files
179
- if (buffer.length < 1024) {
180
- console.log(`Member ${memberId} has file too small: ${buffer.length} bytes`);
181
- return {
182
- success: true,
183
- message: `File too small (${buffer.length} bytes) - skipped`,
184
- };
185
- }
186
-
187
- const contentType = response.headers['content-type'];
188
-
189
- // Validate content type after download
190
- if (!isValidContentType(contentType)) {
191
- console.log(`Member ${memberId} has invalid content type: ${contentType}`);
192
- return {
193
- success: true,
194
- message: `Invalid content type: ${contentType} - skipped`,
195
- };
196
- }
197
-
198
- // Determine file extension from content type
199
- const extension = contentType.includes('png')
200
- ? 'png'
201
- : contentType.includes('gif')
202
- ? 'gif'
203
- : contentType.includes('webp')
204
- ? 'webp'
205
- : contentType.includes('bmp')
206
- ? 'bmp'
207
- : 'jpg';
208
-
209
- // Double-check: ensure we're not trying to upload non-image files
210
- const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];
211
- if (!allowedExtensions.includes(extension)) {
212
- console.log(`Member ${memberId} has invalid file extension: ${extension}`);
213
- return {
214
- success: true,
215
- message: `Invalid file extension: ${extension} - skipped`,
216
- };
217
- }
218
-
219
- const sanitizedFileName = `profile-${memberId}-${Date.now()}.${extension}`.replace(/\./g, '_');
220
- const uploadUrl = (
221
- await elevatedGenerateFileUploadUrl(contentType, {
222
- fileName: sanitizedFileName,
223
- filePath: 'member-profiles',
224
- })
225
- ).uploadUrl;
226
- const params = { filename: sanitizedFileName };
227
- const headers = {
228
- 'Content-Type': contentType,
229
- };
230
-
231
- const uploadResponse = await axios.put(uploadUrl, buffer, {
232
- headers,
233
- params,
234
- });
235
- const fileUrl = uploadResponse.data.file.url;
236
- const updatedMember = {
237
- ...member,
238
- profileImage: fileUrl,
239
- };
240
- await updateMember(updatedMember);
241
-
242
- return {
243
- success: true,
244
- message: 'Profile image updated successfully',
245
- oldUrl: member.profileImage,
246
- newUrl: fileUrl,
247
- };
248
- } catch (error) {
249
- console.error(`Error updating profile image for member ${memberId}:`, error);
250
-
251
- // Handle specific HTTP errors
252
- if (error.response) {
253
- const status = error.response.status;
254
- if (status === 403) {
255
- return {
256
- success: true,
257
- message: `403 Forbidden - Access denied to image URL - skipped`,
258
- };
259
- } else if (status === 404) {
260
- return {
261
- success: true,
262
- message: `404 Not Found - Image URL not found - skipped`,
263
- };
264
- } else if (status === 406) {
265
- return {
266
- success: true,
267
- message: `406 Not Acceptable - Server rejected request headers - skipped`,
268
- };
269
- } else if (status >= 400 && status < 500) {
270
- return {
271
- success: true,
272
- message: `${status} Client Error - Invalid image URL - skipped`,
273
- };
274
- }
275
- }
276
-
277
- return {
278
- success: false,
279
- error: error.message || error,
280
- };
281
- }
282
- }
283
-
284
- async function getAWSTokens() {
285
- const [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY] = await Promise.all([
286
- getSecret('AWS_ACCESS_KEY_ID'),
287
- getSecret('AWS_SECRET_ACCESS_KEY'),
288
- ]);
289
-
290
- // const AWS_SESSION_TOKEN = await getSecret("AWS_SESSION_TOKEN")
291
- return {
292
- AWS_ACCESS_KEY_ID,
293
- AWS_SECRET_ACCESS_KEY,
294
- };
295
- }
296
-
297
- async function generateSitemapXml(members) {
298
- const baseUrl = (await getSiteBaseUrl()).replace(/\/+$/, '');
299
- const profilePageUrl = `${baseUrl}/${PAGES_PATHS.PROFILE}`;
300
- const urls = members
301
- .map(m => {
302
- const loc = `${profilePageUrl}/${encodeURIComponent(m.url)}`;
303
- const lastmod =
304
- m && m._updatedDate
305
- ? `\n <lastmod>${encodeXml(formatDateOnly(m._updatedDate))}</lastmod>`
306
- : '';
307
- return ` <url>\n <loc>${encodeXml(loc)}</loc>${lastmod}\n </url>`;
308
- })
309
- .join('\n');
310
- return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>\n`;
311
- }
312
- async function uploadMembersSitemap({ members, tokens, destinationFileName, siteAssociation }) {
313
- const toLowerCaseSiteAssociation = siteAssociation.toLowerCase().trim();
314
- const bucketHostname = (bucket, region) => {
315
- const r = region || process?.env?.AWS_REGION || process?.env?.AWS_DEFAULT_REGION || 'us-east-1';
316
- return `${bucket}.s3.${r}.amazonaws.com`;
317
- };
318
- if (!siteAssociation) {
319
- throw new Error('Site association is required to determine the AWS S3 bucket name');
320
- }
321
- const bucket = `${toLowerCaseSiteAssociation}-sitemap`; // e.g: 'abmp-sitemap' or 'ascp-sitemap'
322
- const region = 'us-east-1';
323
- const destination_file_name = destinationFileName;
324
-
325
- console.log('Sitemap generation started');
326
- const xml = await generateSitemapXml(members);
327
- console.log('Sitemap generation completed');
328
- const body = xml;
329
- console.log('Body length:', body.length);
330
- const sha256Hex = crypto.createHash('sha256').update(body).digest('hex');
331
- console.log('SHA256 hash calculated');
332
- const host = bucketHostname(bucket, region);
333
- const method = 'PUT';
334
- const pathName = `/${encodeURI(destination_file_name).replace(/%2F/g, '/')}`;
335
- console.log('Path name calculated');
336
- const headers = {
337
- 'Content-Type': 'application/xml',
338
- 'X-Amz-Content-Sha256': sha256Hex,
339
- };
340
-
341
- const creds = {
342
- accessKeyId: tokens.AWS_ACCESS_KEY_ID,
343
- secretAccessKey: tokens.AWS_SECRET_ACCESS_KEY,
344
- // sessionToken: tokens.AWS_SESSION_TOKEN,
345
- };
346
-
347
- const reqOpts = {
348
- host,
349
- path: pathName,
350
- service: 's3',
351
- region: region,
352
- method,
353
- headers,
354
- body,
355
- };
356
- aws4.sign(reqOpts, creds);
357
- console.log('Request options signed');
358
-
359
- const url = `https://${host}${pathName}`;
360
- console.log('url', url);
361
- const res = await axios.put(url, body, {
362
- headers: reqOpts.headers,
363
- transformResponse: [d => d],
364
- validateStatus: () => true,
365
- });
366
- if (res.status < 200 || res.status >= 300) {
367
- const respText = res.data;
368
- console.log('Response body', respText);
369
- throw new Error(`S3 PUT failed ${res.status} ${res.statusText}: ${respText}`);
370
- }
371
- }
372
-
373
- async function stsPost(body, baseAccessKeyId, baseSecretAccessKey) {
374
- const host = 'sts.amazonaws.com';
375
- const method = 'POST';
376
- const path = '/';
377
- const headers = {
378
- 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
379
- 'X-Amz-Content-Sha256': 'UNSIGNED-PAYLOAD',
380
- };
381
- const reqOpts = {
382
- host,
383
- path,
384
- service: 'sts',
385
- region: 'us-east-1',
386
- method,
387
- headers,
388
- body,
389
- };
390
- const parseXmlVal = (xml, tag) => {
391
- const m = xml.match(new RegExp(`<${tag}>([^<]+)</${tag}>`));
392
- return m ? m[1] : '';
393
- };
394
- aws4.sign(reqOpts, {
395
- accessKeyId: baseAccessKeyId,
396
- secretAccessKey: baseSecretAccessKey,
397
- });
398
- const res = await axios.post(`https://${host}${path}`, body, {
399
- headers: reqOpts.headers,
400
- transformResponse: [d => d],
401
- validateStatus: () => true,
402
- });
403
- const text = res.data;
404
- if (res.status < 200 || res.status >= 300) throw new Error(`STS ${res.status}: ${text}`);
405
-
406
- const accessKeyId = parseXmlVal(text, 'AccessKeyId');
407
- const secretAccessKey = parseXmlVal(text, 'SecretAccessKey');
408
- const sessionToken = parseXmlVal(text, 'SessionToken');
409
- const expiration = parseXmlVal(text, 'Expiration');
410
- if (!accessKeyId || !secretAccessKey || !sessionToken || !expiration) {
411
- throw new Error('Failed parsing STS response');
412
- }
413
- return {
414
- accessKeyId,
415
- secretAccessKey,
416
- // sessionToken,
417
- expiresAt: new Date(expiration).toISOString(),
418
- };
419
- }
420
-
421
- // GetSessionToken (no role)
422
- function getNewStsSessionToken(baseAccessKeyId, baseSecretAccessKey, durationSeconds = 3600) {
423
- const body = `Action=GetSessionToken&Version=2011-06-15&DurationSeconds=${durationSeconds}`;
424
- return stsPost(body, baseAccessKeyId, baseSecretAccessKey);
425
- }
426
-
427
- module.exports = {
428
- updateMemberRichContent,
429
- updateMemberProfileImage,
430
- getAWSTokens,
431
- uploadMembersSitemap,
432
- getNewStsSessionToken, //Dev only Method
433
- };