Merged in feature/IO-3182-Phone-Number-Consent (pull request #2321)

Feature/IO-3182 Phone Number Consent
This commit is contained in:
Dave Richer
2025-05-20 17:45:24 +00:00
15 changed files with 919 additions and 1192 deletions

321
client/package-lock.json generated
View File

@@ -13,19 +13,19 @@
"@apollo/client": "^3.13.6",
"@emotion/is-prop-valid": "^1.3.1",
"@fingerprintjs/fingerprintjs": "^4.6.1",
"@firebase/analytics": "^0.10.13",
"@firebase/app": "^0.12.1",
"@firebase/auth": "^1.10.2",
"@firebase/firestore": "^4.7.12",
"@firebase/messaging": "^0.12.18",
"@firebase/analytics": "^0.10.16",
"@firebase/app": "^0.13.0",
"@firebase/auth": "^1.10.5",
"@firebase/firestore": "^4.7.15",
"@firebase/messaging": "^0.12.21",
"@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.8.1",
"@reduxjs/toolkit": "^2.8.2",
"@sentry/cli": "^2.45.0",
"@sentry/react": "^9.18.0",
"@sentry/react": "^9.21.0",
"@sentry/vite-plugin": "^3.4.0",
"@splitsoftware/splitio-react": "^2.1.1",
"@tanem/react-nprogress": "^5.0.53",
"antd": "^5.25.1",
"antd": "^5.25.2",
"apollo-link-logger": "^2.0.1",
"apollo-link-sentry": "^4.3.0",
"autosize": "^6.0.1",
@@ -49,7 +49,7 @@
"normalize-url": "^8.0.1",
"object-hash": "^3.0.0",
"prop-types": "^15.8.1",
"query-string": "^9.1.2",
"query-string": "^9.2.0",
"raf-schd": "^4.0.3",
"react": "^18.3.1",
"react-big-calendar": "^1.18.0",
@@ -78,7 +78,7 @@
"redux-saga": "^1.3.0",
"redux-state-sync": "^3.1.4",
"reselect": "^5.1.1",
"sass": "^1.88.0",
"sass": "^1.89.0",
"socket.io-client": "^4.8.1",
"styled-components": "^6.1.18",
"subscriptions-transport-ws": "^0.11.0",
@@ -90,10 +90,10 @@
"@ant-design/icons": "^6.0.0",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-react": "^7.27.1",
"@dotenvx/dotenvx": "^1.44.0",
"@dotenvx/dotenvx": "^1.44.1",
"@emotion/babel-plugin": "^11.13.5",
"@emotion/react": "^11.14.0",
"@eslint/js": "^9.26.0",
"@eslint/js": "^9.27.0",
"@playwright/test": "^1.51.1",
"@sentry/webpack-plugin": "^3.4.0",
"@testing-library/dom": "^10.4.0",
@@ -108,7 +108,7 @@
"eslint-plugin-react": "^7.37.5",
"globals": "^15.15.0",
"jsdom": "^26.0.0",
"memfs": "^4.17.1",
"memfs": "^4.17.2",
"os-browserify": "^0.3.0",
"playwright": "^1.51.1",
"react-error-overlay": "^6.1.0",
@@ -120,7 +120,7 @@
"vite-plugin-node-polyfills": "^0.23.0",
"vite-plugin-pwa": "^1.0.0",
"vite-plugin-style-import": "^2.0.0",
"vitest": "^3.1.3",
"vitest": "^3.1.4",
"workbox-window": "^7.3.0"
},
"engines": {
@@ -2587,9 +2587,9 @@
}
},
"node_modules/@dotenvx/dotenvx": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.44.0.tgz",
"integrity": "sha512-18Aa+7KP/L2Kj9lxmT4EJZnsCq/xGIHgzU26rdzsKMhjpeT3YY+qin/dNAnIaVHPZnee7kXpZL55M9htd30r7Q==",
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.44.1.tgz",
"integrity": "sha512-j1QImCqf/XJmhIjC1OPpgiZV9g370HG9MNT9s/CDwCKsoYzNCPEKK+GfsidahJx7yIlBbm+4dPLlGec+bKn7oA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -2912,13 +2912,16 @@
}
},
"node_modules/@eslint/js": {
"version": "9.26.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz",
"integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==",
"version": "9.27.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz",
"integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://eslint.org/donate"
}
},
"node_modules/@fingerprintjs/fingerprintjs": {
@@ -2931,15 +2934,15 @@
}
},
"node_modules/@firebase/analytics": {
"version": "0.10.13",
"resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.13.tgz",
"integrity": "sha512-X+6wMOPgA9l0AeeMdMcMfaCP4XKPvrhx55MGuMrfHvUrOvFKldpzBum7KkoGJMoexKmqmKP+mCmJMY9Fb8K6Hw==",
"version": "0.10.16",
"resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.16.tgz",
"integrity": "sha512-cMtp19He7Fd6uaj/nDEul+8JwvJsN8aRSJyuA1QN3QrKvfDDp+efjVurJO61sJpkVftw9O9nNMdhFbRcTmTfRQ==",
"license": "Apache-2.0",
"dependencies": {
"@firebase/component": "0.6.14",
"@firebase/installations": "0.6.14",
"@firebase/component": "0.6.17",
"@firebase/installations": "0.6.17",
"@firebase/logger": "0.4.4",
"@firebase/util": "1.11.1",
"@firebase/util": "1.12.0",
"tslib": "^2.1.0"
},
"peerDependencies": {
@@ -2947,14 +2950,14 @@
}
},
"node_modules/@firebase/app": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.12.1.tgz",
"integrity": "sha512-ASExOlmmjRMdwOQ65Oj6R9JBqa7iiT1/LgZjtbU7FqxoJZNWHrt39NJ/z2bjyYDdAHX8jkY7muFqzahScCXgfA==",
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.0.tgz",
"integrity": "sha512-Vj3MST245nq+V5UmmfEkB3isIgPouyUr8yGJlFeL9Trg/umG5ogAvrjAYvQ8gV7daKDoQSRnJKWI2JFpQqRsuQ==",
"license": "Apache-2.0",
"dependencies": {
"@firebase/component": "0.6.14",
"@firebase/component": "0.6.17",
"@firebase/logger": "0.4.4",
"@firebase/util": "1.11.1",
"@firebase/util": "1.12.0",
"idb": "7.1.1",
"tslib": "^2.1.0"
},
@@ -2963,14 +2966,14 @@
}
},
"node_modules/@firebase/auth": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.2.tgz",
"integrity": "sha512-HHudcj3CJyXpoMKslNOVHGSNJdAUjvy5xBA/G/uPb32QFqvx5F3EW9RDYvve2IHEN7Vpc1QTkk/28J32x83UGA==",
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.5.tgz",
"integrity": "sha512-6wF/NdMTwObL4RNQePunuzMr9O3gyftisvFZFFKf57D2HONXo87YymogRV8d+Z7SLA0rcNBN1gLJVk2D0y97gA==",
"license": "Apache-2.0",
"dependencies": {
"@firebase/component": "0.6.14",
"@firebase/component": "0.6.17",
"@firebase/logger": "0.4.4",
"@firebase/util": "1.11.1",
"@firebase/util": "1.12.0",
"tslib": "^2.1.0"
},
"engines": {
@@ -2987,12 +2990,12 @@
}
},
"node_modules/@firebase/component": {
"version": "0.6.14",
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.14.tgz",
"integrity": "sha512-kf/zAT8GQJ9nYoHuj0mv7twp1QzifKYrO+GsmsVHHM+Hi9KkmI7E3B3J0CtihHpb34vinl4gbJrYJ2p2wfvc9A==",
"version": "0.6.17",
"resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.17.tgz",
"integrity": "sha512-M6DOg7OySrKEFS8kxA3MU5/xc37fiOpKPMz6cTsMUcsuKB6CiZxxNAvgFta8HGRgEpZbi8WjGIj6Uf+TpOhyzg==",
"license": "Apache-2.0",
"dependencies": {
"@firebase/util": "1.11.1",
"@firebase/util": "1.12.0",
"tslib": "^2.1.0"
},
"engines": {
@@ -3000,14 +3003,14 @@
}
},
"node_modules/@firebase/firestore": {
"version": "4.7.12",
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.12.tgz",
"integrity": "sha512-50KRdSp8xA7+G0wfWxlnCoEN951mt8BVdLMxeP57Rehj2DqIb41q6Fc6JH0dfQ4TlMqWua1YfVY1jPEAaHVF9w==",
"version": "4.7.15",
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.15.tgz",
"integrity": "sha512-FgWTmkNBEXdKCoN2ngBNjrMaXuBx6QwjiZZVnOGg+VjUmiBq5gAqlDIW5bZY6i/NYvLUrWugdqIs7y9GHEqwww==",
"license": "Apache-2.0",
"dependencies": {
"@firebase/component": "0.6.14",
"@firebase/component": "0.6.17",
"@firebase/logger": "0.4.4",
"@firebase/util": "1.11.1",
"@firebase/util": "1.12.0",
"@firebase/webchannel-wrapper": "1.0.3",
"@grpc/grpc-js": "~1.9.0",
"@grpc/proto-loader": "^0.7.8",
@@ -3021,13 +3024,13 @@
}
},
"node_modules/@firebase/installations": {
"version": "0.6.14",
"resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.14.tgz",
"integrity": "sha512-uE837g9+sv6PfjWPgOfG3JtjZ+hJ7KBHO4UVenVsvhzgOxFkvLjO/bgE7fyvsaD3fOHSXunx3adRIg4eUEMPyA==",
"version": "0.6.17",
"resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.17.tgz",
"integrity": "sha512-zfhqCNJZRe12KyADtRrtOj+SeSbD1H/K8J24oQAJVv/u02eQajEGlhZtcx9Qk7vhGWF5z9dvIygVDYqLL4o1XQ==",
"license": "Apache-2.0",
"dependencies": {
"@firebase/component": "0.6.14",
"@firebase/util": "1.11.1",
"@firebase/component": "0.6.17",
"@firebase/util": "1.12.0",
"idb": "7.1.1",
"tslib": "^2.1.0"
},
@@ -3048,15 +3051,15 @@
}
},
"node_modules/@firebase/messaging": {
"version": "0.12.18",
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.18.tgz",
"integrity": "sha512-2MGhUGoCZloB7ysoYzG/T2nnRmHYLT+AcqYouZuD6APabpkDhF8lHsmSQq4MFSlXhI3DKFOXxjuvbY8ec4C2JQ==",
"version": "0.12.21",
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.21.tgz",
"integrity": "sha512-bYJ2Evj167Z+lJ1ach6UglXz5dUKY1zrJZd15GagBUJSR7d9KfiM1W8dsyL0lDxcmhmA/sLaBYAAhF1uilwN0g==",
"license": "Apache-2.0",
"dependencies": {
"@firebase/component": "0.6.14",
"@firebase/installations": "0.6.14",
"@firebase/component": "0.6.17",
"@firebase/installations": "0.6.17",
"@firebase/messaging-interop-types": "0.2.3",
"@firebase/util": "1.11.1",
"@firebase/util": "1.12.0",
"idb": "7.1.1",
"tslib": "^2.1.0"
},
@@ -3071,9 +3074,9 @@
"license": "Apache-2.0"
},
"node_modules/@firebase/util": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz",
"integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==",
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.0.tgz",
"integrity": "sha512-Z4rK23xBCwgKDqmzGVMef+Vb4xso2j5Q8OG0vVL4m4fA5ZjPMYQazu8OJJC3vtQRC3SQ/Pgx/6TPNVsCd70QRw==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3836,9 +3839,9 @@
"license": "MIT"
},
"node_modules/@reduxjs/toolkit": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.1.tgz",
"integrity": "sha512-GLjHS13LiBdiuxSJvfWs3+Cx5yt97mCbuVlDteTusS6VRksPhoWviO8L1e3Re1G94m6lkw/l4pjEEyyNaGf19g==",
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.8.2.tgz",
"integrity": "sha512-MYlOhQ0sLdw4ud48FoC5w0dH9VfWQjtCjreKwYTT3l+r427qYC5Y8PihNutepr8XrNaBUDQo9khWUwQxZaqt5A==",
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.0.0",
@@ -4458,50 +4461,50 @@
"license": "MIT"
},
"node_modules/@sentry-internal/browser-utils": {
"version": "9.18.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.18.0.tgz",
"integrity": "sha512-TwSlmgYpHhe55JpOcVApkM0XcXZh1/cYuEPKPFgeaaPD8BrQrLJJvwKxnonSWXOhdnkJxi4GgK7j7mw57PS4aA==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.21.0.tgz",
"integrity": "sha512-/lJ5EVUDbsVsPH/sSXwWBERVtzi4kWYeFLc+u+1zr4NrfDrGnPJ5mVS1VlHwtBmYIIWv8harLP+CReg3nDcXdw==",
"license": "MIT",
"dependencies": {
"@sentry/core": "9.18.0"
"@sentry/core": "9.21.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/feedback": {
"version": "9.18.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.18.0.tgz",
"integrity": "sha512-QlrB8oQK+5bfhbgK6yHF6rLwLNJ9XuGblTc51yVkm4d4jn4W/HDyaNqMfQF+JXdTiFatl8oz2xdKR8kGK8kXyg==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.21.0.tgz",
"integrity": "sha512-Z234NgcWolFpmztCh+9smC6WlO8By5t4KucHNfYSQ0xQYQCxPL5iChj3JpF4dwv+qCYXhDFLQFQbK0U3Px056g==",
"license": "MIT",
"dependencies": {
"@sentry/core": "9.18.0"
"@sentry/core": "9.21.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay": {
"version": "9.18.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.18.0.tgz",
"integrity": "sha512-2A32FFwrlZtdpBruvpcLEfucu6BpyqOk3F4Bo5smM/5q7u0pa7q5d9FSY5l3nwKEAFAoLGv3hcCb+8wxMm50xA==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.21.0.tgz",
"integrity": "sha512-7mq3Bsp8EJa3YTIYgmWfNgJdvbeaAJ6VYsqi0yxR/vNGxY3qH+PLlv+ZOEXI2U0CL6vhqFPbqmxiUOCuAjnpGg==",
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "9.18.0",
"@sentry/core": "9.18.0"
"@sentry-internal/browser-utils": "9.21.0",
"@sentry/core": "9.21.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
"version": "9.18.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.18.0.tgz",
"integrity": "sha512-3DEyQLmHcYgcwJ8n8eMhI6bhhawPuMc2xTT+Az8gXMqCO/X9ZACpipAmhXFjYP9Ptl+w0Vh3nllJw+gXc/DOsg==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.21.0.tgz",
"integrity": "sha512-4tHiNil8qXphaql2YXLGA/wlm0hxaadrh7x8/KErn1iy3vJpn7t/Kka5uug7c2UWhtveS6dgGmqjSkDxM5h9bA==",
"license": "MIT",
"dependencies": {
"@sentry-internal/replay": "9.18.0",
"@sentry/core": "9.18.0"
"@sentry-internal/replay": "9.21.0",
"@sentry/core": "9.21.0"
},
"engines": {
"node": ">=18"
@@ -4517,16 +4520,16 @@
}
},
"node_modules/@sentry/browser": {
"version": "9.18.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.18.0.tgz",
"integrity": "sha512-0SWfp4J2+mH4lZOcHfyIwt9VoGD7yCGQE1cm0BPcLwKnrVQeXHtUXNYNy8HTHSjTGyoFDhEAYelE/tdA3OLcWQ==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.21.0.tgz",
"integrity": "sha512-NF0G104JRP2TZ2hpMHElO4bEEUdBWknKSh2d0SRyGpJFVfOQG3oRHczXWH08A5InA/lNrS9LEdodUhiFue+F3A==",
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "9.18.0",
"@sentry-internal/feedback": "9.18.0",
"@sentry-internal/replay": "9.18.0",
"@sentry-internal/replay-canvas": "9.18.0",
"@sentry/core": "9.18.0"
"@sentry-internal/browser-utils": "9.21.0",
"@sentry-internal/feedback": "9.21.0",
"@sentry-internal/replay": "9.21.0",
"@sentry-internal/replay-canvas": "9.21.0",
"@sentry/core": "9.21.0"
},
"engines": {
"node": ">=18"
@@ -4899,22 +4902,22 @@
}
},
"node_modules/@sentry/core": {
"version": "9.18.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.18.0.tgz",
"integrity": "sha512-kRVH8BqMiaU2FTHYa68zNlAloS43jl4XtIEHkLKVH/7gUtwRmM4Gqj8P7RTrZdO1Lo7ksYnGj+AG05Z09CRbOw==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.21.0.tgz",
"integrity": "sha512-K0a72Evg0fzc52Oe8R8Op5TyUMzORkk4ytt3G24lSnF4hh8NPf0m6VGkEUgQRPj27g2bF6tq9fCNsJILsf1PDA==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry/react": {
"version": "9.18.0",
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.18.0.tgz",
"integrity": "sha512-1cCLYZrZ2gu6H8eE83DC47kLf+pzD1Rim3dDoOEvwt1F5cD3K/DBeIhoHZaXqBeQxuVyHXOOLXSAC/CIuas5Aw==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.21.0.tgz",
"integrity": "sha512-RGbyVo4fS7SX2AjEpdRXDo4C4IYIx0zQcI5bSTgySuhxL0JAxohcuSsNWpx48QkJwK/avtmlmCIPKgbvhF16TQ==",
"license": "MIT",
"dependencies": {
"@sentry/browser": "9.18.0",
"@sentry/core": "9.18.0",
"@sentry/browser": "9.21.0",
"@sentry/core": "9.21.0",
"hoist-non-react-statics": "^3.3.2"
},
"engines": {
@@ -5810,14 +5813,14 @@
}
},
"node_modules/@vitest/expect": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.3.tgz",
"integrity": "sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.4.tgz",
"integrity": "sha512-xkD/ljeliyaClDYqHPNCiJ0plY5YIcM0OlRiZizLhlPmpXWpxnGMyTZXOHFhFeG7w9P5PBeL4IdtJ/HeQwTbQA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "3.1.3",
"@vitest/utils": "3.1.3",
"@vitest/spy": "3.1.4",
"@vitest/utils": "3.1.4",
"chai": "^5.2.0",
"tinyrainbow": "^2.0.0"
},
@@ -5826,13 +5829,13 @@
}
},
"node_modules/@vitest/mocker": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.3.tgz",
"integrity": "sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.4.tgz",
"integrity": "sha512-8IJ3CvwtSw/EFXqWFL8aCMu+YyYXG2WUSrQbViOZkWTKTVicVwZ/YiEZDSqD00kX+v/+W+OnxhNWoeVKorHygA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "3.1.3",
"@vitest/spy": "3.1.4",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.17"
},
@@ -5873,9 +5876,9 @@
}
},
"node_modules/@vitest/pretty-format": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.3.tgz",
"integrity": "sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.4.tgz",
"integrity": "sha512-cqv9H9GvAEoTaoq+cYqUTCGscUjKqlJZC7PRwY5FMySVj5J+xOm1KQcCiYHJOEzOKRUhLH4R2pTwvFlWCEScsg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5886,13 +5889,13 @@
}
},
"node_modules/@vitest/runner": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.3.tgz",
"integrity": "sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.4.tgz",
"integrity": "sha512-djTeF1/vt985I/wpKVFBMWUlk/I7mb5hmD5oP8K9ACRmVXgKTae3TUOtXAEBfslNKPzUQvnKhNd34nnRSYgLNQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/utils": "3.1.3",
"@vitest/utils": "3.1.4",
"pathe": "^2.0.3"
},
"funding": {
@@ -5907,13 +5910,13 @@
"license": "MIT"
},
"node_modules/@vitest/snapshot": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.3.tgz",
"integrity": "sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.4.tgz",
"integrity": "sha512-JPHf68DvuO7vilmvwdPr9TS0SuuIzHvxeaCkxYcCD4jTk67XwL45ZhEHFKIuCm8CYstgI6LZ4XbwD6ANrwMpFg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.1.3",
"@vitest/pretty-format": "3.1.4",
"magic-string": "^0.30.17",
"pathe": "^2.0.3"
},
@@ -5939,9 +5942,9 @@
"license": "MIT"
},
"node_modules/@vitest/spy": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.3.tgz",
"integrity": "sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.4.tgz",
"integrity": "sha512-Xg1bXhu+vtPXIodYN369M86K8shGLouNjoVI78g8iAq2rFoHFdajNvJJ5A/9bPMFcfQqdaCpOgWKEoMQg/s0Yg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5952,13 +5955,13 @@
}
},
"node_modules/@vitest/utils": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.3.tgz",
"integrity": "sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.4.tgz",
"integrity": "sha512-yriMuO1cfFhmiGc8ataN51+9ooHRuURdfAZfwFd3usWynjzpLslZdYnRegTv32qdgtJTsj15FoeZe2g15fY1gg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.1.3",
"@vitest/pretty-format": "3.1.4",
"loupe": "^3.1.3",
"tinyrainbow": "^2.0.0"
},
@@ -6088,9 +6091,9 @@
}
},
"node_modules/antd": {
"version": "5.25.1",
"resolved": "https://registry.npmjs.org/antd/-/antd-5.25.1.tgz",
"integrity": "sha512-4KC7KuPCjr0z3Vuw9DsF+ceqJaPLbuUI3lOX1sY8ix25ceamp+P8yxOmk3Y2JHCD2ZAhq+5IQ/DTJRN2adWYKQ==",
"version": "5.25.2",
"resolved": "https://registry.npmjs.org/antd/-/antd-5.25.2.tgz",
"integrity": "sha512-7R2nUvlHhey7Trx64+hCtGXOiy+DTUs1Lv5bwbV1LzEIZIhWb0at1AM6V3K108a5lyoR9n7DX3ptlLF7uYV/DQ==",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^7.2.0",
@@ -6128,11 +6131,11 @@
"rc-rate": "~2.13.1",
"rc-resize-observer": "^1.4.3",
"rc-segmented": "~2.7.0",
"rc-select": "~14.16.7",
"rc-select": "~14.16.8",
"rc-slider": "~11.1.8",
"rc-steps": "~6.0.1",
"rc-switch": "~4.1.0",
"rc-table": "~7.50.4",
"rc-table": "~7.50.5",
"rc-tabs": "~15.6.1",
"rc-textarea": "~1.10.0",
"rc-tooltip": "~6.4.0",
@@ -11833,9 +11836,9 @@
}
},
"node_modules/memfs": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.1.tgz",
"integrity": "sha512-thuTRd7F4m4dReCIy7vv4eNYnU6XI/tHMLSMMHLiortw/Y0QxqKtinG523U2aerzwYWGi606oBP4oMPy4+edag==",
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz",
"integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -13569,9 +13572,9 @@
}
},
"node_modules/query-string": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-9.1.2.tgz",
"integrity": "sha512-s3UlTyjxRux4KjwWaJsjh1Mp8zoCkSGKirbD9H89pEM9UOZsfpRZpdfzvsy2/mGlLfC3NnYVpy2gk7jXITHEtA==",
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-9.2.0.tgz",
"integrity": "sha512-YIRhrHujoQxhexwRLxfy3VSjOXmvZRd2nyw1PwL1UUqZ/ys1dEZd1+NSgXkne2l/4X/7OXkigEAuhTX0g/ivJQ==",
"license": "MIT",
"dependencies": {
"decode-uri-component": "^0.4.1",
@@ -14024,9 +14027,9 @@
}
},
"node_modules/rc-select": {
"version": "14.16.7",
"resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.16.7.tgz",
"integrity": "sha512-lT9kO5gFHQdJzu9a0btcOtNaJHkhenSl8H5mcpgXN9VIMXP59rnkpbdHmPrteixWs1D5zFOTyoTYX3b7joADIQ==",
"version": "14.16.8",
"resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.16.8.tgz",
"integrity": "sha512-NOV5BZa1wZrsdkKaiK7LHRuo5ZjZYMDxPP6/1+09+FB4KoNi8jcG1ZqLE3AVCxEsYMBe65OBx71wFoHRTP3LRg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.10.1",
@@ -14097,9 +14100,9 @@
}
},
"node_modules/rc-table": {
"version": "7.50.4",
"resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.50.4.tgz",
"integrity": "sha512-Y+YuncnQqoS5e7yHvfvlv8BmCvwDYDX/2VixTBEhkMDk9itS9aBINp4nhzXFKiBP/frG4w0pS9d9Rgisl0T1Bw==",
"version": "7.50.5",
"resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.50.5.tgz",
"integrity": "sha512-FDZu8aolhSYd3v9KOc3lZOVAU77wmRRu44R0Wfb8Oj1dXRUsloFaXMSl6f7yuWZUxArJTli7k8TEOX2mvhDl4A==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.10.1",
@@ -15375,9 +15378,9 @@
"license": "MIT"
},
"node_modules/sass": {
"version": "1.88.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz",
"integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==",
"version": "1.89.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.89.0.tgz",
"integrity": "sha512-ld+kQU8YTdGNjOLfRWBzewJpU5cwEv/h5yyqlSeJcj6Yh8U4TDA9UA5FPicqDz/xgRPWRSYIQNiFks21TbA9KQ==",
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
@@ -17533,9 +17536,9 @@
}
},
"node_modules/vite-node": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.3.tgz",
"integrity": "sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.4.tgz",
"integrity": "sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -17731,19 +17734,19 @@
}
},
"node_modules/vitest": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.3.tgz",
"integrity": "sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.4.tgz",
"integrity": "sha512-Ta56rT7uWxCSJXlBtKgIlApJnT6e6IGmTYxYcmxjJ4ujuZDI59GUQgVDObXXJujOmPDBYXHK1qmaGtneu6TNIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/expect": "3.1.3",
"@vitest/mocker": "3.1.3",
"@vitest/pretty-format": "^3.1.3",
"@vitest/runner": "3.1.3",
"@vitest/snapshot": "3.1.3",
"@vitest/spy": "3.1.3",
"@vitest/utils": "3.1.3",
"@vitest/expect": "3.1.4",
"@vitest/mocker": "3.1.4",
"@vitest/pretty-format": "^3.1.4",
"@vitest/runner": "3.1.4",
"@vitest/snapshot": "3.1.4",
"@vitest/spy": "3.1.4",
"@vitest/utils": "3.1.4",
"chai": "^5.2.0",
"debug": "^4.4.0",
"expect-type": "^1.2.1",
@@ -17756,7 +17759,7 @@
"tinypool": "^1.0.2",
"tinyrainbow": "^2.0.0",
"vite": "^5.0.0 || ^6.0.0",
"vite-node": "3.1.3",
"vite-node": "3.1.4",
"why-is-node-running": "^2.3.0"
},
"bin": {
@@ -17772,8 +17775,8 @@
"@edge-runtime/vm": "*",
"@types/debug": "^4.1.12",
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
"@vitest/browser": "3.1.3",
"@vitest/ui": "3.1.3",
"@vitest/browser": "3.1.4",
"@vitest/ui": "3.1.4",
"happy-dom": "*",
"jsdom": "*"
},

