diff --git a/packages/desktop-client/src/components/Modals.tsx b/packages/desktop-client/src/components/Modals.tsx index 6898967617e708fb1f0e43564cccf2f72d36ecca..38095bb40c5564bf197b0f361aa0f48caa53154d 100644 --- a/packages/desktop-client/src/components/Modals.tsx +++ b/packages/desktop-client/src/components/Modals.tsx @@ -38,7 +38,6 @@ import { ManageRulesModal } from './modals/ManageRulesModal'; import { MergeUnusedPayees } from './modals/MergeUnusedPayees'; import { Notes } from './modals/Notes'; import { PayeeAutocompleteModal } from './modals/PayeeAutocompleteModal'; -import { PlaidExternalMsg } from './modals/PlaidExternalMsg'; import { ReportBalanceMenuModal } from './modals/ReportBalanceMenuModal'; import { ReportBudgetMenuModal } from './modals/ReportBudgetMenuModal'; import { ReportBudgetSummaryModal } from './modals/ReportBudgetSummaryModal'; @@ -216,20 +215,6 @@ export function Modals() { /> ); - case 'plaid-external-msg': - return ( - <PlaidExternalMsg - key={name} - modalProps={modalProps} - onMoveExternal={options.onMoveExternal} - onClose={() => { - options.onClose?.(); - send('poll-web-token-stop'); - }} - onSuccess={options.onSuccess} - /> - ); - case 'gocardless-init': return ( <GoCardlessInitialise diff --git a/packages/desktop-client/src/components/modals/PlaidExternalMsg.tsx b/packages/desktop-client/src/components/modals/PlaidExternalMsg.tsx deleted file mode 100644 index bab96140e80374152956f07c7ec816d459945017..0000000000000000000000000000000000000000 --- a/packages/desktop-client/src/components/modals/PlaidExternalMsg.tsx +++ /dev/null @@ -1,154 +0,0 @@ -// @ts-strict-ignore -import React, { useState, useRef } from 'react'; - -import { AnimatedLoading } from '../../icons/AnimatedLoading'; -import { theme } from '../../style'; -import { Error } from '../alerts'; -import { Button } from '../common/Button'; -import { Modal, ModalButtons } from '../common/Modal'; -import { Paragraph } from '../common/Paragraph'; -import { Text } from '../common/Text'; -import { View } from '../common/View'; -import { type CommonModalProps } from '../Modals'; - -function renderError(error) { - return ( - <Error style={{ alignSelf: 'center' }}> - {error === 'timeout' - ? 'Timed out. Please try again.' - : 'An error occurred while linking your account, sorry!'} - </Error> - ); -} - -type PlainExternalMsgProps = { - modalProps: CommonModalProps; - onMoveExternal: () => Promise<{ error; data }>; - onSuccess: (data: unknown) => Promise<void>; - onClose?: () => void; -}; - -export function PlaidExternalMsg({ - modalProps, - onMoveExternal, - onSuccess, - onClose: originalOnClose, -}: PlainExternalMsgProps) { - const [waiting, setWaiting] = useState(null); - const [success, setSuccess] = useState(false); - const [error, setError] = useState(null); - const data = useRef(null); - - async function onJump() { - setError(null); - setWaiting('browser'); - - const res = await onMoveExternal(); - if (res.error) { - setError(res.error); - setWaiting(null); - return; - } - - data.current = res.data; - setWaiting(null); - setSuccess(true); - } - - function onClose() { - originalOnClose?.(); - modalProps.onClose(); - } - - async function onContinue() { - setWaiting('accounts'); - await onSuccess(data.current); - setWaiting(null); - } - - return ( - <Modal - title="Link Your Bank" - {...modalProps} - onClose={onClose} - style={{ flex: 0 }} - > - {() => ( - <View> - <Paragraph style={{ fontSize: 15 }}> - To link your bank account, you will be moved to your browser for - enhanced security. Click below and Actual will automatically resume - when you have given your bank’s credentials. - </Paragraph> - {error && renderError(error)} - - {waiting ? ( - <View style={{ alignItems: 'center', marginTop: 15 }}> - <AnimatedLoading - color={theme.pageTextDark} - style={{ width: 20, height: 20 }} - /> - <View style={{ marginTop: 10, color: theme.pageText }}> - {waiting === 'browser' - ? 'Waiting on browser...' - : waiting === 'accounts' - ? 'Loading accounts...' - : null} - </View> - </View> - ) : success ? ( - <Button - type="primary" - style={{ - padding: '10px 0', - fontSize: 15, - fontWeight: 600, - marginTop: 10, - }} - onClick={onContinue} - > - Success! Click to continue → - </Button> - ) : ( - <Button - type="primary" - style={{ - padding: '10px 0', - fontSize: 15, - fontWeight: 600, - marginTop: 10, - }} - onClick={onJump} - > - Link bank in browser → - </Button> - )} - <div style={{ marginTop: waiting ? 30 : 35 }}> - <Text style={{ color: theme.pageText, fontWeight: 600 }}> - Why not link it in the app? - </Text> - </div> - <Text - style={{ - marginTop: 10, - color: theme.pageText, - fontSize: 13, - '& a, & a:visited': { - color: theme.pageText, - }, - }} - > - Typing your bank’s username and password is one of the most - security-sensitive things you can do, and the browser is the most - secure app in the world. Why not use it to make sure your - information is safe? [TODO: Link to docs article] - </Text> - - <ModalButtons style={{ marginTop: 10 }}> - <Button onClick={() => modalProps.onBack()}>Back</Button> - </ModalButtons> - </View> - )} - </Modal> - ); -} diff --git a/packages/desktop-client/src/plaid.js b/packages/desktop-client/src/plaid.js deleted file mode 100644 index 7f54ca3528005eed14dae2ed1db342fcb37fbbb0..0000000000000000000000000000000000000000 --- a/packages/desktop-client/src/plaid.js +++ /dev/null @@ -1,52 +0,0 @@ -/* eslint-disable import/no-unused-modules */ -import { send } from 'loot-core/src/platform/client/fetch'; - -function _authorize(pushModal, plaidToken, { onSuccess, onClose }) { - pushModal('plaid-external-msg', { - onMoveExternal: async () => { - const token = await send('create-web-token'); - let url = 'http://link.actualbudget.com/?token=' + token; - // let url = 'http://localhost:8080/?token=' + token; - if (plaidToken) { - url = url + '&plaidToken=' + plaidToken; - } - window.Actual?.openURLInBrowser(url); - - const { error, data } = await send('poll-web-token', { token }); - - return { error, data }; - }, - - onClose, - onSuccess, - }); -} - -export async function authorizeBank(pushModal, { upgradingId } = {}) { - _authorize(pushModal, null, { - onSuccess: async data => { - pushModal('select-linked-accounts', { - institution: data.metadata.institution, - publicToken: data.publicToken, - accounts: data.metadata.accounts, - upgradingId, - }); - }, - }); -} - -export async function reauthorizeBank(pushModal, bankId, onSuccess) { - const { linkToken } = await send('make-plaid-public-token', { - bankId, - }); - - // We don't do anything with the error right now - if (!linkToken) { - return false; - } - - // When the modal is closed here, always try to re-sync the account - // by calling `onSuccess` - _authorize(pushModal, linkToken, { onSuccess, onClose: onSuccess }); - return true; -} diff --git a/packages/loot-core/src/client/state-types/modals.d.ts b/packages/loot-core/src/client/state-types/modals.d.ts index 88583c8fc55fa2abda1a4f18843163e1e958e31b..83646290c1d6560974e698a7eee443286baed893 100644 --- a/packages/loot-core/src/client/state-types/modals.d.ts +++ b/packages/loot-core/src/client/state-types/modals.d.ts @@ -59,12 +59,6 @@ type FinanceModals = { targetPayeeId: string; }; - 'plaid-external-msg': { - onMoveExternal: () => Promise<void>; - onClose?: () => void; - onSuccess: (data: unknown) => Promise<void>; - }; - 'gocardless-init': { onSuccess: () => void; }; diff --git a/packages/loot-core/src/mocks/plaid.ts b/packages/loot-core/src/mocks/plaid.ts deleted file mode 100644 index 74a37651833196148d4227012e0e31f1c13fff0d..0000000000000000000000000000000000000000 --- a/packages/loot-core/src/mocks/plaid.ts +++ /dev/null @@ -1,59 +0,0 @@ -// @ts-strict-ignore -import { v4 as uuidv4 } from 'uuid'; - -export function generateAccount(balance) { - return { - account_id: uuidv4(), - balances: { - available: balance, - current: balance, - limit: null, - }, - mask: '0000', - name: 'Plaid Checking', - official_name: 'Plaid Interest Checking', - subtype: 'checking', - type: 'depository', - }; -} - -export function generateTransaction( - acctId, - amount, - name, - date, - pending = false, -) { - return { - account_id: acctId, - account_owner: null, - amount, - category: [], - category_id: '', - date, - location: { - address: null, - city: null, - lat: null, - lon: null, - state: null, - store_number: null, - zip: null, - }, - name, - payment_meta: { - by_order_of: null, - payee: null, - payer: null, - payment_method: null, - payment_processor: null, - ppd_id: null, - reason: null, - reference_number: null, - }, - pending, - pending_transaction_id: null, - transaction_id: uuidv4(), - transaction_type: 'special', - }; -} diff --git a/packages/loot-core/src/server/accounts/link.ts b/packages/loot-core/src/server/accounts/link.ts index 2f7282c5c7a8521803f002f7eeba7d86c6e2d6ef..db48e8c25304efbb91d6cb961e85beaebdd0245d 100644 --- a/packages/loot-core/src/server/accounts/link.ts +++ b/packages/loot-core/src/server/accounts/link.ts @@ -1,46 +1,7 @@ // @ts-strict-ignore import { v4 as uuidv4 } from 'uuid'; -import * as asyncStorage from '../../platform/server/asyncStorage'; -import { amountToInteger } from '../../shared/util'; import * as db from '../db'; -import { runMutator } from '../mutators'; -import { post } from '../post'; -import { getServer } from '../server-config'; - -import * as bankSync from './sync'; - -export async function handoffPublicToken(institution, publicToken) { - const [[, userId], [, key]] = await asyncStorage.multiGet([ - 'user-id', - 'user-key', - ]); - - if (institution == null || !institution.institution_id || !institution.name) { - throw new Error('Invalid institution object'); - } - - const id = uuidv4(); - - // Make sure to generate an access token first before inserting it - // into our local database in case it fails - await post(getServer().PLAID_SERVER + '/handoff_public_token', { - userId, - key, - item_id: id, - public_token: publicToken, - }); - - await runMutator(() => - db.insertWithUUID('banks', { - id, - bank_id: institution.institution_id, - name: institution.name, - }), - ); - - return id; -} export async function findOrCreateBank(institution, requisitionId) { const bank = await db.first( @@ -62,49 +23,3 @@ export async function findOrCreateBank(institution, requisitionId) { return bankData; } - -export async function addGoCardlessAccounts( - bankId, - accountIds, - offbudgetIds = [], -) { - const [[, userId], [, userKey]] = await asyncStorage.multiGet([ - 'user-id', - 'user-key', - ]); - - // Get all the available accounts - let accounts = await bankSync.getGoCardlessAccounts(userId, userKey, bankId); - - // Only add the selected accounts - accounts = accounts.filter(acct => accountIds.includes(acct.account_id)); - - return Promise.all( - accounts.map(async acct => { - const id = await runMutator(async () => { - const id = await db.insertAccount({ - account_id: acct.account_id, - name: acct.name, - official_name: acct.official_name, - balance_current: amountToInteger(acct.balances.current), - mask: acct.mask, - bank: bankId, - offbudget: offbudgetIds.includes(acct.account_id) ? 1 : 0, - }); - - // Create a transfer payee - await db.insertPayee({ - name: '', - transfer_acct: id, - }); - - return id; - }); - - // Do an initial sync - await bankSync.syncAccount(userId, userKey, id, acct.account_id, bankId); - - return id; - }), - ); -} diff --git a/packages/loot-core/src/server/accounts/sync.test.ts b/packages/loot-core/src/server/accounts/sync.test.ts index 0c8c9e8e1196a57c123dc4be0f07206a92a04209..1ea00a4d0a59605f4a08428a8e43e7c1abb8f487 100644 --- a/packages/loot-core/src/server/accounts/sync.test.ts +++ b/packages/loot-core/src/server/accounts/sync.test.ts @@ -41,7 +41,7 @@ async function prepareDatabase() { is_income: 1, }); - const { accounts } = await post(getServer().PLAID_SERVER + '/accounts', { + const { accounts } = await post(getServer().GOCARDLESS_SERVER + '/accounts', { client_id: '', group_id: '', item_id: '1', diff --git a/packages/loot-core/src/server/accounts/sync.ts b/packages/loot-core/src/server/accounts/sync.ts index 03bd3fb9daeadbb4a96d5910b12ffca5e901f4ec..d8f919524f0d5df02f4576a9a76f23e7bc0076e6 100644 --- a/packages/loot-core/src/server/accounts/sync.ts +++ b/packages/loot-core/src/server/accounts/sync.ts @@ -20,9 +20,6 @@ import { title } from './title'; import { runRules } from './transaction-rules'; import { batchUpdateTransactions } from './transactions'; -// Plaid article about API options: -// https://support.plaid.com/customer/en/portal/articles/2612155-transactions-returned-per-request - function BankSyncError(type: string, code: string) { return { type: 'BankSyncError', category: type, code }; } @@ -60,22 +57,6 @@ async function updateAccountBalance(id, balance) { ]); } -export async function getAccounts(userId, userKey, id) { - const res = await post(getServer().PLAID_SERVER + '/accounts', { - userId, - key: userKey, - item_id: id, - }); - - const { accounts } = res; - - accounts.forEach(acct => { - acct.balances.current = getAccountBalance(acct); - }); - - return accounts; -} - export async function getGoCardlessAccounts(userId, userKey, id) { const userToken = await asyncStorage.getItem('user-token'); if (!userToken) return; @@ -101,80 +82,6 @@ export async function getGoCardlessAccounts(userId, userKey, id) { return accounts; } -export function fromPlaid(trans) { - return { - imported_id: trans.transaction_id, - payee_name: trans.name, - imported_payee: trans.name, - amount: -amountToInteger(trans.amount), - date: trans.date, - }; -} - -async function downloadTransactions( - userId, - userKey, - acctId, - bankId, - since, - count?: number, -) { - let allTransactions = []; - let accountBalance = null; - const pageSize = 100; - let offset = 0; - let numDownloaded = 0; - - while (1) { - const endDate = monthUtils.currentDay(); - - const res = await post(getServer().PLAID_SERVER + '/transactions', { - userId, - key: userKey, - item_id: '' + bankId, - account_id: acctId, - start_date: since, - end_date: endDate, - count: pageSize, - offset, - }); - - if (res.error_code) { - throw BankSyncError(res.error_type, res.error_code); - } - - if (res.transactions.length === 0) { - break; - } - - numDownloaded += res.transactions.length; - - // Remove pending transactions for now - we will handle them in - // the future. - allTransactions = allTransactions.concat( - res.transactions.filter(t => !t.pending), - ); - accountBalance = getAccountBalance(res.accounts[0]); - - if ( - numDownloaded === res.total_transactions || - (count != null && allTransactions.length >= count) - ) { - break; - } - - offset += pageSize; - } - - allTransactions = - count != null ? allTransactions.slice(0, count) : allTransactions; - - return { - transactions: allTransactions.map(fromPlaid), - accountBalance, - }; -} - async function downloadGoCardlessTransactions( userId, userKey, @@ -745,29 +652,8 @@ export async function syncAccount( startDate, ); } else { - // Get all transactions since the latest transaction, plus any 5 - // days before the latest transaction. This gives us a chance to - // resolve any transactions that were entered manually. - // - // TODO: What this really should do is query the last imported_id - // and since then - let date = monthUtils.subDays( - db.fromDateRepr(latestTransaction.date), - 31, - ); - - // Never download transactions before the starting date. This was - // when the account was added to the system. - if (date < startingDate) { - date = startingDate; - } - - download = await downloadTransactions( - userId, - userKey, - acctId, - bankId, - date, + throw new Error( + `Unrecognized bank-sync provider: ${acctRow.account_sync_source}`, ); } diff --git a/packages/loot-core/src/server/main.ts b/packages/loot-core/src/server/main.ts index 7fd73231948cc36dcc4adc170527c615ec86a990..aa13465ac81cc9ad8457e88ca64f3768084ac9d5 100644 --- a/packages/loot-core/src/server/main.ts +++ b/packages/loot-core/src/server/main.ts @@ -567,25 +567,6 @@ handlers['query'] = async function (query) { return aqlQuery(query); }; -handlers['bank-delete'] = async function ({ id }) { - const accts = await db.runQuery( - 'SELECT * FROM accounts WHERE bank = ?', - [id], - true, - ); - - await db.delete_('banks', id); - await Promise.all( - accts.map(async acct => { - // TODO: This will not sync across devices because we are bypassing - // the "recorded" functions - await db.runQuery('DELETE FROM transactions WHERE acct = ?', [acct.id]); - await db.delete_('accounts', acct.id); - }), - ); - return 'ok'; -}; - handlers['account-update'] = mutator(async function ({ id, name }) { return withUndo(async () => { await db.update('accounts', { id, name }); @@ -720,21 +701,6 @@ handlers['simplefin-accounts-link'] = async function ({ return 'ok'; }; -handlers['gocardless-accounts-connect'] = async function ({ - institution, - publicToken, - accountIds, - offbudgetIds, -}) { - const bankId = await link.handoffPublicToken(institution, publicToken); - const ids = await link.addGoCardlessAccounts( - bankId, - accountIds, - offbudgetIds, - ); - return ids; -}; - handlers['account-create'] = mutator(async function ({ name, balance, @@ -777,8 +743,8 @@ handlers['account-close'] = mutator(async function ({ categoryId, forced, }) { - // Unlink the account if it's linked. This makes sure to remove it - // from Plaid. (This should not be undo-able, as it mutates the + // Unlink the account if it's linked. This makes sure to remove it from + // bank-sync providers. (This should not be undo-able, as it mutates the // remote server and the user will have to link the account again) await handlers['account-unlink']({ id }); @@ -878,142 +844,6 @@ handlers['account-move'] = mutator(async function ({ id, targetId }) { let stopPolling = false; -handlers['poll-web-token'] = async function ({ token }) { - const [[, userId], [, key]] = await asyncStorage.multiGet([ - 'user-id', - 'user-key', - ]); - - const startTime = Date.now(); - stopPolling = false; - - async function getData(cb) { - if (stopPolling) { - return; - } - - if (Date.now() - startTime >= 1000 * 60 * 10) { - cb('timeout'); - return; - } - - const data = await post( - getServer().PLAID_SERVER + '/get-web-token-contents', - { - userId, - key, - token, - }, - ); - - if (data) { - if (data.error) { - cb('unknown'); - } else { - cb(null, data); - } - } else { - setTimeout(() => getData(cb), 3000); - } - } - - return new Promise(resolve => { - getData((error, data) => { - if (error) { - resolve({ error }); - } else { - resolve({ data }); - } - }); - }); -}; - -handlers['poll-web-token-stop'] = async function () { - stopPolling = true; - return 'ok'; -}; - -handlers['accounts-sync'] = async function ({ id }) { - const [[, userId], [, userKey]] = await asyncStorage.multiGet([ - 'user-id', - 'user-key', - ]); - let accounts = await db.runQuery( - `SELECT a.*, b.id as bankId FROM accounts a - LEFT JOIN banks b ON a.bank = b.id - WHERE a.tombstone = 0 AND a.closed = 0`, - [], - true, - ); - - if (id) { - accounts = accounts.filter(acct => acct.id === id); - } - - const errors = []; - let newTransactions = []; - let matchedTransactions = []; - let updatedAccounts = []; - - for (let i = 0; i < accounts.length; i++) { - const acct = accounts[i]; - if (acct.bankId) { - try { - const res = await bankSync.syncAccount( - userId, - userKey, - acct.id, - acct.account_id, - acct.bankId, - ); - const { added, updated } = res; - - newTransactions = newTransactions.concat(added); - matchedTransactions = matchedTransactions.concat(updated); - - if (added.length > 0 || updated.length > 0) { - updatedAccounts = updatedAccounts.concat(acct.id); - } - } catch (err) { - if (err.type === 'BankSyncError') { - errors.push({ - type: 'SyncError', - accountId: acct.id, - message: 'Failed syncing account “' + acct.name + '.â€', - category: err.category, - code: err.code, - }); - } else if (err instanceof PostError && err.reason !== 'internal') { - errors.push({ - accountId: acct.id, - message: `Account “${acct.name}†is not linked properly. Please link it again`, - }); - } else { - errors.push({ - accountId: acct.id, - message: - 'There was an internal error. Please get in touch https://actualbudget.org/contact for support.', - internal: err.stack, - }); - - err.message = 'Failed syncing account: ' + err.message; - - captureException(err); - } - } - } - } - - if (updatedAccounts.length > 0) { - connection.send('sync-event', { - type: 'success', - tables: ['transactions'], - }); - } - - return { errors, newTransactions, matchedTransactions, updatedAccounts }; -}; - handlers['secret-set'] = async function ({ name, value }) { const userToken = await asyncStorage.getItem('user-token'); @@ -1370,25 +1200,6 @@ handlers['account-unlink'] = mutator(async function ({ id }) { return 'ok'; }); -handlers['make-plaid-public-token'] = async function ({ bankId }) { - const [[, userId], [, userKey]] = await asyncStorage.multiGet([ - 'user-id', - 'user-key', - ]); - - const data = await post(getServer().PLAID_SERVER + '/make-public-token', { - userId, - key: userKey, - item_id: '' + bankId, - }); - - if (data.error_code) { - return { error: '', code: data.error_code, type: data.error_type }; - } - - return { linkToken: data.link_token }; -}; - handlers['save-global-prefs'] = async function (prefs) { if ('maxMonths' in prefs) { await asyncStorage.setItem('max-months', '' + prefs.maxMonths); diff --git a/packages/loot-core/src/server/server-config.ts b/packages/loot-core/src/server/server-config.ts index 446d88eb03555e7f0eff5c7cd059e520cc8da556..79f4933254e07ff76142875b4d71aedd79d0e1df 100644 --- a/packages/loot-core/src/server/server-config.ts +++ b/packages/loot-core/src/server/server-config.ts @@ -4,7 +4,6 @@ type ServerConfig = { BASE_SERVER: string; SYNC_SERVER: string; SIGNUP_SERVER: string; - PLAID_SERVER: string; GOCARDLESS_SERVER: string; SIMPLEFIN_SERVER: string; }; @@ -32,7 +31,6 @@ export function getServer(url?: string): ServerConfig | null { BASE_SERVER: url, SYNC_SERVER: joinURL(url, '/sync'), SIGNUP_SERVER: joinURL(url, '/account'), - PLAID_SERVER: joinURL(url, '/plaid'), GOCARDLESS_SERVER: joinURL(url, '/gocardless'), SIMPLEFIN_SERVER: joinURL(url, '/simplefin'), }; diff --git a/packages/loot-core/src/server/tests/mockSyncServer.ts b/packages/loot-core/src/server/tests/mockSyncServer.ts index 4852c0955078d9fe2d8115d82b3d83d440a9f61b..08d3eb4018102c25769127acdedc6b2191ed13db 100644 --- a/packages/loot-core/src/server/tests/mockSyncServer.ts +++ b/packages/loot-core/src/server/tests/mockSyncServer.ts @@ -78,34 +78,11 @@ handlers['/sync/sync'] = async (data: Uint8Array): Promise<Uint8Array> => { return responsePb.serializeBinary(); }; -handlers['/plaid/handoff_public_token'] = () => { - // Do nothing -}; - -handlers['/plaid/accounts'] = () => { +handlers['/gocardless/accounts'] = () => { // Ignore the parameters and just return the accounts. return { accounts: currentMockData.accounts }; }; -handlers['/plaid/transactions'] = ({ - account_id, - start_date, - end_date, - count, - offset, -}) => { - const accounts = currentMockData.accounts; - const transactions = currentMockData.transactions[account_id].filter( - t => t.date >= start_date && t.date <= end_date, - ); - - return { - accounts: accounts.filter(acct => acct.account_id === account_id), - transactions: transactions.slice(offset, offset + count), - total_transactions: transactions.length, - }; -}; - export const filterMockData = func => { const copied = JSON.parse(JSON.stringify(defaultMockData)); currentMockData = func(copied); diff --git a/packages/loot-core/src/types/server-handlers.d.ts b/packages/loot-core/src/types/server-handlers.d.ts index 476bbeaa97b33016e641e993e3603ede5a0280ee..9610727fb9dd667788ddf0e63ee6b2f7539db69b 100644 --- a/packages/loot-core/src/types/server-handlers.d.ts +++ b/packages/loot-core/src/types/server-handlers.d.ts @@ -139,8 +139,6 @@ export interface ServerHandlers { query: (query) => Promise<{ data; dependencies }>; - 'bank-delete': (arg: { id }) => Promise<unknown>; - 'account-update': (arg: { id; name }) => Promise<unknown>; 'accounts-get': () => Promise<AccountEntity[]>; @@ -160,13 +158,6 @@ export interface ServerHandlers { upgradingId; }) => Promise<'ok'>; - 'gocardless-accounts-connect': (arg: { - institution; - publicToken; - accountIds; - offbudgetIds; - }) => Promise<unknown>; - 'account-create': (arg: { name: string; balance?: number; @@ -185,17 +176,6 @@ export interface ServerHandlers { 'account-move': (arg: { id; targetId }) => Promise<unknown>; - 'poll-web-token': (arg: { token }) => Promise<unknown>; - - 'poll-web-token-stop': () => Promise<'ok'>; - - 'accounts-sync': (arg: { id? }) => Promise<{ - errors: unknown; - newTransactions: unknown; - matchedTransactions: unknown; - updatedAccounts: unknown; - }>; - 'secret-set': (arg: { name: string; value: string }) => Promise<null>; 'secret-check': (arg: string) => Promise<string | { error?: string }>; @@ -247,10 +227,6 @@ export interface ServerHandlers { 'account-unlink': (arg: { id }) => Promise<'ok'>; - 'make-plaid-public-token': (arg: { - bankId; - }) => Promise<{ error: ''; code; type } | { linkToken }>; - 'save-global-prefs': (prefs) => Promise<'ok'>; 'load-global-prefs': () => Promise<GlobalPrefs>; diff --git a/upcoming-release-notes/2616.md b/upcoming-release-notes/2616.md new file mode 100644 index 0000000000000000000000000000000000000000..dfc9abeed0b18105d85f959f6cc20061fe2aeedc --- /dev/null +++ b/upcoming-release-notes/2616.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +Delete old Plaid integration that is no longer working.