@ -1,19 +0,0 @@
|
||||
const { Logger } = require('winston');
|
||||
const Postgres = require('winston-pg-native');
|
||||
|
||||
const logger = new Logger({
|
||||
transports: [
|
||||
new Postgres({
|
||||
'postgres://budget:budget@sql.caseytimm.com:5432/budget',
|
||||
level: 'info',
|
||||
poolConfig: {
|
||||
connectionTimeoutMillis: 0,
|
||||
idleTimeoutMillis: 0,
|
||||
max: 10
|
||||
},
|
||||
tableName: 'winston_logs'
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
module.exports = logger;
|
||||
@ -1,7 +1,5 @@
|
||||
import db from './db.js';
|
||||
import { chromium } from 'patchright';
|
||||
import logger from './logger.js';
|
||||
import { log } from 'echarts/types/src/util/log.js';
|
||||
|
||||
//const browser = await chromium.launch();
|
||||
let state = [];
|
||||
@ -23,8 +21,6 @@ export function isNeedCode() {
|
||||
export function isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
logger.info('Launching browser for United FCU data pull');
|
||||
const browser = await chromium.launchPersistentContext('context', {
|
||||
channel: 'chrome',
|
||||
headless: false,
|
||||
@ -37,16 +33,14 @@ export async function pullData(amount = 100) {
|
||||
state = [];
|
||||
code = null;
|
||||
needCode = false;
|
||||
state.push('Starting Browser');
|
||||
|
||||
|
||||
logger.info('Starting data pull for United FCU');
|
||||
state.push('Starting data pull for United FCU');
|
||||
const page = await browser.newPage();
|
||||
try {
|
||||
|
||||
logger.info('Navigating to United FCU');
|
||||
state.push('Navigating to United FCU');
|
||||
await page.goto('https://online.unitedfcu.com/unitedfederalcredituniononline/uux.aspx#/login');
|
||||
logger.info(`Current URL: ${page.url()}`);
|
||||
state.push(`Current URL: ${page.url()}`);
|
||||
|
||||
if (page.url().includes('interstitial')) {
|
||||
@ -54,7 +48,6 @@ export async function pullData(amount = 100) {
|
||||
}
|
||||
|
||||
if (!page.url().includes('dashboard')) {
|
||||
logger.info('Logging in to United FCU');
|
||||
state.push('Logging in to United FCU');
|
||||
await new Promise((resolve) => setTimeout(resolve, Math.random() * 5000));
|
||||
await page.getByLabel('Login ID').fill('92830');
|
||||
@ -72,11 +65,9 @@ export async function pullData(amount = 100) {
|
||||
}
|
||||
|
||||
const url = page.url();
|
||||
logger.info(`Current URL after login: ${url}`);
|
||||
state.push(`Current URL after login: ${url}`);
|
||||
|
||||
if (url.includes('mfa/targets')) {
|
||||
logger.info('MFA required, selecting SMS option');
|
||||
state.push('MFA required, selecting SMS option');
|
||||
console.log('MFA required, please complete the authentication process.');
|
||||
await new Promise((resolve) => setTimeout(resolve, Math.random() * 5000));
|
||||
@ -84,7 +75,6 @@ export async function pullData(amount = 100) {
|
||||
await page.waitForURL('**/mfa/entertarget');
|
||||
await page.getByPlaceholder('Secure Access Code');
|
||||
//await page.keyboard.press('Tab');
|
||||
logger.info('Waiting for user to provide code');
|
||||
state.push('Waiting for code input');
|
||||
needCode = true;
|
||||
for (let i = 0; i < 5 * 60; i++) {
|
||||
@ -94,10 +84,8 @@ export async function pullData(amount = 100) {
|
||||
if (code == null) {
|
||||
needCode = false;
|
||||
state.push('Code not provided within 5 minutes');
|
||||
logger.error('Code not provided within 5 minutes');
|
||||
throw new Error('Code not provided within 5 minutes');
|
||||
}
|
||||
logger.info(`Got code: ${code}`);
|
||||
state.push(`Got code: ${code}`);
|
||||
await page.getByPlaceholder('Secure Access Code').fill(code);
|
||||
await new Promise((resolve) => setTimeout(resolve, Math.random() * 5000));
|
||||
@ -108,16 +96,14 @@ export async function pullData(amount = 100) {
|
||||
await page.keyboard.press('Tab');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForURL('**/dashboard');
|
||||
logger.info('Logged in successfully');
|
||||
await page.screenshot({ path: 'united-login.png' });
|
||||
state.push('Logged in successfully');
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('Fetching q2token');
|
||||
state.push('Fetching q2token');
|
||||
const q2token = (await browser.cookies()).find((cookie) => cookie.name === 'q2token')?.value;
|
||||
|
||||
logger.info('q2token:', q2token);
|
||||
console.log('q2token:', q2token);
|
||||
|
||||
page.setExtraHTTPHeaders({
|
||||
@ -152,7 +138,6 @@ export async function pullData(amount = 100) {
|
||||
});
|
||||
|
||||
for (const account of accountsJsonResponse.data) {
|
||||
logger.info(`Account ID: ${account.id}, Name: ${account.name}`);
|
||||
console.log(`Account ID: ${account.id}, Name: ${account.name}`);
|
||||
if (accountsToPull.map((a) => a.id).includes(`${account.id}`)) {
|
||||
const balance =
|
||||
@ -165,14 +150,11 @@ export async function pullData(amount = 100) {
|
||||
balance = EXCLUDED.balance,
|
||||
balance_date = EXCLUDED.balance_date`;
|
||||
console.log(`Account ID: ${account.id}, Balance: ${balance}`);
|
||||
logger.info(`Account ID: ${account.id}, Balance: ${balance}`);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('Fetching transactions for accounts');
|
||||
state.push('Fetching transactions for accounts');
|
||||
for (const account of accountsToPull) {
|
||||
logger.info(`Fetching transactions for account ID: ${account.id}`);
|
||||
state.push(`Fetching transactions for account ID: ${account.id}`);
|
||||
await new Promise((resolve) => setTimeout(resolve, Math.random() * 5000));
|
||||
|
||||
@ -188,45 +170,34 @@ export async function pullData(amount = 100) {
|
||||
|
||||
const transactions = jsonResponse.data.transactions;
|
||||
if (transactions.length === 0) {
|
||||
logger.info(`No transactions found for account ID: ${account.id}`);
|
||||
state.push(`No transactions found for account ID: ${account.id}`);
|
||||
continue;
|
||||
}
|
||||
logger.info(`Found ${transactions.length} transactions for account ID: ${account.id}`);
|
||||
state.push(`Found ${transactions.length} transactions for account ID: ${account.id}`);
|
||||
|
||||
const cardRegEx = /\d{4}$/;
|
||||
|
||||
// Check if any pending need to be updated
|
||||
|
||||
logger.info(`Checking for pending transactions for account ID: ${account.id}`);
|
||||
state.push(`Checking for pending transactions for account ID: ${account.id}`);
|
||||
let currentPend =
|
||||
await db`SELECT id, amount, description, date from transaction where account_id = ${account.id} AND pending=true`;
|
||||
for (const pend of currentPend) {
|
||||
const found = transactions.find((t) => t.transactionId === pend.id);
|
||||
logger.info(`Checking pending transaction: ${pend.id}, found: ${!!found}`);
|
||||
logger.info(`Pending transaction amount: ${pend.amount}, date: ${pend.date}`);
|
||||
if (!found) {
|
||||
const updated = transactions.find(
|
||||
(t) => t.amount == pend.amount && new Date(t.postedDate) == pend.date
|
||||
);
|
||||
logger.info(`Updated transaction for pending: ${pend.id}, found: ${!!updated}`);
|
||||
|
||||
if (updated) {
|
||||
state.push(
|
||||
`I think I found an updated transaction: ${updated.statementDescription} ${updated.amount} for ${pend.description} ${pend.amount}`
|
||||
);
|
||||
logger.info(`I think I found an updated transaction: ${updated.statementDescription} ${updated.amount} for ${pend.description} ${pend.amount}`);
|
||||
|
||||
|
||||
await db`UPDATE budget_transaction SET transaction_id = ${updated.transactionId} WHERE transaction_id = ${pend.id}`;
|
||||
} else {
|
||||
state.push(`No updated transaction found for pending: ${pend.id}`);
|
||||
state.push(`Orphaning no longer pending budget transaction with no new parent`);
|
||||
await db`UPDATE budget_transaction SET transaction_id = null WHERE transaction_id = ${pend.id}`;
|
||||
}
|
||||
logger.info(`Removing pending transaction: ${pend.id}`);
|
||||
state.push(`Removing pending transaction: ${pend.id}`);
|
||||
await db`DELETE FROM transaction WHERE id = ${pend.id}`;
|
||||
}
|
||||
@ -278,7 +249,6 @@ export async function pullData(amount = 100) {
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('Orphaning transactions');
|
||||
state.push('Orphaning transactions');
|
||||
|
||||
const orphaned = await db`SELECT bt.id as id
|
||||
@ -286,7 +256,6 @@ export async function pullData(amount = 100) {
|
||||
LEFT OUTER JOIN transaction t ON bt.transaction_id = t.id
|
||||
WHERE t.id IS NULL;`;
|
||||
for (const orphan of orphaned) {
|
||||
logger.info(`Orphaning transaction: ${orphan.id}`);
|
||||
state.push(`Orphaning transaction: ${orphan.id}`);
|
||||
await db`UPDATE budget_transaction set transaction_id = null where id = ${orphan.id}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user