View File

@@ -12,19 +12,19 @@
"@apollo/client": "^3.13.6",
"@emotion/is-prop-valid": "^1.3.1",
"@fingerprintjs/fingerprintjs": "^4.6.1",
"@firebase/analytics": "^0.10.13",
"@firebase/app": "^0.12.1",
"@firebase/auth": "^1.10.2",
"@firebase/firestore": "^4.7.12",
"@firebase/messaging": "^0.12.18",
"@firebase/analytics": "^0.10.16",
"@firebase/app": "^0.13.0",
"@firebase/auth": "^1.10.5",
"@firebase/firestore": "^4.7.15",
"@firebase/messaging": "^0.12.21",
"@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.8.1",
"@reduxjs/toolkit": "^2.8.2",
"@sentry/cli": "^2.45.0",
"@sentry/react": "^9.18.0",
"@sentry/react": "^9.21.0",
"@sentry/vite-plugin": "^3.4.0",
"@splitsoftware/splitio-react": "^2.1.1",
"@tanem/react-nprogress": "^5.0.53",
"antd": "^5.25.1",
"antd": "^5.25.2",
"apollo-link-logger": "^2.0.1",
"apollo-link-sentry": "^4.3.0",
"autosize": "^6.0.1",
@@ -48,7 +48,7 @@
"normalize-url": "^8.0.1",
"object-hash": "^3.0.0",
"prop-types": "^15.8.1",
"query-string": "^9.1.2",
"query-string": "^9.2.0",
"raf-schd": "^4.0.3",
"react": "^18.3.1",
"react-big-calendar": "^1.18.0",
@@ -77,7 +77,7 @@
"redux-saga": "^1.3.0",
"redux-state-sync": "^3.1.4",
"reselect": "^5.1.1",
"sass": "^1.88.0",
"sass": "^1.89.0",
"socket.io-client": "^4.8.1",
"styled-components": "^6.1.18",
"subscriptions-transport-ws": "^0.11.0",
@@ -130,10 +130,10 @@
"@ant-design/icons": "^6.0.0",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-react": "^7.27.1",
"@dotenvx/dotenvx": "^1.44.0",
"@dotenvx/dotenvx": "^1.44.1",
"@emotion/babel-plugin": "^11.13.5",
"@emotion/react": "^11.14.0",
"@eslint/js": "^9.26.0",
"@eslint/js": "^9.27.0",
"@playwright/test": "^1.51.1",
"@sentry/webpack-plugin": "^3.4.0",
"@testing-library/dom": "^10.4.0",
@@ -148,7 +148,7 @@
"eslint-plugin-react": "^7.37.5",
"globals": "^15.15.0",
"jsdom": "^26.0.0",
"memfs": "^4.17.1",
"memfs": "^4.17.2",
"os-browserify": "^0.3.0",
"playwright": "^1.51.1",
"react-error-overlay": "^6.1.0",
@@ -160,7 +160,7 @@
"vite-plugin-node-polyfills": "^0.23.0",
"vite-plugin-pwa": "^1.0.0",
"vite-plugin-style-import": "^2.0.0",
"vitest": "^3.1.3",
"vitest": "^3.1.4",
"workbox-window": "^7.3.0"
}
}

