mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-22 07:40:32 +00:00
feat: reset plaid lanch link token
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { usePlaidExchangeToken } from '@/hooks/query';
|
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
usePlaidLink,
|
usePlaidLink,
|
||||||
@@ -10,28 +9,28 @@ import {
|
|||||||
PlaidLinkOnEventMetadata,
|
PlaidLinkOnEventMetadata,
|
||||||
PlaidLinkStableEvent,
|
PlaidLinkStableEvent,
|
||||||
} from 'react-plaid-link';
|
} from 'react-plaid-link';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { logEvent } from './_utils';
|
||||||
// import { exchangeToken, setItemState } from '../services/api';
|
import { usePlaidExchangeToken } from '@/hooks/query';
|
||||||
// import { useItems, useLink, useErrors } from '../services';
|
import { useResetBankingPlaidToken } from '@/hooks/state/banking';
|
||||||
|
|
||||||
interface LaunchLinkProps {
|
interface PlaidLaunchLinkProps {
|
||||||
isOauth?: boolean;
|
|
||||||
token: string;
|
token: string;
|
||||||
userId: number;
|
|
||||||
itemId?: number | null;
|
itemId?: number | null;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses the usePlaidLink hook to manage the Plaid Link creation. See https://github.com/plaid/react-plaid-link for full usage instructions.
|
/**
|
||||||
// The link token passed to usePlaidLink cannot be null. It must be generated outside of this component. In this sample app, the link token
|
* Uses the usePlaidLink hook to manage the Plaid Link creation.
|
||||||
// is generated in the link context in client/src/services/link.js.
|
* See https://github.com/plaid/react-plaid-link for full usage instructions.
|
||||||
|
* The link token passed to usePlaidLink cannot be null.
|
||||||
export function LaunchLink(props: LaunchLinkProps) {
|
* It must be generated outside of this component. In this sample app, the link token
|
||||||
const history = useHistory();
|
* is generated in the link context in client/src/services/link.js.
|
||||||
// const { getItemsByUser, getItemById } = useItems();
|
*
|
||||||
// const { generateLinkToken, deleteLinkToken } = useLink();
|
* @param {PlaidLaunchLinkProps} props
|
||||||
// const { setError, resetError } = useErrors();
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
export function LaunchLink(props: PlaidLaunchLinkProps) {
|
||||||
|
const resetPlaidToken = useResetBankingPlaidToken();
|
||||||
const { mutateAsync: exchangeAccessToken } = usePlaidExchangeToken();
|
const { mutateAsync: exchangeAccessToken } = usePlaidExchangeToken();
|
||||||
|
|
||||||
// define onSuccess, onExit and onEvent functions as configs for Plaid Link creation
|
// define onSuccess, onExit and onEvent functions as configs for Plaid Link creation
|
||||||
@@ -40,7 +39,7 @@ export function LaunchLink(props: LaunchLinkProps) {
|
|||||||
metadata: PlaidLinkOnSuccessMetadata,
|
metadata: PlaidLinkOnSuccessMetadata,
|
||||||
) => {
|
) => {
|
||||||
// log and save metatdata
|
// log and save metatdata
|
||||||
// logSuccess(metadata, props.userId);
|
logSuccess(metadata);
|
||||||
if (props.itemId != null) {
|
if (props.itemId != null) {
|
||||||
// update mode: no need to exchange public token
|
// update mode: no need to exchange public token
|
||||||
// await setItemState(props.itemId, 'good');
|
// await setItemState(props.itemId, 'good');
|
||||||
@@ -48,39 +47,26 @@ export function LaunchLink(props: LaunchLinkProps) {
|
|||||||
// getItemById(props.itemId, true);
|
// getItemById(props.itemId, true);
|
||||||
// regular link mode: exchange public token for access token
|
// regular link mode: exchange public token for access token
|
||||||
} else {
|
} else {
|
||||||
// call to Plaid api endpoint: /item/public_token/exchange in order to obtain access_token which is then stored with the created item
|
|
||||||
debugger;
|
|
||||||
|
|
||||||
await exchangeAccessToken({
|
await exchangeAccessToken({
|
||||||
public_token: publicToken,
|
public_token: publicToken,
|
||||||
institution_id: metadata.institution.institution_id,
|
institution_id: metadata.institution.institution_id,
|
||||||
});
|
});
|
||||||
// await exchangeToken(
|
|
||||||
// publicToken,
|
|
||||||
// metadata.institution,
|
|
||||||
// metadata.accounts,
|
|
||||||
// props.userId,
|
|
||||||
// );
|
|
||||||
// getItemsByUser(props.userId, true);
|
|
||||||
}
|
}
|
||||||
// resetError();
|
// resetError();
|
||||||
// deleteLinkToken(props.userId, null);
|
resetPlaidToken();
|
||||||
history.push(`/user/${props.userId}`);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle other error codes, see https://plaid.com/docs/errors/
|
||||||
const onExit = async (
|
const onExit = async (
|
||||||
error: PlaidLinkError | null,
|
error: PlaidLinkError | null,
|
||||||
metadata: PlaidLinkOnExitMetadata,
|
metadata: PlaidLinkOnExitMetadata,
|
||||||
) => {
|
) => {
|
||||||
// log and save error and metatdata
|
// log and save error and metatdata
|
||||||
// logExit(error, metadata, props.userId);
|
logExit(error, metadata, props.userId);
|
||||||
if (error != null && error.error_code === 'INVALID_LINK_TOKEN') {
|
|
||||||
// await generateLinkToken(props.userId, props.itemId);
|
|
||||||
}
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
// setError(error.error_code, error.display_message || error.error_message);
|
// setError(error.error_code, error.display_message || error.error_message);
|
||||||
}
|
}
|
||||||
// to handle other error codes, see https://plaid.com/docs/errors/
|
resetPlaidToken();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEvent = async (
|
const onEvent = async (
|
||||||
@@ -91,7 +77,7 @@ export function LaunchLink(props: LaunchLinkProps) {
|
|||||||
if (eventName === 'ERROR' && metadata.error_code != null) {
|
if (eventName === 'ERROR' && metadata.error_code != null) {
|
||||||
// setError(metadata.error_code, ' ');
|
// setError(metadata.error_code, ' ');
|
||||||
}
|
}
|
||||||
// logEvent(eventName, metadata);
|
logEvent(eventName, metadata);
|
||||||
};
|
};
|
||||||
|
|
||||||
const config: PlaidLinkOptionsWithLinkToken = {
|
const config: PlaidLinkOptionsWithLinkToken = {
|
||||||
@@ -101,31 +87,14 @@ export function LaunchLink(props: LaunchLinkProps) {
|
|||||||
token: props.token,
|
token: props.token,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (props.isOauth) {
|
|
||||||
// add additional receivedRedirectUri config when handling an OAuth reidrect
|
|
||||||
config.receivedRedirectUri = window.location.href;
|
|
||||||
}
|
|
||||||
const { open, ready } = usePlaidLink(config);
|
const { open, ready } = usePlaidLink(config);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// initiallizes Link automatically
|
// initiallizes Link automatically
|
||||||
if (props.isOauth && ready) {
|
if (ready) {
|
||||||
open();
|
|
||||||
} else if (ready) {
|
|
||||||
// regular, non-OAuth case:
|
|
||||||
// set link token, userId and itemId in local storage for use if needed later by OAuth
|
|
||||||
|
|
||||||
localStorage.setItem(
|
|
||||||
'oauthConfig',
|
|
||||||
JSON.stringify({
|
|
||||||
userId: props.userId,
|
|
||||||
itemId: props.itemId,
|
|
||||||
token: props.token,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
}, [ready, open, props.isOauth, props.userId, props.itemId, props.token]);
|
}, [ready, open, props.itemId, props.token]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|||||||
30
packages/webapp/src/containers/Banking/Plaid/_utils.ts
Normal file
30
packages/webapp/src/containers/Banking/Plaid/_utils.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import {
|
||||||
|
PlaidLinkError,
|
||||||
|
PlaidLinkOnEventMetadata,
|
||||||
|
PlaidLinkOnExitMetadata,
|
||||||
|
PlaidLinkOnSuccessMetadata,
|
||||||
|
PlaidLinkStableEvent,
|
||||||
|
} from 'react-plaid-link';
|
||||||
|
|
||||||
|
export const logEvent = (
|
||||||
|
eventName: PlaidLinkStableEvent | string,
|
||||||
|
metadata:
|
||||||
|
| PlaidLinkOnEventMetadata
|
||||||
|
| PlaidLinkOnSuccessMetadata
|
||||||
|
| PlaidLinkOnExitMetadata,
|
||||||
|
error?: PlaidLinkError | null,
|
||||||
|
) => {
|
||||||
|
console.log(`Link Event: ${eventName}`, metadata, error);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const logSuccess = async ({
|
||||||
|
institution,
|
||||||
|
accounts,
|
||||||
|
link_session_id,
|
||||||
|
}: PlaidLinkOnSuccessMetadata) => {
|
||||||
|
logEvent('onSuccess', {
|
||||||
|
institution,
|
||||||
|
accounts,
|
||||||
|
link_session_id,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -4,5 +4,5 @@ import { useGetBankingPlaidToken } from '@/hooks/state/banking';
|
|||||||
export function CashflowAccountsPlaidLink() {
|
export function CashflowAccountsPlaidLink() {
|
||||||
const plaidToken = useGetBankingPlaidToken();
|
const plaidToken = useGetBankingPlaidToken();
|
||||||
|
|
||||||
return <LaunchLink userId={3} token={plaidToken} />;
|
return <LaunchLink token={plaidToken} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { getPlaidToken, setPlaidId } from '@/store/banking/banking.reducer';
|
import {
|
||||||
|
getPlaidToken,
|
||||||
|
setPlaidId,
|
||||||
|
resetPlaidId,
|
||||||
|
} from '@/store/banking/banking.reducer';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
@@ -18,3 +22,11 @@ export const useGetBankingPlaidToken = () => {
|
|||||||
|
|
||||||
return plaidToken;
|
return plaidToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useResetBankingPlaidToken = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
return useCallback(() => {
|
||||||
|
dispatch(resetPlaidId());
|
||||||
|
}, [dispatch]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -13,8 +13,11 @@ export const PlaidSlice = createSlice({
|
|||||||
setPlaidId: (state: StorePlaidState, action: PayloadAction<string>) => {
|
setPlaidId: (state: StorePlaidState, action: PayloadAction<string>) => {
|
||||||
state.plaidToken = action.payload;
|
state.plaidToken = action.payload;
|
||||||
},
|
},
|
||||||
|
resetPlaidId: (state: StorePlaidState) => {
|
||||||
|
state.plaidToken = '';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { setPlaidId } = PlaidSlice.actions;
|
export const { setPlaidId, resetPlaidId } = PlaidSlice.actions;
|
||||||
export const getPlaidToken = (state: any) => state.plaid.plaidToken;
|
export const getPlaidToken = (state: any) => state.plaid.plaidToken;
|
||||||
Reference in New Issue
Block a user