Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fraudnet): add fraudnet util for shared SDK components #170

Merged
merged 22 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* @flow */
import { ENV } from "@paypal/sdk-constants/src";

export const FPTI_CONTEXT_TYPE = {
ORDER_ID: ("EC-Token": "EC-Token"),
Expand All @@ -13,3 +14,19 @@ export const FPTI_TRANSITION = {
export const FPTI_STATE = {
PXP: ("PXP_CHECK": "PXP_CHECK"),
};

type FraudnetUrl = {|
[$Values<typeof ENV>]: string,
|};

export const FRAUDNET_URL: FraudnetUrl = {
[ENV.LOCAL]:
"https://cdn-latest.static.engineering.dev.paypalinc.com/qaRdaAssets/fraudnet/async/fb-raw.js",
[ENV.STAGE]:
"https://cdn-latest.static.engineering.dev.paypalinc.com/qaRdaAssets/fraudnet/async/fb-raw.js",
[ENV.SANDBOX]: "https://c.paypal.com/da/r/fb.js",
[ENV.PRODUCTION]: "https://c.paypal.com/da/r/fb.js",
[ENV.TEST]: "https://c.paypal.com/da/r/fb.js",
};

export const FRAUDNET_FNCLS = "fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99";
141 changes: 141 additions & 0 deletions src/fraudnet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/* eslint-disable promise/no-native, no-restricted-globals */
/* @flow */

import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
import { ENV } from "@paypal/sdk-constants/src";
import { memoize, type Memoized } from "@krakenjs/belter/src";

import { FRAUDNET_FNCLS, FRAUDNET_URL } from "./constants";
import { getLogger } from "./logger";

type FraudnetOptions = {|
env: $Values<typeof ENV>,
clientMetadataID: string,
cspNonce: string,
appName: string,
queryStringParams?: { [string]: string | boolean },
|};

type FraudnetConfig = {|
f: string,
s: string,
u?: string,
cb1: string,
sandbox?: boolean,
io: boolean,
|};

type CreateConfigOptions = {|
env: $Values<typeof ENV>,
cspNonce: string,
clientMetadataID: string,
appName: string,
|};

type CreateFraudnetOptions = {|
cspNonce: string,
env: $Values<typeof ENV>,
queryStringParams?: { [string]: string | boolean },
|};

export const createConfigScript = ({
env,
cspNonce = "",
clientMetadataID,
appName,
}: CreateConfigOptions): ZalgoPromise<void> => {
return new ZalgoPromise((resolve) => {
if (__TEST__) {
return resolve();

Check warning on line 49 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L47-L49

Added lines #L47 - L49 were not covered by tests
}

const config: FraudnetConfig = {

Check warning on line 52 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L52

Added line #L52 was not covered by tests
f: clientMetadataID,
s: appName,
io: true,
cb1: "fnCallback",
};

if (env === ENV.SANDBOX) {
config.sandbox = true;

Check warning on line 60 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L59-L60

Added lines #L59 - L60 were not covered by tests
}

const configScript = document.createElement("script");

Check warning on line 63 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L63

Added line #L63 was not covered by tests

configScript.setAttribute("nonce", cspNonce);
configScript.setAttribute("type", "application/json");
configScript.setAttribute("id", "fconfig");
configScript.setAttribute("fncls", FRAUDNET_FNCLS);
configScript.text = JSON.stringify(config);

Check warning on line 69 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L65-L69

Added lines #L65 - L69 were not covered by tests
// eslint-disable-next-line compat/compat
document.body?.appendChild(configScript);

Check warning on line 71 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L71

Added line #L71 was not covered by tests
});
};

export const createFraudnetScript = ({
cspNonce,
env,
queryStringParams = {},
}: CreateFraudnetOptions): ZalgoPromise<void> => {
return new ZalgoPromise((resolve, reject) => {
const fraudnetScript = document.createElement("script");
const queryString = Object.keys(queryStringParams)

Check warning on line 82 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L80-L82

Added lines #L80 - L82 were not covered by tests
.map(
(key) => `${key}=${encodeURIComponent(String(queryStringParams[key]))}`

Check warning on line 84 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L84

Added line #L84 was not covered by tests
)
.join("&");

const fraudnetUrl = queryString.length

Check warning on line 88 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L88

Added line #L88 was not covered by tests
? `${FRAUDNET_URL[env]}?${queryString}`
: FRAUDNET_URL[env];

fraudnetScript.setAttribute("nonce", cspNonce || "");
fraudnetScript.setAttribute("src", fraudnetUrl);
fraudnetScript.addEventListener("error", () => resolve());

Check warning on line 94 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L92-L94

Added lines #L92 - L94 were not covered by tests

window.fnCallback = resolve;

Check warning on line 96 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L96

Added line #L96 was not covered by tests
// eslint-disable-next-line compat/compat
document.body?.appendChild(fraudnetScript);

Check warning on line 98 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L98

Added line #L98 was not covered by tests

fraudnetScript.addEventListener("load", () => {
resolve();

Check warning on line 101 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L100-L101

Added lines #L100 - L101 were not covered by tests
});
fraudnetScript.addEventListener("error", () => {
reject(new Error(`Fraudnet failed to load.`));

Check warning on line 104 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L103-L104

Added lines #L103 - L104 were not covered by tests
});
fraudnetScript.addEventListener("abort", () => {
reject(new Error(`Fraudnet load was aborted.`));

Check warning on line 107 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L106-L107

Added lines #L106 - L107 were not covered by tests
});
});
};

type LoadFraudnetResponse = {|
collect: () => Promise<*> | void,
|};
type LoadFraudnet = (opts: FraudnetOptions) => LoadFraudnetResponse;

export const loadFraudnet: Memoized<LoadFraudnet> = memoize(
({ env, clientMetadataID, cspNonce, appName, queryStringParams = {} }) => {
createConfigScript({ env, cspNonce, clientMetadataID, appName });

Check warning on line 119 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L119

Added line #L119 was not covered by tests

const fraudnetPromise = createFraudnetScript({

Check warning on line 121 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L121

Added line #L121 was not covered by tests
cspNonce,
env,
queryStringParams,
}).catch(() => {
getLogger().warn("ppcp_axo_init_fraudnet_failed");

Check warning on line 126 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L126

Added line #L126 was not covered by tests
});

return {

Check warning on line 129 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L129

Added line #L129 was not covered by tests
collect: async () => {
try {
await fraudnetPromise;
await window.PAYPAL.asyncData.collect();

Check warning on line 133 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L131-L133

Added lines #L131 - L133 were not covered by tests
} catch (err) {
getLogger().warn("ppcp_axo_collect_fraudnet_failed");

Check warning on line 135 in src/fraudnet.js

View check run for this annotation

Codecov / codecov/patch

src/fraudnet.js#L135

Added line #L135 was not covered by tests
}
},
};
}
);
/* eslint-enable promise/no-native, no-restricted-globals */
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from "./logger";
export * from "./types";
export * from "./global";
export * from "./script";
export * from "./fraudnet";
export * from "./meta";
export * from "./api";
export * from "./experiment";
Expand Down