View File

@@ -957,6 +957,7 @@
- enforce_conversion_category
- enforce_conversion_csr
- enforce_referral
- enforce_sms_consent
- entegral_configuration
- entegral_id
- features
@@ -1067,6 +1068,7 @@
- enforce_conversion_category
- enforce_conversion_csr
- enforce_referral
- enforce_sms_consent
- federal_tax_id
- id
- inhousevendorid
@@ -5861,6 +5863,105 @@
template_engine: Kriti
url: '{{$base_url}}/opensearch'
version: 2
- table:
name: phone_number_consent
schema: public
object_relationships:
- name: bodyshop
using:
foreign_key_constraint_on: bodyshopid
array_relationships:
- name: phone_number_consent_histories
using:
foreign_key_constraint_on:
column: phone_number_consent_id
table:
name: phone_number_consent_history
schema: public
insert_permissions:
- role: user
permission:
check:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- consent_status
- phone_number
- consent_updated_at
- created_at
- updated_at
- bodyshopid
- id
comment: ""
select_permissions:
- role: user
permission:
columns:
- consent_status
- phone_number
- consent_updated_at
- created_at
- updated_at
- bodyshopid
- id
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
comment: ""
update_permissions:
- role: user
permission:
columns:
- bodyshopid
- consent_status
- consent_updated_at
- created_at
- phone_number
- updated_at
filter: {}
check: null
comment: ""
- table:
name: phone_number_consent_history
schema: public
object_relationships:
- name: phone_number_consent
using:
foreign_key_constraint_on: phone_number_consent_id
select_permissions:
- role: user
permission:
columns:
- new_value
- old_value
- changed_by
- reason
- changed_at
- id
- phone_number_consent_id
filter:
phone_number_consent:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
comment: ""
- table:
name: phonebook
schema: public

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."bodyshops" add column "enforce_sms_consent" boolean
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."bodyshops" add column "enforce_sms_consent" boolean
null;

