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

initial implementation of DA #2300

Closed
wants to merge 2 commits into from

Conversation

davordavidovic
Copy link

Summary

initial implementation of delegated authentication:

  • handle enrollment scenario after successful 3ds2 challenge (via DelegatedAuthenticationEnrollment.tsx component)
  • introduce new delegatedAuthentication action type
  • handle followup (authentication) scenario delegatedAuthentication action type (via DelegatedAuthentication.tsx component)
  • submit delegated authentication result to new endpoint (/v1/submitDelegatedAuthenticationResult) and handle followup action

@changeset-bot
Copy link

changeset-bot bot commented Aug 16, 2023

⚠️ No Changeset found

Latest commit: 41f59e3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Aug 16, 2023

Size Change: +14.3 kB (+1%)

Total Size: 1.08 MB

Filename Size Change
packages/lib/dist/adyen.js 288 kB +4.43 kB (+2%)
packages/lib/dist/cjs/index.js 248 kB +3.51 kB (+1%)
packages/lib/dist/es.modern/index.js 121 kB +2.8 kB (+2%)
packages/lib/dist/es/index.js 141 kB +3.54 kB (+3%)
ℹ️ View Unchanged
Filename Size
packages/lib/dist/es.modern/ar.js 6.41 kB
packages/lib/dist/es.modern/cs-CZ.js 5.79 kB
packages/lib/dist/es.modern/da-DK.js 5.27 kB
packages/lib/dist/es.modern/de-DE.js 5.66 kB
packages/lib/dist/es.modern/el-GR.js 7.29 kB
packages/lib/dist/es.modern/es-ES.js 5.36 kB
packages/lib/dist/es.modern/fi-FI.js 5.35 kB
packages/lib/dist/es.modern/fr-FR.js 5.47 kB
packages/lib/dist/es.modern/hr-HR.js 5.49 kB
packages/lib/dist/es.modern/hu-HU.js 5.78 kB
packages/lib/dist/es.modern/it-IT.js 5.34 kB
packages/lib/dist/es.modern/ja-JP.js 6.18 kB
packages/lib/dist/es.modern/ko-KR.js 5.78 kB
packages/lib/dist/es.modern/nl-NL.js 5.37 kB
packages/lib/dist/es.modern/no-NO.js 5.25 kB
packages/lib/dist/es.modern/pl-PL.js 5.76 kB
packages/lib/dist/es.modern/pt-BR.js 5.32 kB
packages/lib/dist/es.modern/pt-PT.js 5.45 kB
packages/lib/dist/es.modern/ro-RO.js 5.58 kB
packages/lib/dist/es.modern/ru-RU.js 6.76 kB
packages/lib/dist/es.modern/sk-SK.js 5.85 kB
packages/lib/dist/es.modern/sl-SI.js 5.43 kB
packages/lib/dist/es.modern/sv-SE.js 5.23 kB
packages/lib/dist/es.modern/zh-CN.js 5.62 kB
packages/lib/dist/es.modern/zh-TW.js 5.74 kB
packages/lib/dist/es/ar.js 6.41 kB
packages/lib/dist/es/cs-CZ.js 5.79 kB
packages/lib/dist/es/da-DK.js 5.27 kB
packages/lib/dist/es/de-DE.js 5.66 kB
packages/lib/dist/es/el-GR.js 7.29 kB
packages/lib/dist/es/es-ES.js 5.36 kB
packages/lib/dist/es/fi-FI.js 5.35 kB
packages/lib/dist/es/fr-FR.js 5.47 kB
packages/lib/dist/es/hr-HR.js 5.49 kB
packages/lib/dist/es/hu-HU.js 5.78 kB
packages/lib/dist/es/it-IT.js 5.34 kB
packages/lib/dist/es/ja-JP.js 6.18 kB
packages/lib/dist/es/ko-KR.js 5.78 kB
packages/lib/dist/es/nl-NL.js 5.37 kB
packages/lib/dist/es/no-NO.js 5.25 kB
packages/lib/dist/es/pl-PL.js 5.76 kB
packages/lib/dist/es/pt-BR.js 5.32 kB
packages/lib/dist/es/pt-PT.js 5.45 kB
packages/lib/dist/es/ro-RO.js 5.58 kB
packages/lib/dist/es/ru-RU.js 6.76 kB
packages/lib/dist/es/sk-SK.js 5.85 kB
packages/lib/dist/es/sl-SI.js 5.43 kB
packages/lib/dist/es/sv-SE.js 5.23 kB
packages/lib/dist/es/zh-CN.js 5.62 kB
packages/lib/dist/es/zh-TW.js 5.74 kB

