From 6d861943f06af777c8a9b55443b22e5abe515ec0 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 14:12:06 -0600 Subject: [PATCH 01/17] Add @parameter1/omeda-graphql-client --- packages/marko-web-omeda/package.json | 6 +++++- yarn.lock | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/marko-web-omeda/package.json b/packages/marko-web-omeda/package.json index e4d7d92b0..24d555d65 100644 --- a/packages/marko-web-omeda/package.json +++ b/packages/marko-web-omeda/package.json @@ -11,7 +11,11 @@ "test": "yarn compile && yarn lint" }, "dependencies": { - "@parameter1/base-cms-marko-web-deferred-script-loader": "^2.48.1" + "@parameter1/base-cms-marko-web-deferred-script-loader": "^2.48.1", + "@parameter1/base-cms-utils": "^2.22.2", + "@parameter1/omeda-graphql-client": "^0.7.0", + "graphql": "^14.7.0", + "graphql-tag": "^2.12.5" }, "peerDependencies": { "@parameter1/base-cms-marko-web": "^2.0.0" diff --git a/yarn.lock b/yarn.lock index 5feb2677d..ce8190100 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3085,6 +3085,17 @@ dependencies: joi "^17.4.2" +"@parameter1/omeda-graphql-client@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@parameter1/omeda-graphql-client/-/omeda-graphql-client-0.7.0.tgz#d2d7e5a640565494680287f1b5e60b495776b547" + integrity sha512-1BZUfMyv8LDBZOlD57awctPNX8c0EzsM3Us16+Z5uF/hOg7l+VkyTyIeO/fTgxzGtbr+TkbgbO6CERuF4K92sQ== + dependencies: + apollo-cache-inmemory "^1.6.6" + apollo-client "^2.6.10" + apollo-link-http "^1.5.17" + graphql "^15.6.1" + node-fetch "^2.6.5" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -10110,6 +10121,11 @@ graphql@^14.5.4, graphql@^14.7.0: dependencies: iterall "^1.2.2" +graphql@^15.6.1: + version "15.7.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.7.2.tgz#85ab0eeb83722977151b3feb4d631b5f2ab287ef" + integrity sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" From d00866f5b641b1f4b2b66f0d6639661a7799feec Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 14:12:44 -0600 Subject: [PATCH 02/17] Create generic rapid ident function & middleware --- .../middleware/rapid-identify.js | 21 +++++++++ packages/marko-web-omeda/rapid-identify.js | 47 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 packages/marko-web-omeda/middleware/rapid-identify.js create mode 100644 packages/marko-web-omeda/rapid-identify.js diff --git a/packages/marko-web-omeda/middleware/rapid-identify.js b/packages/marko-web-omeda/middleware/rapid-identify.js new file mode 100644 index 000000000..6b965f478 --- /dev/null +++ b/packages/marko-web-omeda/middleware/rapid-identify.js @@ -0,0 +1,21 @@ +const rapidIdentify = require('../rapid-identify'); + +module.exports = ({ + productId, + prop = '$omedaRapidIdentify', + graphqlProp = '$omedaGraphQLClient', +} = {}) => { + if (!productId) throw new Error('No Omeda rapid identification product ID was provided.'); + return (req, res, next) => { + const omedaGraphQLClient = req[graphqlProp]; + if (!omedaGraphQLClient) throw new Error(`Unable to find the Omeda GraphQL client on the request using ${graphqlProp}`); + const handler = (params = {}) => rapidIdentify(omedaGraphQLClient, { + productId, + ...params, + }); + + req[prop] = handler; + res.locals[prop] = handler; + next(); + }; +}; diff --git a/packages/marko-web-omeda/rapid-identify.js b/packages/marko-web-omeda/rapid-identify.js new file mode 100644 index 000000000..41352cc08 --- /dev/null +++ b/packages/marko-web-omeda/rapid-identify.js @@ -0,0 +1,47 @@ +const gql = require('graphql-tag'); + +const RAPID_IDENT = gql` + mutation RapidIdentityX($input: RapidCustomerIdentificationMutationInput!) { + result: rapidCustomerIdentification(input: $input) { id encryptedCustomerId } + } +`; + +const { isArray } = Array; + +module.exports = async (omedaGraphQLClient, { + email, + productId, + + firstName, + lastName, + companyName, + title, + + regionCode, + countryCode, + postalCode, + + deploymentTypeIds, + demographics, +} = {}) => { + const input = { + productId, + email, + ...(firstName && { firstName }), + ...(lastName && { lastName }), + ...(companyName && { companyName }), + ...(title && { title }), + + ...(regionCode && { regionCode }), + ...(countryCode && { countryCode }), + ...(postalCode && { postalCode }), + + ...(isArray(deploymentTypeIds) && deploymentTypeIds.length && { deploymentTypeIds }), + ...(isArray(demographics) && demographics.length && { demographics }), + }; + const { data } = await omedaGraphQLClient.mutate({ + mutation: RAPID_IDENT, + variables: { input }, + }); + return data.result; +}; From aad05f79de6e4dfd5122fb0f58a41c14fa5fc20b Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 14:12:53 -0600 Subject: [PATCH 03/17] Create omeda graphql client middleware --- .../middleware/graphql-client.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 packages/marko-web-omeda/middleware/graphql-client.js diff --git a/packages/marko-web-omeda/middleware/graphql-client.js b/packages/marko-web-omeda/middleware/graphql-client.js new file mode 100644 index 000000000..7e04b5799 --- /dev/null +++ b/packages/marko-web-omeda/middleware/graphql-client.js @@ -0,0 +1,32 @@ +const createClient = require('@parameter1/omeda-graphql-client'); + +module.exports = ({ + uri = 'https://graphql.omeda.parameter1.com/', + brandKey, + clientKey, + appId, + inputId, + + config = {}, + linkConfig = {}, + prop = '$omedaGraphQLClient', +} = {}) => { + if (!uri) throw new Error('The Omeda GraphQL `uri` is required.'); + if (!brandKey) throw new Error('The Omeda `brandKey` is required.'); + if (!appId) throw new Error('The Omeda `appId` is required.'); + if (!prop) throw new Error('The middleware request property is required.'); + return (req, res, next) => { + const client = createClient({ + uri, + brandKey, + clientKey, + appId, + inputId, + config, + linkConfig, + }); + req[prop] = client; + res.locals[prop] = client; + next(); + }; +}; From aa1e1286eb6c446aea16ae1c285f585dd6fd4596 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 14:13:03 -0600 Subject: [PATCH 04/17] Create middleware installer --- packages/marko-web-omeda/middleware/index.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 packages/marko-web-omeda/middleware/index.js diff --git a/packages/marko-web-omeda/middleware/index.js b/packages/marko-web-omeda/middleware/index.js new file mode 100644 index 000000000..c6ad4899f --- /dev/null +++ b/packages/marko-web-omeda/middleware/index.js @@ -0,0 +1,19 @@ +const graphqlClient = require('./graphql-client'); +const rapidIdentify = require('./rapid-identify'); + +module.exports = (app, { + brandKey, + clientKey, + appId, + inputId, + + rapidIdentProductId, +} = {}) => { + app.use(graphqlClient({ + brandKey, + clientKey, + appId, + inputId, + })); + app.use(rapidIdentify({ productId: rapidIdentProductId })); +}; From a5666f38df345d2517b45a3d63ffe17969291ea4 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 14:14:26 -0600 Subject: [PATCH 05/17] Set identity-x as a direct dependency --- packages/marko-web-omeda-identity-x/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/marko-web-omeda-identity-x/package.json b/packages/marko-web-omeda-identity-x/package.json index 83660b5b0..44d327ef4 100644 --- a/packages/marko-web-omeda-identity-x/package.json +++ b/packages/marko-web-omeda-identity-x/package.json @@ -11,6 +11,7 @@ "test": "yarn compile && yarn lint" }, "dependencies": { + "@parameter1/base-cms-marko-web-identity-x": "^2.53.1", "@parameter1/base-cms-marko-web-omeda": "^2.52.0", "@parameter1/base-cms-object-path": "^2.45.0", "@parameter1/base-cms-utils": "^2.22.2", @@ -19,7 +20,6 @@ }, "peerDependencies": { "@parameter1/base-cms-marko-web": "^2.13.0", - "@parameter1/base-cms-marko-web-identity-x": "^2.16.0", "express": "^4.17.1" }, "publishConfig": { From 50aea4228d9b4459cae2af63e3c2e996d4d7c8db Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:05:13 -0600 Subject: [PATCH 06/17] Change graphql client prop key --- packages/marko-web-omeda/middleware/rapid-identify.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/marko-web-omeda/middleware/rapid-identify.js b/packages/marko-web-omeda/middleware/rapid-identify.js index 6b965f478..53ccbee72 100644 --- a/packages/marko-web-omeda/middleware/rapid-identify.js +++ b/packages/marko-web-omeda/middleware/rapid-identify.js @@ -3,13 +3,13 @@ const rapidIdentify = require('../rapid-identify'); module.exports = ({ productId, prop = '$omedaRapidIdentify', - graphqlProp = '$omedaGraphQLClient', + omedaGraphQLClientProp = '$omedaGraphQLClient', } = {}) => { if (!productId) throw new Error('No Omeda rapid identification product ID was provided.'); return (req, res, next) => { - const omedaGraphQLClient = req[graphqlProp]; - if (!omedaGraphQLClient) throw new Error(`Unable to find the Omeda GraphQL client on the request using ${graphqlProp}`); - const handler = (params = {}) => rapidIdentify(omedaGraphQLClient, { + const omedaGraphQLClient = req[omedaGraphQLClientProp]; + if (!omedaGraphQLClient) throw new Error(`Unable to find the Omeda GraphQL client on the request using ${omedaGraphQLClientProp}`); + const handler = async (params = {}) => rapidIdentify(omedaGraphQLClient, { productId, ...params, }); From e27684a875837d0b7ddc81d94012b2005bfe9451 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:05:23 -0600 Subject: [PATCH 07/17] Move installation of middlewares to root export --- packages/marko-web-omeda/index.js | 25 +++++++++++++++++++- packages/marko-web-omeda/middleware/index.js | 17 +------------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/packages/marko-web-omeda/index.js b/packages/marko-web-omeda/index.js index f053ebf79..fdf7be064 100644 --- a/packages/marko-web-omeda/index.js +++ b/packages/marko-web-omeda/index.js @@ -1 +1,24 @@ -module.exports = {}; +const { graphqlClient, rapidIdentify } = require('./middleware'); + +module.exports = (app, { + brandKey, + clientKey, + appId, + inputId, + rapidIdentProductId, + omedaGraphQLClientProp = '$omedaGraphQLClient', + omedaRapidIdentifyProp = '$omedaRapidIdentify', +} = {}) => { + app.use(graphqlClient({ + brandKey, + clientKey, + appId, + inputId, + prop: omedaGraphQLClientProp, + })); + app.use(rapidIdentify({ + productId: rapidIdentProductId, + omedaGraphQLClientProp, + prop: omedaRapidIdentifyProp, + })); +}; diff --git a/packages/marko-web-omeda/middleware/index.js b/packages/marko-web-omeda/middleware/index.js index c6ad4899f..d165f15e1 100644 --- a/packages/marko-web-omeda/middleware/index.js +++ b/packages/marko-web-omeda/middleware/index.js @@ -1,19 +1,4 @@ const graphqlClient = require('./graphql-client'); const rapidIdentify = require('./rapid-identify'); -module.exports = (app, { - brandKey, - clientKey, - appId, - inputId, - - rapidIdentProductId, -} = {}) => { - app.use(graphqlClient({ - brandKey, - clientKey, - appId, - inputId, - })); - app.use(rapidIdentify({ productId: rapidIdentProductId })); -}; +module.exports = { graphqlClient, rapidIdentify }; From a8c4c625615c432af8f3f87f1756662474fc1169 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:06:14 -0600 Subject: [PATCH 08/17] Cross-integrate identity-x + omeda via middlewares --- .../add-integration-hooks.js | 18 +++---- packages/marko-web-omeda-identity-x/index.js | 52 +++++++++++++++++++ .../integration-hooks/on-login-link-sent.js | 43 +++++++-------- .../on-user-profile-update.js | 22 ++------ .../middleware/rapid-identify.js | 30 +++++++++++ .../rapid-identify.js | 20 ++----- 6 files changed, 118 insertions(+), 67 deletions(-) create mode 100644 packages/marko-web-omeda-identity-x/index.js create mode 100644 packages/marko-web-omeda-identity-x/middleware/rapid-identify.js diff --git a/packages/marko-web-omeda-identity-x/add-integration-hooks.js b/packages/marko-web-omeda-identity-x/add-integration-hooks.js index 8e53612e8..b9cc5b9da 100644 --- a/packages/marko-web-omeda-identity-x/add-integration-hooks.js +++ b/packages/marko-web-omeda-identity-x/add-integration-hooks.js @@ -14,19 +14,17 @@ const { module.exports = ({ idxConfig, brandKey, - productId, - omedaGraphQLProp = '$omeda', + omedaGraphQLProp = '$omedaGraphQLClient', + idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify', } = {}) => { if (!idxConfig) throw new Error('The IdentityX configuration instances is required to add Omeda+IdentityX integration hooks.'); - if (!brandKey) throw new Error('An Omeda brand key is required to add Omeda+IdentityX integration hooks.'); - if (!productId) throw new Error('An Omeda rapid identification product ID is required to add Omeda+IdentityX integration hooks.'); idxConfig.addHook({ name: 'onLoginLinkSent', shouldAwait: false, fn: async ({ req, service, user }) => onLoginLinkSent({ brandKey, - productId, omedaGraphQLProp, + idxOmedaRapidIdentifyProp, req, service, @@ -43,14 +41,10 @@ module.exports = ({ idxConfig.addHook({ name: 'onUserProfileUpdate', shouldAwait: false, - fn: async ({ user, service, req }) => onUserProfileUpdate({ - brandKey, - productId, - omedaGraphQLProp, - - user, - service, + fn: async ({ user, req }) => onUserProfileUpdate({ + idxOmedaRapidIdentifyProp, req, + user, }), }); diff --git a/packages/marko-web-omeda-identity-x/index.js b/packages/marko-web-omeda-identity-x/index.js new file mode 100644 index 000000000..3725df75b --- /dev/null +++ b/packages/marko-web-omeda-identity-x/index.js @@ -0,0 +1,52 @@ +const omeda = require('@parameter1/base-cms-marko-web-omeda'); +const identityX = require('@parameter1/base-cms-marko-web-identity-x'); +const addOmedaHooksToConfig = require('./add-integration-hooks'); +const stripOlyticsParam = require('./middleware/strip-olytics-param'); +const rapidIdentify = require('./middleware/rapid-identify'); + +module.exports = (app, { + brandKey, + clientKey, + appId, + inputId, + + rapidIdentProductId, + omedaGraphQLClientProp = '$omedaGraphQLClient', + omedaRapidIdentifyProp = '$omedaRapidIdentify', + + idxConfig, + idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify', +} = {}) => { + // install omeda middleware + omeda(app, { + brandKey, + clientKey, + appId, + inputId, + rapidIdentProductId, + omedaGraphQLClientProp, + omedaRapidIdentifyProp, + }); + + // add appropiate identity-x to omeda integration hooks + addOmedaHooksToConfig({ + idxConfig, + brandKey, + productId: rapidIdentProductId, + omedaGraphQLProp: omedaGraphQLClientProp, + }); + + // install identity x + identityX(app, idxConfig); + + // attach the identity-x rapid identification wrapper middleware + app.use(rapidIdentify({ + brandKey, + productId: rapidIdentProductId, + prop: idxOmedaRapidIdentifyProp, + omedaRapidIdentifyProp, + })); + + // strip `oly_enc_id` when identity-x user is logged-in + app.use(stripOlyticsParam()); +}; diff --git a/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js b/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js index 10631e808..50f825048 100644 --- a/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js +++ b/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js @@ -1,7 +1,6 @@ const gql = require('graphql-tag'); const { get, getAsArray } = require('@parameter1/base-cms-object-path'); const isOmedaDemographicId = require('../external-id/is-demographic-id'); -const rapidIdentify = require('../rapid-identify'); const FIELD_QUERY = gql` query GetCustomFields { @@ -58,13 +57,13 @@ const SET_OMEDA_DEMOGRAPHIC_DATA = gql` } `; -const getOmedaCustomerRecord = async (omedaGraphQL, encryptedCustomerId) => { +const getOmedaCustomerRecord = async (omedaGraphQLClient, encryptedCustomerId) => { const variables = { id: encryptedCustomerId }; - const { data } = await omedaGraphQL.query({ query: CUSTOMER_QUERY, variables }); + const { data } = await omedaGraphQLClient.query({ query: CUSTOMER_QUERY, variables }); return data.customerByEncryptedId; }; -const setOmedaData = async ({ service, user, omedaCustomer }) => { +const setOmedaData = async ({ identityX, user, omedaCustomer }) => { const input = { email: user.email, @@ -77,14 +76,14 @@ const setOmedaData = async ({ service, user, omedaCustomer }) => { regionCode: get(omedaCustomer, 'primaryPostalAddress.regionCode'), postalCode: get(omedaCustomer, 'primaryPostalAddress.postalCode'), }; - return service.client.mutate({ + return identityX.client.mutate({ mutation: SET_OMEDA_DATA, variables: { input }, }); }; const setOmedaDemographics = async ({ - service, + identityX, user, omedaCustomer, omedaLinkedFields, @@ -118,35 +117,33 @@ const setOmedaDemographics = async ({ answerMap.forEach((optionIdSet, fieldId) => { answers.push({ fieldId, optionIds: [...optionIdSet] }); }); - await service.client.mutate({ + await identityX.client.mutate({ mutation: SET_OMEDA_DEMOGRAPHIC_DATA, variables: { input: { id: user.id, answers } }, - context: { apiToken: service.config.getApiToken() }, + context: { apiToken: identityX.config.getApiToken() }, }); } }; module.exports = async ({ brandKey, - productId, - omedaGraphQLProp = '$omeda', + omedaGraphQLProp = '$omedaGraphQLClient', + idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify', req, - service, + service: identityX, user, }) => { - const omedaGraphQL = req[omedaGraphQLProp]; - if (!omedaGraphQL) throw new Error(`Unable to load the Omeda GraphQL API from the request using prop ${omedaGraphQLProp}`); + const omedaGraphQLClient = req[omedaGraphQLProp]; + if (!omedaGraphQLClient) throw new Error(`Unable to load the Omeda GraphQL API from the request using prop ${omedaGraphQLProp}`); + const idxRapidIdentify = req[idxOmedaRapidIdentifyProp]; + if (!idxRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`); // get omeda customer id (via rapid identity) and load omeda custom field data const [{ data }, { encryptedCustomerId }] = await Promise.all([ - service.client.query({ query: FIELD_QUERY }), - rapidIdentify({ - brandKey, - productId, - appUser: user.verified ? user : { id: user.id, email: user.email }, - identityX: service, - omedaGraphQL, + identityX.client.query({ query: FIELD_QUERY }), + idxRapidIdentify({ + user: user.verified ? user : { id: user.id, email: user.email }, }), ]); @@ -170,12 +167,12 @@ module.exports = async ({ } // find the omeda customer record to "prime" the identity-x user. - const omedaCustomer = await getOmedaCustomerRecord(omedaGraphQL, encryptedCustomerId); + const omedaCustomer = await getOmedaCustomerRecord(omedaGraphQLClient, encryptedCustomerId); const promises = []; - if (!user.verified) promises.push(setOmedaData({ service, user, omedaCustomer })); + if (!user.verified) promises.push(setOmedaData({ identityX, user, omedaCustomer })); if (!hasAnsweredAllOmedaQuestions) { promises.push(setOmedaDemographics({ - service, + identityX, user, omedaCustomer, omedaLinkedFields, diff --git a/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js b/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js index 3e907cde6..f9b845a5d 100644 --- a/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js +++ b/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js @@ -1,21 +1,9 @@ -const rapidIdentify = require('../rapid-identify'); - module.exports = async ({ - brandKey, - productId, - omedaGraphQLProp = '$omeda', - - user, - service, + idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify', req, + user, }) => { - const omedaGraphQL = req[omedaGraphQLProp]; - if (!omedaGraphQL) throw new Error(`Unable to load the Omeda GraphQL API from the request using prop ${omedaGraphQLProp}`); - return rapidIdentify({ - brandKey, - productId, - appUser: user, - identityX: service, - omedaGraphQL, - }); + const idxRapidIdentify = req[idxOmedaRapidIdentifyProp]; + if (!idxRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`); + return idxRapidIdentify({ user }); }; diff --git a/packages/marko-web-omeda-identity-x/middleware/rapid-identify.js b/packages/marko-web-omeda-identity-x/middleware/rapid-identify.js new file mode 100644 index 000000000..30c78b243 --- /dev/null +++ b/packages/marko-web-omeda-identity-x/middleware/rapid-identify.js @@ -0,0 +1,30 @@ +const idxRapidIdentify = require('../rapid-identify'); + +module.exports = ({ + brandKey, + productId, + + prop = '$idxOmedaRapidIdentify', + omedaRapidIdentifyProp = '$omedaRapidIdentify', +}) => { + if (!prop) throw new Error('An Omeda + IdentityX rapid identifcation prop is required.'); + if (!omedaRapidIdentifyProp) throw new Error('The Omeda rapid identifcation prop is required.'); + + return (req, res, next) => { + const rapidIdentify = req[omedaRapidIdentifyProp]; + if (!rapidIdentify) throw new Error(`Unable to find the Omeda rapid identifier on the request using ${omedaRapidIdentifyProp}`); + + const handler = async ({ user } = {}) => idxRapidIdentify({ + brandKey, + productId, + appUser: user, + + identityX: req.identityX, + rapidIdentify, + }); + + req[prop] = handler; + res.locals[prop] = handler; + next(); + }; +}; diff --git a/packages/marko-web-omeda-identity-x/rapid-identify.js b/packages/marko-web-omeda-identity-x/rapid-identify.js index 72eac495c..c68fd156b 100644 --- a/packages/marko-web-omeda-identity-x/rapid-identify.js +++ b/packages/marko-web-omeda-identity-x/rapid-identify.js @@ -8,12 +8,6 @@ const ALPHA3_CODE = gql` } `; -const RAPID_IDENT = gql` - mutation RapidIdentityX($input: RapidCustomerIdentificationMutationInput!) { - result: rapidCustomerIdentification(input: $input) { id encryptedCustomerId } - } -`; - const getAlpha3CodeFor = async (alpha2, identityX) => { const { data } = await identityX.client.query({ query: ALPHA3_CODE, @@ -29,14 +23,15 @@ const getAlpha3CodeFor = async (alpha2, identityX) => { * @param {number} params.productId The Omeda product ID to associate with the identification * @param {object} params.appUser The IdentityX user * @param {IdentityX} params.identityX The Marko web IdentityX service - * @param {ApolloClient} params.omedaGraphQL The Omeda GraphQL client + * @param {function} params.rapidIdentify The Omeda rapid identifcation action */ module.exports = async ({ brandKey, productId, appUser, + identityX, - omedaGraphQL, + rapidIdentify, } = {}) => { const { givenName, @@ -68,9 +63,9 @@ module.exports = async ({ }; }); - const input = { - productId, + const { id, encryptedCustomerId } = await rapidIdentify({ email: appUser.email, + productId, ...(givenName && { firstName: givenName }), ...(familyName && { lastName: familyName }), ...(organization && { companyName: organization }), @@ -79,12 +74,7 @@ module.exports = async ({ ...(regionCode && { regionCode }), ...(postalCode && { postalCode }), ...(demographics.length && { demographics }), - }; - const { data } = await omedaGraphQL.mutate({ - mutation: RAPID_IDENT, - variables: { input }, }); - const { id, encryptedCustomerId } = data.result; const namespace = { provider: 'omeda', tenant: brandKey.toLowerCase(), type: 'customer' }; await Promise.all([ From b090eeb8e8b20524185df83df50feb0bcb5b1dc3 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:23:41 -0600 Subject: [PATCH 09/17] More clearly name the rapid identify variables --- .../integration-hooks/on-user-profile-update.js | 6 +++--- .../middleware/rapid-identify.js | 10 +++++----- packages/marko-web-omeda-identity-x/rapid-identify.js | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js b/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js index f9b845a5d..5d48f9330 100644 --- a/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js +++ b/packages/marko-web-omeda-identity-x/integration-hooks/on-user-profile-update.js @@ -3,7 +3,7 @@ module.exports = async ({ req, user, }) => { - const idxRapidIdentify = req[idxOmedaRapidIdentifyProp]; - if (!idxRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`); - return idxRapidIdentify({ user }); + const idxOmedaRapidIdentify = req[idxOmedaRapidIdentifyProp]; + if (!idxOmedaRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`); + return idxOmedaRapidIdentify({ user }); }; diff --git a/packages/marko-web-omeda-identity-x/middleware/rapid-identify.js b/packages/marko-web-omeda-identity-x/middleware/rapid-identify.js index 30c78b243..299b36a24 100644 --- a/packages/marko-web-omeda-identity-x/middleware/rapid-identify.js +++ b/packages/marko-web-omeda-identity-x/middleware/rapid-identify.js @@ -1,4 +1,4 @@ -const idxRapidIdentify = require('../rapid-identify'); +const idxOmedaRapidIdentify = require('../rapid-identify'); module.exports = ({ brandKey, @@ -11,16 +11,16 @@ module.exports = ({ if (!omedaRapidIdentifyProp) throw new Error('The Omeda rapid identifcation prop is required.'); return (req, res, next) => { - const rapidIdentify = req[omedaRapidIdentifyProp]; - if (!rapidIdentify) throw new Error(`Unable to find the Omeda rapid identifier on the request using ${omedaRapidIdentifyProp}`); + const omedaRapidIdentify = req[omedaRapidIdentifyProp]; + if (!omedaRapidIdentify) throw new Error(`Unable to find the Omeda rapid identifier on the request using ${omedaRapidIdentifyProp}`); - const handler = async ({ user } = {}) => idxRapidIdentify({ + const handler = async ({ user } = {}) => idxOmedaRapidIdentify({ brandKey, productId, appUser: user, identityX: req.identityX, - rapidIdentify, + omedaRapidIdentify, }); req[prop] = handler; diff --git a/packages/marko-web-omeda-identity-x/rapid-identify.js b/packages/marko-web-omeda-identity-x/rapid-identify.js index c68fd156b..d1a2b4ad9 100644 --- a/packages/marko-web-omeda-identity-x/rapid-identify.js +++ b/packages/marko-web-omeda-identity-x/rapid-identify.js @@ -23,7 +23,7 @@ const getAlpha3CodeFor = async (alpha2, identityX) => { * @param {number} params.productId The Omeda product ID to associate with the identification * @param {object} params.appUser The IdentityX user * @param {IdentityX} params.identityX The Marko web IdentityX service - * @param {function} params.rapidIdentify The Omeda rapid identifcation action + * @param {function} params.omedaRapidIdentify The Omeda rapid identifcation action */ module.exports = async ({ brandKey, @@ -31,7 +31,7 @@ module.exports = async ({ appUser, identityX, - rapidIdentify, + omedaRapidIdentify, } = {}) => { const { givenName, @@ -63,7 +63,7 @@ module.exports = async ({ }; }); - const { id, encryptedCustomerId } = await rapidIdentify({ + const { id, encryptedCustomerId } = await omedaRapidIdentify({ email: appUser.email, productId, ...(givenName && { firstName: givenName }), From 7d95091bfc01a883ca8d350e16a97538eb3fe28e Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:24:01 -0600 Subject: [PATCH 10/17] Install the rapid identify ajax route --- packages/marko-web-omeda-identity-x/index.js | 6 +++++ .../routes/rapid-identify.js | 22 +++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/marko-web-omeda-identity-x/index.js b/packages/marko-web-omeda-identity-x/index.js index 3725df75b..b510520f0 100644 --- a/packages/marko-web-omeda-identity-x/index.js +++ b/packages/marko-web-omeda-identity-x/index.js @@ -47,6 +47,12 @@ module.exports = (app, { omedaRapidIdentifyProp, })); + // register the rapid identify AJAX route + app.use('/__idx/omeda-rapid-ident', rapidIdentify({ + brandKey, + idxOmedaRapidIdentifyProp, + })); + // strip `oly_enc_id` when identity-x user is logged-in app.use(stripOlyticsParam()); }; diff --git a/packages/marko-web-omeda-identity-x/routes/rapid-identify.js b/packages/marko-web-omeda-identity-x/routes/rapid-identify.js index 072d1e63f..82d12795d 100644 --- a/packages/marko-web-omeda-identity-x/routes/rapid-identify.js +++ b/packages/marko-web-omeda-identity-x/routes/rapid-identify.js @@ -6,14 +6,18 @@ const jsonErrorHandler = require('@parameter1/base-cms-marko-web/express/json-er const tokenCookie = require('@parameter1/base-cms-marko-web-identity-x/utils/token-cookie'); const olyticsCookie = require('@parameter1/base-cms-marko-web-omeda/olytics/customer-cookie'); -const omedaRapidIdentityX = require('../rapid-identify'); const findEncryptedId = require('../external-id/find-encrypted-customer-id'); -module.exports = ({ brandKey, productId } = {}) => { +module.exports = ({ + brandKey, + idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify', +} = {}) => { if (!brandKey) throw new Error('An Omeda brand key is required to use this middleware.'); - if (!productId) throw new Error('An Omeda rapid identification product ID is required to use this middleware.'); const router = Router(); router.get('/', asyncRoute(async (req, res) => { + const idxOmedaRapidIdentify = req[idxOmedaRapidIdentifyProp]; + if (!idxOmedaRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`); + const data = { userId: null, encryptedId: null, @@ -25,8 +29,8 @@ module.exports = ({ brandKey, productId } = {}) => { if (!idxUserExists) return res.json(data); - const { identityX } = req; - const context = await identityX.loadActiveContext(); + // const { identityX } = req; + const context = await req.identityX.loadActiveContext(); const user = getAsObject(context, 'user'); if (!user.id) return res.json(data); data.userId = user.id; @@ -38,13 +42,7 @@ module.exports = ({ brandKey, productId } = {}) => { data.source = 'existing'; } else { // no omeda identifier found for this user, rapidly identify. - const { encryptedCustomerId } = await omedaRapidIdentityX({ - brandKey, - productId, - appUser: user, - identityX, - omedaGraphQL: req.$omeda, - }); + const { encryptedCustomerId } = await idxOmedaRapidIdentify({ user }); data.encryptedId = encryptedCustomerId; data.source = 'new'; } From 96ebff25c071cb9aea9477989e1072cce53d4cec Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:24:18 -0600 Subject: [PATCH 11/17] Lowercase brand key and check for required variables --- packages/marko-web-omeda-identity-x/index.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/marko-web-omeda-identity-x/index.js b/packages/marko-web-omeda-identity-x/index.js index b510520f0..3594681f6 100644 --- a/packages/marko-web-omeda-identity-x/index.js +++ b/packages/marko-web-omeda-identity-x/index.js @@ -5,7 +5,7 @@ const stripOlyticsParam = require('./middleware/strip-olytics-param'); const rapidIdentify = require('./middleware/rapid-identify'); module.exports = (app, { - brandKey, + brandKey: brand, clientKey, appId, inputId, @@ -17,6 +17,13 @@ module.exports = (app, { idxConfig, idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify', } = {}) => { + if (!brand) throw new Error('The Omeda `brandKey` is required.'); + if (!appId) throw new Error('The Omeda `appId` is required.'); + if (!rapidIdentProductId) throw new Error('The Omeda `rapidIdentProductId` is required.'); + + // consistently pass brand key + const brandKey = brand.trim().toLowerCase(); + // install omeda middleware omeda(app, { brandKey, From 9c4b9a2cc5737a1c6883fff025c59dd6585296a3 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:25:57 -0600 Subject: [PATCH 12/17] Rename integration hooks var --- packages/marko-web-omeda-identity-x/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/marko-web-omeda-identity-x/index.js b/packages/marko-web-omeda-identity-x/index.js index 3594681f6..5bcf74f92 100644 --- a/packages/marko-web-omeda-identity-x/index.js +++ b/packages/marko-web-omeda-identity-x/index.js @@ -1,6 +1,6 @@ const omeda = require('@parameter1/base-cms-marko-web-omeda'); const identityX = require('@parameter1/base-cms-marko-web-identity-x'); -const addOmedaHooksToConfig = require('./add-integration-hooks'); +const addOmedaHooksToIdentityXConfig = require('./add-integration-hooks'); const stripOlyticsParam = require('./middleware/strip-olytics-param'); const rapidIdentify = require('./middleware/rapid-identify'); @@ -36,7 +36,7 @@ module.exports = (app, { }); // add appropiate identity-x to omeda integration hooks - addOmedaHooksToConfig({ + addOmedaHooksToIdentityXConfig({ idxConfig, brandKey, productId: rapidIdentProductId, From 87caed904aa05ff16e7d1879a43cc628be4b51d2 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:39:06 -0600 Subject: [PATCH 13/17] Rename rapid ident var name --- .../integration-hooks/on-login-link-sent.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js b/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js index 50f825048..081de6709 100644 --- a/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js +++ b/packages/marko-web-omeda-identity-x/integration-hooks/on-login-link-sent.js @@ -136,13 +136,13 @@ module.exports = async ({ }) => { const omedaGraphQLClient = req[omedaGraphQLProp]; if (!omedaGraphQLClient) throw new Error(`Unable to load the Omeda GraphQL API from the request using prop ${omedaGraphQLProp}`); - const idxRapidIdentify = req[idxOmedaRapidIdentifyProp]; - if (!idxRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`); + const idxOmedaRapidIdentify = req[idxOmedaRapidIdentifyProp]; + if (!idxOmedaRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`); // get omeda customer id (via rapid identity) and load omeda custom field data const [{ data }, { encryptedCustomerId }] = await Promise.all([ identityX.client.query({ query: FIELD_QUERY }), - idxRapidIdentify({ + idxOmedaRapidIdentify({ user: user.verified ? user : { id: user.id, email: user.email }, }), ]); From 1b8de307ff6ea883153dbf7b23052d2fe5ed3e26 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:45:36 -0600 Subject: [PATCH 14/17] Remove commented out code --- packages/marko-web-omeda-identity-x/routes/rapid-identify.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/marko-web-omeda-identity-x/routes/rapid-identify.js b/packages/marko-web-omeda-identity-x/routes/rapid-identify.js index 82d12795d..c835a05b1 100644 --- a/packages/marko-web-omeda-identity-x/routes/rapid-identify.js +++ b/packages/marko-web-omeda-identity-x/routes/rapid-identify.js @@ -28,8 +28,6 @@ module.exports = ({ const idxUserExists = tokenCookie.exists(req); if (!idxUserExists) return res.json(data); - - // const { identityX } = req; const context = await req.identityX.loadActiveContext(); const user = getAsObject(context, 'user'); if (!user.id) return res.json(data); From dd5b44c6453726aa19d12131c022d7a003466aa3 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:45:41 -0600 Subject: [PATCH 15/17] Add doc blocks --- packages/marko-web-identity-x/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/marko-web-identity-x/index.js b/packages/marko-web-identity-x/index.js index 20f4c5948..992a2fb54 100644 --- a/packages/marko-web-identity-x/index.js +++ b/packages/marko-web-identity-x/index.js @@ -1,6 +1,11 @@ const routes = require('./routes'); const middleware = require('./middleware'); +/** + * + * @param {object} app The express app instance + * @param {IdentityXConfiguration} config The IdentityX config + */ module.exports = (app, config) => { app.use(middleware(config)); app.use('/__idx', routes); From 0710774a5f24db4ef6adb9d4fc7dbfd7cf759df9 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:48:57 -0600 Subject: [PATCH 16/17] Optionally allow for passing omeda graphql uri via env --- packages/marko-web-omeda/middleware/graphql-client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/marko-web-omeda/middleware/graphql-client.js b/packages/marko-web-omeda/middleware/graphql-client.js index 7e04b5799..488cc68b9 100644 --- a/packages/marko-web-omeda/middleware/graphql-client.js +++ b/packages/marko-web-omeda/middleware/graphql-client.js @@ -1,7 +1,7 @@ const createClient = require('@parameter1/omeda-graphql-client'); module.exports = ({ - uri = 'https://graphql.omeda.parameter1.com/', + uri = process.env.OMEDA_GRAPHQL_URI || 'https://graphql.omeda.parameter1.com/', brandKey, clientKey, appId, From 33c17e10bb65efa558c301faa2659a3000789d38 Mon Sep 17 00:00:00 2001 From: Jacob Bare Date: Fri, 12 Nov 2021 15:51:13 -0600 Subject: [PATCH 17/17] Do not allow `productId` to be overridden by params --- packages/marko-web-omeda/middleware/rapid-identify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/marko-web-omeda/middleware/rapid-identify.js b/packages/marko-web-omeda/middleware/rapid-identify.js index 53ccbee72..ff5f618d8 100644 --- a/packages/marko-web-omeda/middleware/rapid-identify.js +++ b/packages/marko-web-omeda/middleware/rapid-identify.js @@ -10,8 +10,8 @@ module.exports = ({ const omedaGraphQLClient = req[omedaGraphQLClientProp]; if (!omedaGraphQLClient) throw new Error(`Unable to find the Omeda GraphQL client on the request using ${omedaGraphQLClientProp}`); const handler = async (params = {}) => rapidIdentify(omedaGraphQLClient, { - productId, ...params, + productId, }); req[prop] = handler;