View File

@@ -0,0 +1 @@
DROP TABLE "public"."phone_number_consent";

View File

@@ -0,0 +1,2 @@
CREATE TABLE "public"."phone_number_consent" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "bodyshopid" uuid NOT NULL, "phone_number" text NOT NULL, "consent_status" boolean NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "consent_updated_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") , FOREIGN KEY ("bodyshopid") REFERENCES "public"."bodyshops"("id") ON UPDATE restrict ON DELETE restrict, UNIQUE ("id"), UNIQUE ("bodyshopid", "phone_number"));
CREATE EXTENSION IF NOT EXISTS pgcrypto;

View File

@@ -0,0 +1 @@
DROP TABLE "public"."phone_number_consent_history";

View File

@@ -0,0 +1,2 @@
CREATE TABLE "public"."phone_number_consent_history" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "phone_number_consent_id" uuid NOT NULL, "old_value" boolean NOT NULL, "new_value" boolean NOT NULL, "reason" text NOT NULL, "changed_at" timestamptz NOT NULL DEFAULT now(), "changed_by" text NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("phone_number_consent_id") REFERENCES "public"."phone_number_consent"("id") ON UPDATE restrict ON DELETE restrict, UNIQUE ("id"));
CREATE EXTENSION IF NOT EXISTS pgcrypto;