compressed-size-action

@sonarcloud
Copy link

sonarcloud bot commented Aug 16, 2023

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

2.9% 2.9% Coverage
0.0% 0.0% Duplication

idea Catch issues before they fail your Quality Gate with our IDE extension sonarlint SonarLint


this.props.onComplete(data); // (equals onAdditionalDetails - except for 3DS2InMDFlow)
if (this.state.challengeData.delegatedAuthenticationSDKInput && resultObj.transStatus === 'Y') {
this.setState({ status: 'delegatedAuthenticationEnrollment' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there are a few different status' it would be cleaner to create an enum rather than relying on strings.

@@ -207,3 +237,11 @@ export const get3DS2FlowProps = (actionSubtype, props) => {
i18n: props.i18n
};
};

export const isInIframe = () => {
try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for a try/catch here, just need to check window is defined and then return the boolean expression.

const [supported, setSupported] = useState<boolean>();
const [spcSupported, setSpcSupported] = useState<boolean>();

const inIframe = useMemo(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't need to memoized, it's not doing a heavy calculation just returning a boolean.

authorisationToken,
onComplete
}: DelegatedAuthenticationEnrollmentProps) => {
const [status, setStatus] = useState<string>('loading');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here also I would use an enum for status rather than strings.

transStatus: string,
authorisationToken: string,
delegatedAuthenticationSDKOutput?: string
): any => ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also have a return type rather than any.

@@ -0,0 +1,8 @@
export const decodeBase64 = (value: string) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these in a different utils file when there already is a utils file?

const complete = (sdkOutput: string) => {
setStatus('loading');
const resolveDataFunction = useOriginalFlow ? createOldChallengeResolveData : createChallengeResolveData;
const data = resolveDataFunction(dataKey, 'Y', authorisationToken, sdkOutput);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not good practice to pass strings like this, better to extract it to a constant and name it.

complete(sdkOutput);
};

useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a extracted into a hook

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or the async function could be a util, that way it's testable

}

try {
return await mockPaymentRequest().canMakePayment();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean everytime a user does DA a mock payment request is made first to determine if the payment can be made?

}
};

const mockPaymentRequest = () => {
Copy link
Contributor

@sarobrien sarobrien Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a util then it's independently testable.

document.cookie = `${credentialId}=; path=/; expires=${expiryDate.toUTCString()};`;
};

const createPaymentCredential = async (registrationData: DelegatedAuthenticationEnrollmentInputData): Promise<PublicKeyCredential> => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a util, then it is independently testable.

// todo: this should be a part of the token data
const useCookiesInSpc = true;

const shouldDoSpc = useMemo(() => {
Copy link
Contributor

@sarobrien sarobrien Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useMemo is not required here, it should only be used when doing calculation type stuff otherwise it can negatively impact performance when used unnecessarily.

} else {
complete({ errorCode: DelegatedAuthenticationError.NoInputDataPresent });
}
}, []);
Copy link
Contributor

@sarobrien sarobrien Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This useEffect depends on token so it should have token in it's dependency array.

}, [authenticationData]);

useEffect(() => {
if (!authenticationData) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This useEffect depends on hasCookieForCrediential but doesn't call it anywhere? Should the if perhaps be (!authenticationData && hasCookieForCredential) otherwise every time hasCookieForCrediential gets updated this will run regardless of it's value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although actually I see hasCookieForCredential is a function so is this a mistake?

Copy link
Contributor

@sarobrien sarobrien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review still in progress but added some comments.

Copy link
Contributor

@sarobrien sarobrien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of logic in the components that could be extracted to utils or hooks. This will make the code easier to test and keep the components clean.

complete({ errorCode: DelegatedAuthenticationError.Canceled, deleteCredential: true });
};

const getAmountValue = (amount: PaymentAmount, currencyExponent: number): string => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function and the one below should be a util so it can independently tested


useEffect(() => {
if (token) {
try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you using a try/catch here?

@sonarcloud
Copy link

sonarcloud bot commented Sep 21, 2023

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

3.4% 3.4% Coverage
0.0% 0.0% Duplication

idea Catch issues before they fail your Quality Gate with our IDE extension sonarlint SonarLint

@sponglord sponglord closed this May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants