Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Commit

Permalink
Merge pull request #378 from solocommand/oidx-config
Browse files Browse the repository at this point in the history
Omeda+IdentityX config validation
  • Loading branch information
solocommand authored Jul 27, 2022
2 parents 9e2de61 + e373111 commit b8d2d1e
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 105 deletions.
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,12 @@ services:
IDENTITYX_APP_ID: ${EXAMPLE_IDENTITYX_APP_ID-5d1b86070ce467bff670a052}
IDENTITYX_API_TOKEN: ${EXAMPLE_IDENTITYX_API_TOKEN-}

OMEDA_CLIENT_KEY: ${EXAMPLE_OMEDA_CLIENT_KEY-client_allu}
OMEDA_CLIENT_KEY: ${EXAMPLE_OMEDA_CLIENT_KEY-client_acbm}
OMEDA_GRAPHQL_URI: ${EXAMPLE_OMEDA_GRAPHQL_URI-}
OMEDA_BRAND_KEY: ${EXAMPLE_OMEDA_BRAND_KEY-allucd}
OMEDA_BRAND_KEY: ${EXAMPLE_OMEDA_BRAND_KEY-hcl}
OMEDA_APP_ID: ${EXAMPLE_OMEDA_APP_ID}
OMEDA_INPUT_ID: ${EXAMPLE_OMEDA_INPUT_ID}
OMEDA_RAPID_IDENT_PRODUCT_ID: ${EXAMPLE_OMEDA_RAPID_IDENT_PRODUCT_ID-374}
OMEDA_RAPID_IDENT_PRODUCT_ID: ${EXAMPLE_OMEDA_RAPID_IDENT_PRODUCT_ID-15289}
RECAPTCHA_V3_SECRET_KEY: ${EXAMPLE_RECAPTCHA_V3_SECRET_KEY-}
RECAPTCHA_V3_SITE_KEY: ${EXAMPLE_RECAPTCHA_V3_SITE_KEY-}
SENDGRID_API_KEY: ${EXAMPLE_SENDGRID_API_KEY-}
Expand Down
28 changes: 14 additions & 14 deletions packages/marko-web-omeda-identity-x/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ Additional information can be found in the [Omeda](https://training.omeda.com/kn
## Configuration
All configuration data must be passed to the middleware when loaded (See [Middleware Setup](#1-middleware-setup) below.)

| Key | Description | Link
| - | - | - |
| `brandKey` | (Required) The Omeda Brand key (such as `orgcd`).
| `clientKey` | (Optional) The Omeda client key (such as `client_orgc`.) *Required if sending deployment optIns via the underlying omeda package!* | [marko-web-omeda docs](../marko-web-omeda)
| `appId` | (Required) The Omeda application API read token
| `inputId` | (Required) The Omeda application API write token
| `rapidIdentProductId` | (Required) The Omeda identifier for a Website product (ProductType=7).
| `idxConfig` | (Required) An instance of the IdentityX configuration class | [marko-web-identity-x#1](../marko-web-identity-x/config.js)
| `idxRouteTemplates` | (Required) An object containing the Marko templates to use for each IdentityX endpoint. | [marko-web-identity-x#2](../marko-web-identity-x/index.js)
| `omedaGraphQLClientProp` | (Optional) Custom path to the Omeda GraphQL client (within app.locals), default value `$omedaGraphQLClient`
| `omedaRapidIdentifyProp` | (Optional) Custom path to the Omeda Rapid Identification handler (within app.locals), default value `$omedaRapidIdentify`
| `idxOmedaRapidIdentifyProp` | (Optional) Custom path to the IdentityX Omeda Rapid Identification handler (within app.locals), default value `$idXOmedaRapidIdentify`
| `omedaPromoCodeCookieName` | (Optional) The Omeda promocode cookie name to detect, default value `omeda_promo_code`
| `omedaPromoCodeDefault` | (Optional) The default promo code to send with rapid identification requests
| Property | Required? | Description | Default value |
| - | - | - | - |
| `brandKey` | **Yes** | The Omeda Brand key (such as `orgcd`).
| `clientKey` | No | The Omeda client key (such as `client_orgc`.) *Required if sending deployment optIns via the underlying omeda package!* [marko-web-omeda docs](../marko-web-omeda)
| `appId` | **Yes** | The Omeda application API read token
| `inputId` | **Yes** | The Omeda application API write token
| `rapidIdentProductId` | **Yes** | The Omeda identifier for a Website product (ProductType=7).
| `idxConfig` | **Yes** | An instance of the IdentityX configuration class (see [marko-web-identity-x#1](../marko-web-identity-x/config.js)) | _n/a_
| `idxRouteTemplates` | **Yes** | An object containing the Marko templates to use for each IdentityX endpoint. (see [marko-web-identity-x#2](../marko-web-identity-x/index.js))
| `omedaPromoCodeCookieName` | No | The name of the cookie to look for a persisted/original promo code. | `omeda_promo_code` |
| `omedaPromoCodeDefault` | No | The default promo code to send with all Omeda requests. Falls back to input ID default configured by Omeda. |
| `idxOmedaRapidIdentifyProp` | No | The property (in the express app context) where the O+IdX rapid identification service is located. | `$idxOmedaRapidIdentify` |
| `omedaGraphQLClientProp` | No | The property (in the express app context) where the Omeda GraphQL client is located. | `$omedaGraphQLClient` |
| `omedaRapidIdentifyProp` | No | The property (in the express app context) where the Omeda rapid identification service is located. | `$omedaRapidIdentify` |

## Usage
This package:
Expand Down
54 changes: 35 additions & 19 deletions packages/marko-web-omeda-identity-x/add-integration-hooks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

const Joi = require('@parameter1/joi');
const { validate } = require('@parameter1/joi/utils');
const { get } = require('@parameter1/base-cms-object-path');
const IdXConfig = require('@parameter1/base-cms-marko-web-identity-x/config');
const {
onAuthenticationSuccess,
onLoginLinkSent,
Expand All @@ -11,49 +14,62 @@ const {
* @param {object} params
* @param {IdentityXConfiguration} params.idxConfig
*/
module.exports = ({
idxConfig,
brandKey,
omedaGraphQLProp = '$omedaGraphQLClient',
idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify',
} = {}) => {
if (!idxConfig) throw new Error('The IdentityX configuration instances is required to add Omeda+IdentityX integration hooks.');
module.exports = (params = {}) => {
const {
idxConfig,
brandKey,
omedaGraphQLClientProp,
idxOmedaRapidIdentifyProp,
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
} = validate(Joi.object({
brandKey: Joi.string().required(),
idxConfig: Joi.object().instance(IdXConfig).required(),
idxOmedaRapidIdentifyProp: Joi.string().required(),
omedaGraphQLClientProp: Joi.string().required(),
omedaPromoCodeCookieName: Joi.string().required(),
omedaPromoCodeDefault: Joi.string(),
}), params);

idxConfig.addHook({
name: 'onLoginLinkSent',
shouldAwait: false,
fn: async args => onLoginLinkSent({
...args,
brandKey,
omedaGraphQLProp,
idxOmedaRapidIdentifyProp,

req: args.req,
service: args.service,
user: args.user,
idxOmedaRapidIdentify: get(args, `req.${idxOmedaRapidIdentifyProp}`),
omedaGraphQLClient: get(args, `req.${omedaGraphQLClientProp}`),
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
}),
});

idxConfig.addHook({
name: 'onAuthenticationSuccess',
shouldAwait: true,
fn: async ({ user, res }) => onAuthenticationSuccess({ brandKey, user, res }),
fn: async args => onAuthenticationSuccess({
...args,
brandKey,
}),
});

idxConfig.addHook({
name: 'onUserProfileUpdate',
shouldAwait: false,
fn: async args => onUserProfileUpdate({
...args,
idxOmedaRapidIdentifyProp,
req: args.req,
user: args.user,
idxOmedaRapidIdentify: get(args, `req.${idxOmedaRapidIdentifyProp}`),
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
}),
});

idxConfig.addHook({
name: 'onLogout',
shouldAwait: true,
fn: async ({ res }) => onLogout({ res }),
fn: async args => onLogout({
...args,
}),
});

return idxConfig;
Expand Down
69 changes: 42 additions & 27 deletions packages/marko-web-omeda-identity-x/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const Joi = require('@parameter1/joi');
const { validate } = require('@parameter1/joi/utils');
const IdXConfig = require('@parameter1/base-cms-marko-web-identity-x/config');
const omeda = require('@parameter1/base-cms-marko-web-omeda');
const identityX = require('@parameter1/base-cms-marko-web-identity-x');
const addOmedaHooksToIdentityXConfig = require('./add-integration-hooks');
Expand All @@ -8,29 +11,34 @@ const setOlyticsCookie = require('./middleware/set-olytics-cookie');
const rapidIdentify = require('./middleware/rapid-identify');
const rapidIdentifyRouter = require('./routes/rapid-identify');

module.exports = (app, {
brandKey: brand,
clientKey,
appId,
inputId,

rapidIdentProductId,
omedaGraphQLClientProp = '$omedaGraphQLClient',
omedaRapidIdentifyProp = '$omedaRapidIdentify',

omedaPromoCodeCookieName = 'omeda_promo_code',
omedaPromoCodeDefault,

idxConfig,
idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify',
idxRouteTemplates = {},
} = {}) => {
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();
module.exports = (app, params = {}) => {
const {
appId,
brandKey,
clientKey,
idxConfig,
idxOmedaRapidIdentifyProp,
idxRouteTemplates,
inputId,
omedaGraphQLClientProp,
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
omedaRapidIdentifyProp,
rapidIdentProductId,
} = validate(Joi.object({
appId: Joi.string().required(),
brandKey: Joi.string().required().trim().lowercase(),
clientKey: Joi.string().required().trim().lowercase(),
idxConfig: Joi.object().required().instance(IdXConfig),
idxOmedaRapidIdentifyProp: Joi.string().default('$idxOmedaRapidIdentify'),
idxRouteTemplates: Joi.object().required(),
inputId: Joi.string().required(),
omedaGraphQLClientProp: Joi.string().default('$omedaGraphQLClient'),
omedaPromoCodeCookieName: Joi.string().default('omeda_promo_code'),
omedaPromoCodeDefault: Joi.string(),
omedaRapidIdentifyProp: Joi.string().default('$omedaRapidIdentify'),
rapidIdentProductId: Joi.number().required(),
}), params);

// strip `oly_enc_id` when identity-x user is logged-in
app.use(stripOlyticsParam());
Expand All @@ -53,10 +61,12 @@ module.exports = (app, {

// add appropiate identity-x to omeda integration hooks
addOmedaHooksToIdentityXConfig({
idxConfig,
brandKey,
productId: rapidIdentProductId,
omedaGraphQLProp: omedaGraphQLClientProp,
idxConfig,
idxOmedaRapidIdentifyProp,
omedaGraphQLClientProp,
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
});

// attach the identity-x rapid identification wrapper middleware
Expand All @@ -75,11 +85,16 @@ module.exports = (app, {
app.use(setOlyticsCookie({ brandKey }));

// install the Omeda data sync middleware
app.use(resyncCustomerData({ brandKey, omedaGraphQLClientProp }));
app.use(resyncCustomerData({
brandKey,
omedaGraphQLClientProp,
}));

// register the rapid identify AJAX route
app.use('/__idx/omeda-rapid-ident', rapidIdentifyRouter({
brandKey,
idxOmedaRapidIdentifyProp,
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
}));
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
const Joi = require('@parameter1/joi');
const { validate } = require('@parameter1/joi/utils');
const olyticsCookie = require('@parameter1/base-cms-marko-web-omeda/olytics/customer-cookie');
const findEncryptedId = require('../external-id/find-encrypted-customer-id');

module.exports = ({ brandKey, user, res }) => {
module.exports = async (params = {}) => {
const {
brandKey,
user,
res,
} = validate(Joi.object({
brandKey: Joi.string().required(),
user: Joi.object().required(),
res: Joi.object().required(),
}).unknown(true), params);
const encryptedId = findEncryptedId({ externalIds: user.externalIds, brandKey });
if (!encryptedId) return;
olyticsCookie.setTo(res, encryptedId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const Joi = require('@parameter1/joi');
const { validate } = require('@parameter1/joi/utils');
const extractPromoCode = require('../utils/extract-promo-code');
const {
getAnsweredQuestionMap,
Expand All @@ -6,22 +8,28 @@ const {
updateIdentityX,
} = require('../omeda-data');

module.exports = async ({
brandKey,
omedaGraphQLProp = '$omedaGraphQLClient',
idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify',
omedaPromoCodeCookieName = 'omeda_promo_code',
omedaPromoCodeDefault,
promoCode: hookDataPromoCode,

req,
service: identityX,
user,
}) => {
const omedaGraphQLClient = req[omedaGraphQLProp];
if (!omedaGraphQLClient) throw new Error(`Unable to load the Omeda GraphQL API from the request using prop ${omedaGraphQLProp}`);
const idxOmedaRapidIdentify = req[idxOmedaRapidIdentifyProp];
if (!idxOmedaRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`);
module.exports = async (params = {}) => {
const {
brandKey,
idxOmedaRapidIdentify,
omedaGraphQLClient,
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
promoCode: hookDataPromoCode,
req,
service: identityX,
user,
} = validate(Joi.object({
brandKey: Joi.string().required(),
idxOmedaRapidIdentify: Joi.function().required(),
omedaGraphQLClient: Joi.object().required(),
omedaPromoCodeCookieName: Joi.string().required(),
omedaPromoCodeDefault: Joi.string(),
promoCode: Joi.string(),
req: Joi.object().required(),
service: Joi.object().required(),
user: Joi.object().required(),
}).unknown(), params);

const promoCode = extractPromoCode({
promoCode: hookDataPromoCode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
const Joi = require('@parameter1/joi');
const { validate } = require('@parameter1/joi/utils');
const olyticsCookie = require('@parameter1/base-cms-marko-web-omeda/olytics/customer-cookie');

module.exports = ({ res }) => {
module.exports = (params = {}) => {
const {
res,
} = validate(Joi.object({
res: Joi.object().required(),
}).unknown(), params);
olyticsCookie.clearFrom(res);
};
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
const Joi = require('@parameter1/joi');
const { validate } = require('@parameter1/joi/utils');
const extractPromoCode = require('../utils/extract-promo-code');

module.exports = async ({
idxOmedaRapidIdentifyProp = '$idxOmedaRapidIdentify',
omedaPromoCodeCookieName = 'omeda_promo_code',
omedaPromoCodeDefault,
req,
user,
promoCode: hookDataPromoCode,
}) => {
const idxOmedaRapidIdentify = req[idxOmedaRapidIdentifyProp];
if (!idxOmedaRapidIdentify) throw new Error(`Unable to find the IdentityX+Omeda rapid identifier on the request using ${idxOmedaRapidIdentifyProp}`);
module.exports = async (params = {}) => {
const {
idxOmedaRapidIdentify,
omedaPromoCodeCookieName,
omedaPromoCodeDefault,
promoCode: hookDataPromoCode,
req,
user,
} = validate(Joi.object({
idxOmedaRapidIdentify: Joi.function().required(),
omedaPromoCodeCookieName: Joi.string().required(),
omedaPromoCodeDefault: Joi.string(),
promoCode: Joi.string(),
req: Joi.object().required(),
user: Joi.object().required(),
}).unknown(), params);

const promoCode = extractPromoCode({
promoCode: hookDataPromoCode,
omedaPromoCodeCookieName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ module.exports = ({
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, promoCode } = {}) => idxOmedaRapidIdentify({
const handler = async ({
user,
promoCode,
} = {}) => idxOmedaRapidIdentify({
brandKey,
productId,
appUser: user,
Expand Down
1 change: 1 addition & 0 deletions packages/marko-web-omeda-identity-x/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@parameter1/base-cms-marko-web-omeda": "^2.103.0",
"@parameter1/base-cms-object-path": "^2.75.1",
"@parameter1/base-cms-utils": "^2.75.1",
"@parameter1/joi": "^1.2.10",
"graphql": "^14.7.0",
"graphql-tag": "^2.12.5"
},
Expand Down
Loading

0 comments on commit b8d2d1e

Please sign in to comment.