1461
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,14 +16,14 @@
"job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js"
},
"dependencies": {
"@aws-sdk/client-cloudwatch-logs": "^3.808.0",
"@aws-sdk/client-elasticache": "^3.808.0",
"@aws-sdk/client-s3": "^3.808.0",
"@aws-sdk/client-secrets-manager": "^3.808.0",
"@aws-sdk/client-ses": "^3.808.0",
"@aws-sdk/credential-provider-node": "^3.808.0",
"@aws-sdk/lib-storage": "^3.808.0",
"@aws-sdk/s3-request-presigner": "^3.808.0",
"@aws-sdk/client-cloudwatch-logs": "^3.812.0",
"@aws-sdk/client-elasticache": "^3.812.0",
"@aws-sdk/client-s3": "^3.812.0",
"@aws-sdk/client-secrets-manager": "^3.812.0",
"@aws-sdk/client-ses": "^3.812.0",
"@aws-sdk/credential-provider-node": "^3.812.0",
"@aws-sdk/lib-storage": "^3.812.0",
"@aws-sdk/s3-request-presigner": "^3.812.0",
"@opensearch-project/opensearch": "^2.13.0",
"@socket.io/admin-ui": "^0.5.1",
"@socket.io/redis-adapter": "^8.3.0",
@@ -31,14 +31,14 @@
"aws4": "^1.13.2",
"axios": "^1.8.4",
"better-queue": "^3.8.12",
"bullmq": "^5.52.2",
"bullmq": "^5.52.3",
"chart.js": "^4.4.8",
"cloudinary": "^2.6.1",
"compression": "^1.8.0",
"cookie-parser": "^1.4.7",
"cors": "2.8.5",
"cors": "^2.8.5",
"crisp-status-reporter": "^1.2.2",
"dd-trace": "^5.51.0",
"dd-trace": "^5.52.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.5",
"express": "^4.21.1",
@@ -73,14 +73,14 @@
"xmlbuilder2": "^3.1.1"
},
"devDependencies": {
"@eslint/js": "^9.26.0",
"eslint": "^9.26.0",
"@eslint/js": "^9.27.0",
"eslint": "^9.27.0",
"eslint-plugin-react": "^7.37.5",
"globals": "^15.15.0",
"mock-require": "^3.0.3",
"p-limit": "^3.1.0",
"prettier": "^3.5.3",
"supertest": "^7.1.1",
"vitest": "^3.1.3"
"vitest": "^3.1.4"
}
}

