abmp-npm 2.0.76 → 2.0.78

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 (99) hide show
  1. package/package.json +8 -1
  2. package/pages/Home.js +27 -55
  3. package/pages/index.js +0 -1
  4. package/public/Utils/personalDetailsUtils.js +5 -1
  5. package/public/Utils/sharedUtils.js +32 -0
  6. package/public/consts.js +0 -1
  7. package/.claude/worktrees/fix-save-button-disable/.husky/pre-commit +0 -19
  8. package/.claude/worktrees/fix-save-button-disable/.prettierignore +0 -7
  9. package/.claude/worktrees/fix-save-button-disable/.prettierrc.json +0 -16
  10. package/.claude/worktrees/fix-save-button-disable/README.md +0 -1
  11. package/.claude/worktrees/fix-save-button-disable/backend/README-member-contact-flows.md +0 -136
  12. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  13. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  14. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/login-email-sync.test.js +0 -49
  15. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  16. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/url-uniqueness.test.js +0 -194
  17. package/.claude/worktrees/fix-save-button-disable/backend/automations-methods.js +0 -13
  18. package/.claude/worktrees/fix-save-button-disable/backend/cms-data-methods.js +0 -251
  19. package/.claude/worktrees/fix-save-button-disable/backend/consts.js +0 -58
  20. package/.claude/worktrees/fix-save-button-disable/backend/contacts-methods.js +0 -67
  21. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/bulk-process-methods.js +0 -222
  22. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/consts.js +0 -39
  23. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/index.js +0 -5
  24. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/process-member-methods.js +0 -213
  25. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/schedule-methods.js +0 -41
  26. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/sync-to-cms-methods.js +0 -161
  27. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/utils.js +0 -151
  28. package/.claude/worktrees/fix-save-button-disable/backend/data-hooks.js +0 -29
  29. package/.claude/worktrees/fix-save-button-disable/backend/dev-only-methods.js +0 -58
  30. package/.claude/worktrees/fix-save-button-disable/backend/elevated-modules.js +0 -18
  31. package/.claude/worktrees/fix-save-button-disable/backend/forms-methods.js +0 -52
  32. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/httpFunctions.js +0 -86
  33. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/index.js +0 -3
  34. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/interests.js +0 -35
  35. package/.claude/worktrees/fix-save-button-disable/backend/index.js +0 -19
  36. package/.claude/worktrees/fix-save-button-disable/backend/jobs.js +0 -158
  37. package/.claude/worktrees/fix-save-button-disable/backend/login/generate-member-session-token.js +0 -27
  38. package/.claude/worktrees/fix-save-button-disable/backend/login/index.js +0 -8
  39. package/.claude/worktrees/fix-save-button-disable/backend/login/qa-login-methods.js +0 -54
  40. package/.claude/worktrees/fix-save-button-disable/backend/login/sso-methods.js +0 -159
  41. package/.claude/worktrees/fix-save-button-disable/backend/member-contact-orchestration.js +0 -111
  42. package/.claude/worktrees/fix-save-button-disable/backend/members-area-methods.js +0 -88
  43. package/.claude/worktrees/fix-save-button-disable/backend/members-data-methods.js +0 -789
  44. package/.claude/worktrees/fix-save-button-disable/backend/pac-api-methods.js +0 -54
  45. package/.claude/worktrees/fix-save-button-disable/backend/routers/index.js +0 -3
  46. package/.claude/worktrees/fix-save-button-disable/backend/routers/methods.js +0 -191
  47. package/.claude/worktrees/fix-save-button-disable/backend/routers/utils.js +0 -128
  48. package/.claude/worktrees/fix-save-button-disable/backend/search-filters-methods.js +0 -124
  49. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-primary-methods.js +0 -256
  50. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js +0 -160
  51. package/.claude/worktrees/fix-save-button-disable/backend/tasks/consts.js +0 -34
  52. package/.claude/worktrees/fix-save-button-disable/backend/tasks/daily-pull-check-methods.js +0 -78
  53. package/.claude/worktrees/fix-save-button-disable/backend/tasks/email-normalize-methods.js +0 -134
  54. package/.claude/worktrees/fix-save-button-disable/backend/tasks/index.js +0 -10
  55. package/.claude/worktrees/fix-save-button-disable/backend/tasks/migration-methods.js +0 -46
  56. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-configs.js +0 -251
  57. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-helpers-methods.js +0 -433
  58. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-process-methods.js +0 -606
  59. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-migration-methods.js +0 -378
  60. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-space-fix-methods.js +0 -174
  61. package/.claude/worktrees/fix-save-button-disable/backend/utils.js +0 -277
  62. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  63. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-ids.js +0 -159
  64. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-urls.js +0 -201
  65. package/.claude/worktrees/fix-save-button-disable/eslint.config.js +0 -120
  66. package/.claude/worktrees/fix-save-button-disable/index.js +0 -5
  67. package/.claude/worktrees/fix-save-button-disable/package-lock.json +0 -12160
  68. package/.claude/worktrees/fix-save-button-disable/package.json +0 -60
  69. package/.claude/worktrees/fix-save-button-disable/pages/ContactUs.js +0 -129
  70. package/.claude/worktrees/fix-save-button-disable/pages/Home.js +0 -779
  71. package/.claude/worktrees/fix-save-button-disable/pages/LearnMore.js +0 -27
  72. package/.claude/worktrees/fix-save-button-disable/pages/LoadingPage.js +0 -29
  73. package/.claude/worktrees/fix-save-button-disable/pages/Profile.js +0 -354
  74. package/.claude/worktrees/fix-save-button-disable/pages/QAPage.js +0 -39
  75. package/.claude/worktrees/fix-save-button-disable/pages/SaveAlerts.js +0 -13
  76. package/.claude/worktrees/fix-save-button-disable/pages/SelectBannerImages.js +0 -46
  77. package/.claude/worktrees/fix-save-button-disable/pages/deleteConfirm.js +0 -19
  78. package/.claude/worktrees/fix-save-button-disable/pages/index.js +0 -12
  79. package/.claude/worktrees/fix-save-button-disable/pages/personalDetails.js +0 -2486
  80. package/.claude/worktrees/fix-save-button-disable/public/Utils/homePage.js +0 -798
  81. package/.claude/worktrees/fix-save-button-disable/public/Utils/personalDetailsUtils.js +0 -25
  82. package/.claude/worktrees/fix-save-button-disable/public/Utils/sharedUtils.js +0 -235
  83. package/.claude/worktrees/fix-save-button-disable/public/consts.js +0 -113
  84. package/.claude/worktrees/fix-save-button-disable/public/index.js +0 -5
  85. package/.claude/worktrees/fix-save-button-disable/public/messages.js +0 -16
  86. package/.claude/worktrees/fix-save-button-disable/public/sso-auth-methods.js +0 -43
  87. package/.husky/pre-commit +0 -19
  88. package/.prettierignore +0 -7
  89. package/.prettierrc.json +0 -16
  90. package/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  91. package/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  92. package/backend/__tests__/login-email-sync.test.js +0 -49
  93. package/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  94. package/backend/__tests__/url-uniqueness.test.js +0 -194
  95. package/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  96. package/dev-only-scripts/find-duplicate-ids.js +0 -159
  97. package/dev-only-scripts/find-duplicate-urls.js +0 -201
  98. package/eslint.config.js +0 -120
  99. package/pages/contactForLocation.js +0 -28
