From cc67aa0e15e87f627e63659f3b8c767ed0ddb2b6 Mon Sep 17 00:00:00 2001 From: Sumrender Singh <78428003+sumrender@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:04:19 +0530 Subject: [PATCH] fix: add mfa flow to sync/fetch txns personal card (#3316) * fix: add mfa flow to sync/fetch txns personal card * fix tests * add tests * fix: change selectedAccount type to PersonalCard and finally mfa flow is working * fix: remove console.log --- ...et-tasks-query-params-with-filters.data.ts | 2 +- src/app/core/mock-data/personal-cards.data.ts | 4 + src/app/core/models/personal_card.model.ts | 1 + .../services/personal-cards.service.spec.ts | 81 +++++++++++++- .../core/services/personal-cards.service.ts | 25 ++++- .../personal-cards.page.spec.ts | 105 ++++++++++++------ .../personal-cards/personal-cards.page.ts | 73 ++++++++---- .../bank-account-cards.component.spec.ts | 2 +- .../bank-account-cards.component.ts | 12 +- 9 files changed, 230 insertions(+), 75 deletions(-) diff --git a/src/app/core/mock-data/get-tasks-query-params-with-filters.data.ts b/src/app/core/mock-data/get-tasks-query-params-with-filters.data.ts index 15af610722..df468ec18c 100644 --- a/src/app/core/mock-data/get-tasks-query-params-with-filters.data.ts +++ b/src/app/core/mock-data/get-tasks-query-params-with-filters.data.ts @@ -37,6 +37,6 @@ export const personalCardQueryParamFiltersData: Partial { }); }); - it('htmlFormUrl(): get html from URL', () => { - const URL = 'https://repo1.maven.org/maven2'; - - expect(personalCardsService.htmlFormUrl(URL, '123')).toEqual( - 'data:text/html;base64,PGZvcm0gaWQ9ImZhc3RsaW5rLWZvcm0iIG5hbWU9ImZhc3RsaW5rLWZvcm0iIGFjdGlvbj0iaHR0cHM6Ly9yZXBvMS5tYXZlbi5vcmcvbWF2ZW4yIiBtZXRob2Q9IlBPU1QiPgogICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBuYW1lPSJhY2Nlc3NUb2tlbiIgdmFsdWU9IkJlYXJlciAxMjMiIGhpZGRlbj0idHJ1ZSIgLz4KICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgIG5hbWU9ImV4dHJhUGFyYW1zIiB2YWx1ZT0iY29uZmlnTmFtZT1BZ2dyZWdhdGlvbiZjYWxsYmFjaz1odHRwczovL3d3dy5meWxlaHEuY29tIiBoaWRkZW49InRydWUiIC8+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9mb3JtPiAKICAgICAgICAgICAgICAgICAgICAgICAgICA8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImZhc3RsaW5rLWZvcm0iKS5zdWJtaXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NjcmlwdD4KICAgICAgICAgICAgICAgICAgICAgICAgICA=' - ); + describe('htmlFormUrl()', () => { + const baseUrl = 'https://repo1.maven.org/maven2'; + + it('should generate the correct HTML for a normal flow', () => { + const accessToken = '123'; + const isMfaFlow = false; + + const result = personalCardsService.htmlFormUrl(baseUrl, accessToken, isMfaFlow); + const expectedExtraParams = 'configName=Aggregation&callback=https://www.fylehq.com'; + const expectedHtml = ` + + `; + const expectedEncodedHtml = 'data:text/html;base64,' + btoa(expectedHtml); + + expect(result).toEqual(expectedEncodedHtml); + }); + + it('should generate the correct HTML for an MFA flow with providerAccountId', () => { + const accessToken = '789'; + const isMfaFlow = true; + const providerAccountId = 'test-provider-id'; + + const result = personalCardsService.htmlFormUrl(baseUrl, accessToken, isMfaFlow, providerAccountId); + const expectedExtraParams = `configName=Aggregation&flow=refresh&providerAccountId=${providerAccountId}&callback=https://www.fylehq.com`; + const expectedHtml = ` + + `; + const expectedEncodedHtml = 'data:text/html;base64,' + btoa(expectedHtml); + + expect(result).toEqual(expectedEncodedHtml); + }); }); describe('getToken()', () => { @@ -1568,4 +1603,38 @@ describe('PersonalCardsService', () => { }); }); }); + + describe('isMfaEnabled()', () => { + it('should return false when using public api', (done) => { + const personalCardId = '12345'; + const usePlatformApi = false; + + personalCardsService.isMfaEnabled(personalCardId, usePlatformApi).subscribe((res) => { + expect(res).toBeFalse(); + expect(spenderPlatformV1ApiService.post).not.toHaveBeenCalled(); + done(); + }); + }); + + it('should call platform API usePlatformApi is true', (done) => { + const personalCardId = '12345'; + const usePlatformApi = true; + const mockApiResponse = { + data: { + is_mfa_enabled: true, + }, + }; + spenderPlatformV1ApiService.post.and.returnValue(of(mockApiResponse)); + + personalCardsService.isMfaEnabled(personalCardId, usePlatformApi).subscribe((res) => { + expect(res).toBeTrue(); + expect(spenderPlatformV1ApiService.post).toHaveBeenCalledOnceWith('/personal_cards/mfa', { + data: { + id: personalCardId, + }, + }); + done(); + }); + }); + }); }); diff --git a/src/app/core/services/personal-cards.service.ts b/src/app/core/services/personal-cards.service.ts index 8a69f88dea..fafff07b66 100644 --- a/src/app/core/services/personal-cards.service.ts +++ b/src/app/core/services/personal-cards.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { PersonalCard } from '../models/personal_card.model'; import { YodleeAccessToken } from '../models/yoodle-token.model'; @@ -55,6 +55,7 @@ export class PersonalCardsService { last_synced_at: card.yodlee_last_synced_at, mask: card.card_number.slice(-4), account_type: card.account_type, + yodlee_provider_account_id: card.yodlee_provider_account_id, }; return personalCard; }); @@ -190,10 +191,28 @@ export class PersonalCardsService { return this.expenseAggregationService.get('/yodlee/personal/access_token') as Observable; } - htmlFormUrl(url: string, accessToken: string): string { + isMfaEnabled(personalCardId: string, usePlatformApi): Observable { + if (!usePlatformApi) { + return of(false); // TODO sumrender: hack, this will be removed with old personalCards removal in next pr; + } + const payload = { + data: { + id: personalCardId, + }, + }; + return this.spenderPlatformV1ApiService + .post>('/personal_cards/mfa', payload) + .pipe(map((res) => res.data.is_mfa_enabled)); + } + + htmlFormUrl(url: string, accessToken: string, isMfaFlow: boolean, providerAccountId = ''): string { + let extraParams = 'configName=Aggregation&callback=https://www.fylehq.com'; + if (isMfaFlow) { + extraParams = `configName=Aggregation&flow=refresh&providerAccountId=${providerAccountId}&callback=https://www.fylehq.com`; + } const pageContent = `