View File

@@ -1,16 +1,61 @@
const path = require("path");
require("dotenv").config({
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
});
const client = require("../graphql-client/graphql-client").client;
const queries = require("../graphql-client/queries");
const {
FIND_BODYSHOP_BY_MESSAGING_SERVICE_SID,
UNARCHIVE_CONVERSATION,
CREATE_CONVERSATION,
INSERT_MESSAGE
} = require("../graphql-client/queries");
const { phone } = require("phone");
const { admin } = require("../firebase/firebase-handler");
const logger = require("../utils/logger");
const InstanceManager = require("../utils/instanceMgr").default;
exports.receive = async (req, res) => {
/**
* Generate an array of media URLs from the request body
* @param body
* @returns {null|*[]}
*/
const generateMediaArray = (body) => {
const { NumMedia } = body;
if (parseInt(NumMedia) > 0) {
const ret = [];
for (let i = 0; i < parseInt(NumMedia); i++) {
ret.push(body[`MediaUrl${i}`]);
}
return ret;
} else {
return null;
}
};
/**
* Handle errors during the message receiving process
* @param req
* @param error
* @param res
* @param context
*/
const handleError = (req, error, res, context) => {
logger.log("sms-inbound-error", "ERROR", "api", null, {
msid: req.body.SmsMessageSid,
text: req.body.Body,
image: !!req.body.MediaUrl0,
image_path: generateMediaArray(req.body),
messagingServiceSid: req.body.MessagingServiceSid,
context,
error
});
res.status(500).json({ error: error.message || "Internal Server Error" });
};
/**
* Receive an inbound SMS message
* @param req
* @param res
* @returns {Promise<*>}
*/
const receive = async (req, res) => {
const {
ioRedis,
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom }
@@ -35,7 +80,7 @@ exports.receive = async (req, res) => {
try {
// Step 1: Find the bodyshop and existing conversation
const response = await client.request(queries.FIND_BODYSHOP_BY_MESSAGING_SERVICE_SID, {
const response = await client.request(FIND_BODYSHOP_BY_MESSAGING_SERVICE_SID, {
mssid: req.body.MessagingServiceSid,
phone: phone(req.body.From).phoneNumber
});
@@ -68,14 +113,14 @@ exports.receive = async (req, res) => {
// Unarchive the conversation if necessary
if (existingConversation.archived) {
await client.request(queries.UNARCHIVE_CONVERSATION, {
await client.request(UNARCHIVE_CONVERSATION, {
id: conversationid,
archived: false
});
}
} else {
// Create a new conversation
const newConversationResponse = await client.request(queries.CREATE_CONVERSATION, {
const newConversationResponse = await client.request(CREATE_CONVERSATION, {
conversation: {
bodyshopid: bodyshop.id,
phone_num: phone(req.body.From).phoneNumber,
@@ -90,7 +135,7 @@ exports.receive = async (req, res) => {
newMessage.conversationid = conversationid;
// Step 3: Insert the message into the conversation
const insertresp = await client.request(queries.INSERT_MESSAGE, {
const insertresp = await client.request(INSERT_MESSAGE, {
msg: newMessage,
conversationid: conversationid
});
@@ -137,7 +182,7 @@ exports.receive = async (req, res) => {
notification: {
title: InstanceManager({
imex: `ImEX Online Message - ${message.conversation.phone_num}`,
rome: `Rome Online Message - ${message.conversation.phone_num}`,
rome: `Rome Online Message - ${message.conversation.phone_num}`
}),
body: message.image_path ? `Image ${message.text}` : message.text
},
@@ -161,29 +206,6 @@ exports.receive = async (req, res) => {
}
};
const generateMediaArray = (body) => {
const { NumMedia } = body;
if (parseInt(NumMedia) > 0) {
const ret = [];
for (let i = 0; i < parseInt(NumMedia); i++) {
ret.push(body[`MediaUrl${i}`]);
}
return ret;
} else {
return null;
}
};
const handleError = (req, error, res, context) => {
logger.log("sms-inbound-error", "ERROR", "api", null, {
msid: req.body.SmsMessageSid,
text: req.body.Body,
image: !!req.body.MediaUrl0,
image_path: generateMediaArray(req.body),
messagingServiceSid: req.body.MessagingServiceSid,
context,
error
});
res.status(500).json({ error: error.message || "Internal Server Error" });
module.exports = {
receive
};

View File

@@ -1,16 +1,17 @@
const path = require("path");
require("dotenv").config({
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
});
const twilio = require("twilio");
const { phone } = require("phone");
const queries = require("../graphql-client/queries");
const { INSERT_MESSAGE } = require("../graphql-client/queries");
const logger = require("../utils/logger");
const client = twilio(process.env.TWILIO_AUTH_TOKEN, process.env.TWILIO_AUTH_KEY);
const gqlClient = require("../graphql-client/graphql-client").client;
exports.send = async (req, res) => {
/**
* Send an outbound SMS message
* @param req
* @param res
* @returns {Promise<void>}
*/
const send = async (req, res) => {
const { to, messagingServiceSid, body, conversationid, selectedMedia, imexshopid } = req.body;
const {
ioRedis,
@@ -64,7 +65,10 @@ exports.send = async (req, res) => {
};
try {
const gqlResponse = await gqlClient.request(queries.INSERT_MESSAGE, { msg: newMessage, conversationid });
const gqlResponse = await gqlClient.request(INSERT_MESSAGE, {
msg: newMessage,
conversationid
});
logger.log("sms-outbound-success", "DEBUG", req.user.email, null, {
msid: message.sid,
@@ -111,3 +115,7 @@ exports.send = async (req, res) => {
res.status(500).json({ success: false, message: "Failed to send message through Twilio." });
}
};
module.exports = {
send
};

View File

@@ -1,13 +1,14 @@
const path = require("path");
require("dotenv").config({
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
});
const client = require("../graphql-client/graphql-client").client;
const queries = require("../graphql-client/queries");
const { UPDATE_MESSAGE_STATUS, MARK_MESSAGES_AS_READ } = require("../graphql-client/queries");
const logger = require("../utils/logger");
exports.status = async (req, res) => {
/**
* Handle the status of an SMS message
* @param req
* @param res
* @returns {Promise<*>}
*/
const status = async (req, res) => {
const { SmsSid, SmsStatus } = req.body;
const {
ioRedis,
@@ -21,7 +22,7 @@ exports.status = async (req, res) => {
}
// Update message status in the database
const response = await client.request(queries.UPDATE_MESSAGE_STATUS, {
const response = await client.request(UPDATE_MESSAGE_STATUS, {
msid: SmsSid,
fields: { status: SmsStatus }
});
@@ -65,7 +66,13 @@ exports.status = async (req, res) => {
}
};
exports.markConversationRead = async (req, res) => {
/**
* Mark a conversation as read
* @param req
* @param res
* @returns {Promise<*>}
*/
const markConversationRead = async (req, res) => {
const {
ioRedis,
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom }
@@ -80,7 +87,7 @@ exports.markConversationRead = async (req, res) => {
}
try {
const response = await client.request(queries.MARK_MESSAGES_AS_READ, {
const response = await client.request(MARK_MESSAGES_AS_READ, {
conversationId
});
@@ -104,3 +111,8 @@ exports.markConversationRead = async (req, res) => {
res.status(500).json({ error: "Failed to mark conversation as read." });
}
};
module.exports = {
status,
markConversationRead
};

View File

@@ -1,3 +1,11 @@
/**
* @module ioHelpers
* @param app
* @param api
* @param io
* @param logger
* @returns {{getBodyshopRoom: (function(*): string), getBodyshopConversationRoom: (function({bodyshopId: *, conversationId: *}): string)}}
*/
const applyIOHelpers = ({ app, api, io, logger }) => {
// Global Bodyshop Room
const getBodyshopRoom = (bodyshopId) => `bodyshop-broadcast-room:${bodyshopId}`;