@@ -1,158 +0,0 @@
1
- const { taskManager } = require('psdev-task-manager');
2
-
3
- const { scheduleDailyPullTasks } = require('./daily-pull/schedule-methods');
4
- const { TASKS_NAMES } = require('./tasks/consts');
5
- const { dailyPullExecutionCheck } = require('./tasks/daily-pull-check-methods');
6
- const { TASKS } = require('./tasks/tasks-configs');
7
-
8
- async function runScheduledTasks() {
9
- try {
10
- console.log('runScheduledTasks started');
11
- return await taskManager().runScheduledTasks(TASKS);
12
- } catch (error) {
13
- console.error(`Failed to runScheduledTasks: ${error.message}`);
14
- throw new Error(`Failed to runScheduledTasks: ${error.message}`);
15
- }
16
- }
17
-
18
- /**
19
- * Schedule daily pull tasks for all member actions.
20
- * @param {string|Object} [options] - Optional. Either a backup date (YYYY-MM-DD) or options.
21
- * @param {string} [options.backupDate] - Optional backup date to pull.
22
- * @param {boolean} [options.isTestEnvironment=false] - Whether to use test environment.
23
- * @param {boolean} [options.includeNone=false] - Whether to include NONE action.
24
- * @returns {Promise<void>}
25
- */
26
- async function scheduleDailyPullTask(options = null) {
27
- try {
28
- console.log('scheduleDailyPullTask started!');
29
- const hasOptions = options && typeof options === 'object' && !Array.isArray(options);
30
- const backupDate = hasOptions ? options.backupDate : options;
31
- const isTestEnvironment = hasOptions ? Boolean(options.isTestEnvironment) : false;
32
- const includeNone = hasOptions ? Boolean(options.includeNone) : false;
33
- console.log(`backupDate: ${backupDate}`);
34
- console.log(`isTestEnvironment: ${isTestEnvironment}`);
35
- console.log(`includeNone: ${includeNone}`);
36
-
37
- return await scheduleDailyPullTasks({ backupDate, isTestEnvironment, includeNone });
38
- } catch (error) {
39
- console.error(`Failed to scheduleDailyPullTask: ${error.message}`);
40
- throw new Error(`Failed to scheduleDailyPullTask: ${error.message}`);
41
- }
42
- }
43
-
44
- async function scheduleCreateContactsFromMembersTask() {
45
- try {
46
- console.log('scheduleCreateContactsFromMembers started!');
47
- return await taskManager().schedule({
48
- name: TASKS_NAMES.scheduleCreateContactsFromMembers,
49
- data: {},
50
- type: 'scheduled',
51
- });
52
- } catch (error) {
53
- console.error(`Failed to scheduleCreateContactsFromMembers: ${error.message}`);
54
- throw new Error(`Failed to scheduleCreateContactsFromMembers: ${error.message}`);
55
- }
56
- }
57
-
58
- async function scheduleFixPrimaryAddressForMembersTask() {
59
- try {
60
- console.log('scheduleFixPrimaryAddressForMembers started!');
61
- return await taskManager().schedule({
62
- name: TASKS_NAMES.scheduleFixPrimaryAddressForMembers,
63
- data: {},
64
- type: 'scheduled',
65
- });
66
- } catch (error) {
67
- console.error(`Failed to scheduleFixPrimaryAddressForMembers: ${error.message}`);
68
- throw new Error(`Failed to scheduleFixPrimaryAddressForMembers: ${error.message}`);
69
- }
70
- }
71
-
72
- async function scheduleFixUrlsWithSpacesTask() {
73
- try {
74
- console.log('scheduleFixUrlsWithSpaces started!');
75
- return await taskManager().schedule({
76
- name: TASKS_NAMES.scheduleFixUrlsWithSpaces,
77
- data: {},
78
- type: 'scheduled',
79
- });
80
- } catch (error) {
81
- console.error(`Failed to scheduleFixUrlsWithSpaces: ${error.message}`);
82
- throw new Error(`Failed to scheduleFixUrlsWithSpaces: ${error.message}`);
83
- }
84
- }
85
-
86
- async function scheduleNormalizeMemberEmailsTask() {
87
- try {
88
- console.log('scheduleNormalizeMemberEmails started!');
89
- return await taskManager().schedule({
90
- name: TASKS_NAMES.scheduleNormalizeMemberEmails,
91
- data: {},
92
- type: 'scheduled',
93
- });
94
- } catch (error) {
95
- console.error(`Failed to scheduleNormalizeMemberEmails: ${error.message}`);
96
- throw new Error(`Failed to scheduleNormalizeMemberEmails: ${error.message}`);
97
- }
98
- }
99
-
100
- /**
101
- * Schedules setting ALL addresses for ALL members that have any address to STATE_CITY_ZIP
102
- * (show city/state/zip, hide the street). Manually triggered one-off maintenance task.
103
- */
104
- async function scheduleSetAddressesToCityStateTask() {
105
- try {
106
- console.log('scheduleSetAddressesToCityState started!');
107
- return await taskManager().schedule({
108
- name: TASKS_NAMES.scheduleSetAddressesToCityState,
109
- data: {},
110
- type: 'scheduled',
111
- });
112
- } catch (error) {
113
- console.error(`Failed to scheduleSetAddressesToCityState: ${error.message}`);
114
- throw new Error(`Failed to scheduleSetAddressesToCityState: ${error.message}`);
115
- }
116
- }
117
-
118
- /**
119
- * Runs the daily pull execution check (watchdog).
120
- * @param {Object} [options]
121
- * @param {number} [options.hoursBack=4] - Lookback window in hours
122
- * @param {boolean} [options.isTestEnvironment=false] - Pull from the test PAC API if the fallback fires
123
- * @param {boolean} [options.includeNone=false] - Include the NONE action if the fallback fires
124
- * @returns {Promise<Object>} - Check result
125
- */
126
- async function runDailyPullExecutionCheck(options = {}) {
127
- try {
128
- console.log('runDailyPullExecutionCheck started!');
129
- return await dailyPullExecutionCheck(options || {});
130
- } catch (error) {
131
- console.error(`Failed to runDailyPullExecutionCheck: ${error.message}`);
132
- throw new Error(`Failed to runDailyPullExecutionCheck: ${error.message}`);
133
- }
134
- }
135
-
136
- async function updateSiteMapS3() {
137
- try {
138
- return await taskManager().schedule({
139
- name: TASKS_NAMES.updateSiteMapS3,
140
- data: {},
141
- type: 'scheduled',
142
- });
143
- } catch (error) {
144
- throw new Error(`Failed to updateSiteMapS3: ${error.message}`);
145
- }
146
- }
147
-
148
- module.exports = {
149
- runScheduledTasks,
150
- scheduleDailyPullTask,
151
- updateSiteMapS3,
152
- scheduleCreateContactsFromMembersTask,
153
- scheduleFixPrimaryAddressForMembersTask,
154
- scheduleFixUrlsWithSpacesTask,
155
- scheduleNormalizeMemberEmailsTask,
156
- scheduleSetAddressesToCityStateTask,
157
- runDailyPullExecutionCheck,
158
- };
@@ -1,27 +0,0 @@
1
- const { auth } = require('@wix/essentials');
2
- const { authentication } = require('@wix/identity');
3
-
4
- const elevatedSignOn = auth.elevate(authentication.signOn);
5
-
6
- /**
7
- * Creates a Wix member session token for SSO / QA login using @wix/identity signOn (elevated).
8
- * @param {string} email - Member login email
9
- * @returns {Promise<string>} Session token for authentication.applySessionToken on the client
10
- */
11
- async function generateMemberSessionToken(email) {
12
- const trimmedEmail = (email || '').trim();
13
- if (!trimmedEmail) {
14
- throw new Error('Email is required to generate a session token');
15
- }
16
-
17
- const response = await elevatedSignOn({ email: trimmedEmail });
18
- const sessionToken = response?.sessionToken;
19
- if (!sessionToken) {
20
- throw new Error('Failed to generate session token: empty response from signOn');
21
- }
22
- return sessionToken;
23
- }
24
-
25
- module.exports = {
26
- generateMemberSessionToken,
27
- };
@@ -1,8 +0,0 @@
1
- const { loginQAMember } = require('./qa-login-methods');
2
- const { validateMemberToken, authenticateSSOToken } = require('./sso-methods');
3
-
4
- module.exports = {
5
- loginQAMember,
6
- validateMemberToken,
7
- authenticateSSOToken,
8
- };
@@ -1,54 +0,0 @@
1
- const { CONFIG_KEYS } = require('../consts');
2
- const { prepareMemberForQALogin, getQAUsers } = require('../members-data-methods');
3
- const { getSecret, getSiteConfigs } = require('../utils');
4
-
5
- const { generateMemberSessionToken } = require('./generate-member-session-token');
6
-
7
- const validateQAUser = async userEmail => {
8
- const qaUsers = await getQAUsers();
9
- const matchingUserEmail = qaUsers.find(user => user.email === userEmail)?.email;
10
- if (!matchingUserEmail) {
11
- return { error: `Invalid user email: ${userEmail}` };
12
- }
13
- return { valid: true, email: matchingUserEmail };
14
- };
15
-
16
- /**
17
- * Login a QA user
18
- * @param {Object} params - The parameters for the login
19
- * @param {string} params.userEmail - The email of the user to login
20
- * @param {string} params.secret - The secret of the user to login
21
- * @returns {Promise<Object>} The result of the login
22
- */
23
- const loginQAMember = async ({ userEmail, secret }) => {
24
- try {
25
- const [qaSecret, allowAnyMember] = await Promise.all([
26
- getSecret('ABMP_QA_SECRET'),
27
- getSiteConfigs(CONFIG_KEYS.QA_ALLOW_ANY_MEMBER),
28
- ]);
29
- if (secret !== qaSecret) {
30
- return { success: false, error: 'Invalid secret' };
31
- }
32
- if (!allowAnyMember) {
33
- const userValidation = await validateQAUser(userEmail);
34
- if (userValidation.error) {
35
- return { success: false, error: userValidation.error };
36
- }
37
- }
38
-
39
- const memberData = await prepareMemberForQALogin(userEmail);
40
- const token = await generateMemberSessionToken(memberData.email);
41
- return {
42
- success: true,
43
- token,
44
- memberCMSId: memberData._id,
45
- };
46
- } catch (error) {
47
- console.error('QA login error:', error);
48
- return { error: 'Failed to generate session token' };
49
- }
50
- };
51
-
52
- module.exports = {
53
- loginQAMember,
54
- };
@@ -1,159 +0,0 @@
1
- const { createHmac } = require('crypto');
2
-
3
- const axios = require('axios');
4
- const { decode } = require('jwt-js-decode');
5
-
6
- const { CONFIG_KEYS, SSO_TOKEN_AUTH_API_URL } = require('../consts');
7
- const { MEMBER_ACTIONS } = require('../daily-pull/consts');
8
- const { getCurrentMember } = require('../members-area-methods');
9
- const { getCMSMemberByWixMemberId, prepareMemberForSSOLogin } = require('../members-data-methods');
10
- const {
11
- formatDateToMonthYear,
12
- getAddressDisplayOptions,
13
- isStudent,
14
- getSiteConfigs,
15
- getSecret,
16
- } = require('../utils');
17
-
18
- const { generateMemberSessionToken } = require('./generate-member-session-token');
19
-
20
- /**
21
- * Validates member token and retrieves member data
22
- * @param {string} memberIdInput - The member ID to validate
23
- * @returns {Promise<{memberData: Object|null, isValid: boolean}>} Validation result with member data
24
- */
25
- async function validateMemberToken(memberIdInput) {
26
- const invalidTokenResponse = { memberData: null, isValid: false };
27
-
28
- if (!memberIdInput) {
29
- return invalidTokenResponse;
30
- }
31
-
32
- try {
33
- const member = await getCurrentMember();
34
- if (!member || !member._id) {
35
- console.log(
36
- 'member not found from members.getCurrentMember() for memberIdInput',
37
- memberIdInput
38
- );
39
- return invalidTokenResponse;
40
- }
41
-
42
- const [dbMember, siteConfigs] = await Promise.all([
43
- getCMSMemberByWixMemberId(member._id),
44
- getSiteConfigs(),
45
- ]);
46
- const siteAssociation = siteConfigs[CONFIG_KEYS.SITE_ASSOCIATION];
47
- const membersExternalPortalUrl = siteConfigs[CONFIG_KEYS.MEMBERS_EXTERNAL_PORTAL_URL];
48
- console.log('dbMember by wix member id is:', dbMember);
49
- console.log('member._id', member._id);
50
-
51
- if (!dbMember?._id) {
52
- const errorMessage = `No record found in DB for logged in Member [Corrupted Data - Duplicate Members? ] - There is no match in DB for currentMember: ${JSON.stringify(
53
- { memberIdInput, currentMemberId: member._id }
54
- )}`;
55
- console.error(errorMessage);
56
- throw new Error('CORRUPTED_MEMBER_DATA');
57
- }
58
-
59
- console.log(`Id found in DB for memberIdInput :${memberIdInput} is ${dbMember?._id}`);
60
-
61
- const memberData = dbMember;
62
-
63
- // Format membership dates
64
- memberData.memberships = memberData.memberships.map(membership => ({
65
- ...membership,
66
- membersince: formatDateToMonthYear(membership.membersince),
67
- isSiteAssociation: membership.association === siteAssociation,
68
- }));
69
-
70
- const savedMemberId = memberData?._id;
71
- const isValid = savedMemberId === memberIdInput;
72
-
73
- if (!savedMemberId || !isValid) {
74
- return invalidTokenResponse;
75
- }
76
-
77
- // Check if member is dropped
78
- if (memberData.action === MEMBER_ACTIONS.DROP) {
79
- return invalidTokenResponse;
80
- }
81
-
82
- // Add computed properties
83
- memberData.addressDisplayOption = getAddressDisplayOptions(memberData);
84
- console.log('memberData', memberData);
85
- memberData.isStudent = isStudent(memberData);
86
-
87
- return { memberData, isValid, membersExternalPortalUrl };
88
- } catch (error) {
89
- console.error('Error in validateMemberToken:', error);
90
- throw error;
91
- }
92
- }
93
- async function checkAndFetchSSO(token) {
94
- const SSO_TOKEN_AUTH_API_KEY = await getSecret('SSO_TOKEN_AUTH_API_KEY');
95
- const signature = createHmac('sha256', SSO_TOKEN_AUTH_API_KEY).update(token).digest('hex');
96
- const professionalassistcorpUrl = `${SSO_TOKEN_AUTH_API_URL}/eweb/SSOToken.ashx?token=${token}&Partner=Wix&Signature=${signature}`;
97
- try {
98
- const httpResponse = await axios.get(professionalassistcorpUrl, {
99
- transformResponse: [d => d],
100
- validateStatus: () => true,
101
- });
102
- console.log('httpResponse status', httpResponse.status);
103
- if (httpResponse.status < 200 || httpResponse.status >= 300) {
104
- throw new Error('Fetch did not succeed with status: ' + httpResponse.status);
105
- }
106
- return httpResponse.data;
107
- } catch (error) {
108
- console.error('Error in checkAndFetchSSO', error);
109
- return null;
110
- }
111
- }
112
-
113
- /**
114
- * Authenticate an SSO token
115
- * @param {Object} params - The parameters for the authentication
116
- * @param {string} params.token - The token to authenticate
117
- * @returns {Promise<Object>} The result of the authentication
118
- */
119
- const authenticateSSOToken = async ({ token }) => {
120
- const responseToken = await checkAndFetchSSO(token);
121
- const isValidToken = Boolean(
122
- responseToken && typeof responseToken === 'string' && responseToken?.trim()
123
- );
124
- const toLogTokenData = {
125
- isValidToken,
126
- tokenData: responseToken
127
- ? {
128
- length: responseToken.length,
129
- preview: responseToken.substring(0, 50),
130
- }
131
- : 'No token',
132
- };
133
- console.log('checkAndFetchSSO responseToken data', JSON.stringify(toLogTokenData, null, 2));
134
- if (isValidToken) {
135
- const jwt = decode(responseToken);
136
- const payload = jwt.payload;
137
- const memberData = await prepareMemberForSSOLogin(payload);
138
- console.log('memberDataCollectionId', memberData._id);
139
- const sessionToken = await generateMemberSessionToken(memberData.email);
140
- const authObj = {
141
- type: 'success',
142
- memberId: memberData._id,
143
- sessionToken,
144
- };
145
- return authObj;
146
- } else {
147
- console.log('invalid Token responseToken is: ', responseToken);
148
- return {
149
- type: 'error',
150
- memberId: '',
151
- sessionToken: '',
152
- };
153
- }
154
- };
155
-
156
- module.exports = {
157
- validateMemberToken,
158
- authenticateSSOToken,
159
- };
@@ -1,111 +0,0 @@
1
- /**
2
- * Orchestrates syncing between Wix Members and CRM Contacts.
3
- * Returns member data to save; caller does a single updateMember to avoid double-write.
4
- */
5
- const { emailsMatch } = require('../public/Utils/sharedUtils');
6
-
7
- const { createSiteContact, updateContactInfo, deleteSiteContact } = require('./contacts-methods');
8
-
9
- /**
10
- * Updates contact email in CRM. Returns member patch { wixContactId } when member record
11
- * must change; otherwise null. Caller merges and saves once.
12
- */
13
- async function updateContactEmail(newContactEmail, existingMemberData) {
14
- if (!newContactEmail) {
15
- throw new Error('New email is required');
16
- }
17
- if (!existingMemberData || existingMemberData.wixContactId == null) {
18
- throw new Error('Existing member data with wixContactId is required');
19
- }
20
-
21
- const { wixContactId, wixMemberId, email: loginEmail } = existingMemberData;
22
- const isSingleEntity = wixContactId === wixMemberId;
23
- // Compare case-insensitively: Wix CRM enforces email uniqueness without regard to case,
24
- // so a contact email that equals the login email (e.g. different casing) must collapse to
25
- // a single entity rather than attempt a duplicate contact write.
26
- const contactEmailDiffersFromLogin = !emailsMatch(loginEmail, newContactEmail);
27
-
28
- if (!contactEmailDiffersFromLogin) {
29
- if (isSingleEntity) {
30
- return null;
31
- }
32
- await deleteSiteContact(wixContactId);
33
- return { wixContactId: wixMemberId };
34
- }
35
-
36
- if (isSingleEntity) {
37
- const newWixContactId = await createSiteContact({
38
- firstName: existingMemberData.firstName,
39
- lastName: existingMemberData.lastName,
40
- contactFormEmail: newContactEmail,
41
- });
42
- return { wixContactId: newWixContactId };
43
- }
44
-
45
- await updateContactInfo(
46
- wixContactId,
47
- currentInfo => ({
48
- ...currentInfo,
49
- emails: {
50
- items: [{ email: newContactEmail, primary: true }],
51
- },
52
- }),
53
- 'update contact email'
54
- );
55
- return null;
56
- }
57
-
58
- async function updateContactNames({ wixContactId, firstName, lastName }) {
59
- if (!firstName && !lastName) {
60
- throw new Error('First name or last name is required');
61
- }
62
- const createNameUpdate = currentInfo => ({
63
- ...currentInfo,
64
- name: {
65
- first: firstName || currentInfo?.name?.first || '',
66
- last: lastName || currentInfo?.name?.last || '',
67
- },
68
- });
69
- return await updateContactInfo(wixContactId, createNameUpdate, 'update contact names');
70
- }
71
-
72
- /**
73
- * Syncs contact with member (email, names). Contact CRUD only; returns member data to save.
74
- * Caller must call updateMember once with the result.
75
- */
76
- async function updateMemberContactInfo(data, existingMemberData) {
77
- const { wixContactId } = existingMemberData;
78
- if (!wixContactId) {
79
- throw new Error('Wix Contact ID is required');
80
- }
81
- const updateConfig = [
82
- {
83
- fields: ['contactFormEmail'],
84
- updater: updateContactEmail,
85
- args: ([email]) => [email, existingMemberData],
86
- returnsMemberPatch: true,
87
- },
88
- {
89
- fields: ['firstName', 'lastName'],
90
- updater: updateContactNames,
91
- args: ([firstName, lastName]) => [{ firstName, lastName, wixContactId }],
92
- returnsMemberPatch: false,
93
- },
94
- ];
95
-
96
- const results = await Promise.all(
97
- updateConfig.map(async ({ fields, updater, args, returnsMemberPatch }) => {
98
- const existingValues = fields.map(field => existingMemberData[field]);
99
- const newValues = fields.map(field => data[field]);
100
- const hasChanged = existingValues.some((val, idx) => val !== newValues[idx]);
101
- if (!hasChanged) return null;
102
- const result = await updater(...args(newValues));
103
- return returnsMemberPatch ? result : null;
104
- })
105
- );
106
-
107
- const memberPatch = results.reduce((acc, patch) => (patch ? { ...acc, ...patch } : acc), {});
108
- return { ...data, ...memberPatch };
109
- }
110
-
111
- module.exports = { updateMemberContactInfo };
@@ -1,88 +0,0 @@
1
- const { auth } = require('@wix/essentials');
2
- const { members, authentication } = require('@wix/members');
3
-
4
- const { LOGIN_EMAIL_SYNC_STATUS } = require('./consts');
5
-
6
- const elevatedCreateMember = auth.elevate(members.createMember);
7
- const elevatedChangeLoginEmail = auth.elevate(authentication.changeLoginEmail);
8
-
9
- const LOG = '[loginEmailSync]';
10
-
11
- function prepareMemberData(partner) {
12
- const options = {
13
- member: {
14
- loginEmail: partner.email,
15
- contact: {
16
- firstName: partner.firstName,
17
- lastName: partner.lastName,
18
- },
19
- },
20
- };
21
- return options;
22
- }
23
- async function createMemberFunction(member) {
24
- const newMember = await elevatedCreateMember(member);
25
- console.log('[createMemberFunction]newMember', JSON.stringify(newMember, null, 2));
26
- return newMember._id;
27
- }
28
- const createSiteMember = async memberDetails => {
29
- console.log('createSiteMember memberDetails', memberDetails);
30
- try {
31
- const options = prepareMemberData(memberDetails);
32
- return await createMemberFunction(options);
33
- } catch (error) {
34
- console.error(`Error in createSiteMember ${error.message}`);
35
- throw error;
36
- }
37
- };
38
-
39
- const getCurrentMember = async () => {
40
- const member = await members.getCurrentMember();
41
- return member.member;
42
- };
43
-
44
- /**
45
- * Attempts to change a Wix member's login email to `member.email` and reports a structured
46
- * outcome instead of swallowing failures. Never throws.
47
- *
48
- * Outcomes:
49
- * - SKIPPED: member has no wixMemberId, nothing to change.
50
- * - UPDATED: Wix login email changed successfully.
51
- * - FAILED: change failed. The caller keeps the CMS login email unchanged (so it stays
52
- * consistent with Wix) and reports the member in the task result for manual handling.
53
- *
54
- * @param {Object} member - Member with { memberId, wixMemberId, email }
55
- * @returns {Promise<Object>} outcome
56
- */
57
- async function updateWixMemberLoginEmail(member) {
58
- const desiredEmail = member.email;
59
- const base = { memberId: member.memberId, wixMemberId: member.wixMemberId, desiredEmail };
60
-
61
- if (!member.wixMemberId) {
62
- console.log(`${LOG} member ${member.memberId} has no wixMemberId - skipping`);
63
- return { ...base, status: LOGIN_EMAIL_SYNC_STATUS.SKIPPED };
64
- }
65
-
66
- console.log(
67
- `${LOG} attempting login-email change for member ${member.memberId} (wixMemberId: ${member.wixMemberId}) -> ${desiredEmail}`
68
- );
69
-
70
- try {
71
- const updatedWixMember = await elevatedChangeLoginEmail(member.wixMemberId, desiredEmail);
72
- console.log(
73
- `${LOG} ✅ updated member ${member.memberId} (wixMemberId: ${member.wixMemberId}) -> ${updatedWixMember.loginEmail}`
74
- );
75
- return { ...base, status: LOGIN_EMAIL_SYNC_STATUS.UPDATED };
76
- } catch (error) {
77
- console.error(
78
- `${LOG} ❌ login-email change failed for member ${member.memberId} (wixMemberId: ${member.wixMemberId}) -> ${desiredEmail}: ${error.message}`
79
- );
80
- return { ...base, status: LOGIN_EMAIL_SYNC_STATUS.FAILED, error: error.message };
81
- }
82
- }
83
-
84
- module.exports = {
85
- createSiteMember,
86
- getCurrentMember,
87
- updateWixMemberLoginEmail,
88
- };