From 1f7a3edba28f9af3e371214cec0746ed1d03516d Mon Sep 17 00:00:00 2001 From: projectmoon Date: Tue, 21 Mar 2023 14:05:31 +0100 Subject: [PATCH] Add content script and message passing to begin txn downloading --- package.json | 1 + .../auth-state-handler.ts} | 4 +-- src/background/message-handler.ts | 26 +++++++++++++++ src/content-script.ts | 33 ------------------- src/content-scripts/statement-page.tsx | 27 +++++++++++++++ src/manifest.json | 7 ++-- src/tsconfig.json | 2 +- todo.org | 13 +++++--- yarn.lock | 12 +++++++ 9 files changed, 81 insertions(+), 44 deletions(-) rename src/{background.ts => background/auth-state-handler.ts} (93%) create mode 100644 src/background/message-handler.ts delete mode 100644 src/content-script.ts create mode 100644 src/content-scripts/statement-page.tsx diff --git a/package.json b/package.json index e9fc8d8..45687f7 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "date-fns": "^2.29.3", "graphql": "^16.6.0", "graphql-request": "^5.2.0", + "jsx-dom": "^8.0.5", "level": "^8.0.0" } } diff --git a/src/background.ts b/src/background/auth-state-handler.ts similarity index 93% rename from src/background.ts rename to src/background/auth-state-handler.ts index 9a80ed0..8128350 100644 --- a/src/background.ts +++ b/src/background/auth-state-handler.ts @@ -1,7 +1,7 @@ const matchGraphQL = { urls: ["https://graphql.landsbankinn.is/v2"] }; -import { fetchAccounts } from './landsbankinn'; -import { PartialStateUpdate, State } from './state'; +import { fetchAccounts } from '~/src/landsbankinn'; +import { PartialStateUpdate, State } from '~/src/state'; type HttpHeaders = browser.webRequest.HttpHeaders; diff --git a/src/background/message-handler.ts b/src/background/message-handler.ts new file mode 100644 index 0000000..3cbd7e6 --- /dev/null +++ b/src/background/message-handler.ts @@ -0,0 +1,26 @@ +import { State } from "~/src/state"; + +enum Actions { + GetAccounts = 'GET_ACCOUNTS', + DownloadTransactions = 'DOWNLOAD_TRANSACTIONS' +} + +type MessageSender = browser.runtime.MessageSender; + +async function getAccounts(sender: MessageSender): Promise { + //TODO somehow ensure state exists. + const message = { + accounts: (await State.current).accounts + }; + + browser.tabs.sendMessage(sender.tab?.id!, message); +} + +browser.runtime.onMessage.addListener((message, sender) => { + switch (message.action) { + case Actions.GetAccounts: + getAccounts(sender); + } +}); + +export { } diff --git a/src/content-script.ts b/src/content-script.ts deleted file mode 100644 index 0d184e9..0000000 --- a/src/content-script.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { setDefaultOptions, parse, format } from 'date-fns'; -import { enUS } from 'date-fns/locale'; -import { fetchAccounts, OutputFormat, DownloadTransactionsRequest, downloadTransactions } from './landsbankinn'; - -setDefaultOptions({ locale: enUS }); - - -//First attempt hardcoded data -async function doIt() { - console.log('doing it'); - const from = parse('01 Jan 2023', 'dd MMM yyyy', new Date()); - console.log(from); - const to = parse('31 Jan 2023', 'dd MMM yyyy', new Date()); - const req: DownloadTransactionsRequest = { - accountNumber: '010126013792', - dateFrom: from, - dateTo: to, - outputFormat: OutputFormat.CSV, - }; - - const txns = await downloadTransactions(req); - console.log(txns); -} - -//doIt().then(() => alert('did it')); - -async function fetchIt() { - console.log('fetching it'); - const data = fetchAccounts(); - console.log(data); -} - -//fetchIt().then(() => alert('fetched it')); diff --git a/src/content-scripts/statement-page.tsx b/src/content-scripts/statement-page.tsx new file mode 100644 index 0000000..72190af --- /dev/null +++ b/src/content-scripts/statement-page.tsx @@ -0,0 +1,27 @@ +import React from 'jsx-dom'; + +async function populateAccounts() { + const resp = await browser.runtime.sendMessage({ + action: 'GET_ACCOUNTS', + }); +} + +//Add an element to the statement page +document.addEventListener('DOMContentLoaded', async () => { + const contentDiv = document.querySelector('div[class="table-data content-box fill shadow"]'); + contentDiv?.prepend( +
+

Download Transaction Statements

+

+ Here, you can export statements from one or more of your accounts + over a specified date range. +

+
+ ); + + await populateAccounts(); +}); + +browser.runtime.onMessage.addListener((message, sender) => { + console.log('message received!', message); +}); diff --git a/src/manifest.json b/src/manifest.json index c28271e..c37a51a 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -9,11 +9,12 @@ "webRequestBlocking" ], "background": { - "scripts": [ "background.ts" ], + "scripts": [ "background/auth-state-handler.ts", "background/message-handler.ts" ], "persistent": false }, "content_scripts": [{ - "matches": ["https://netbanki.landsbankinn.is/*", "https://graphql.landsbankinn.is/v2"], - "js": ["content-script.ts"] + "matches": ["https://netbanki.landsbankinn.is/Ebli/Statements/ClientSummary.aspx"], + "js": ["content-scripts/statement-page.tsx"], + "run_at": "document_start" }] } diff --git a/src/tsconfig.json b/src/tsconfig.json index ac7ef9a..c8db7f4 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -7,8 +7,8 @@ "allowSyntheticDefaultImports": true, "lib": [ "dom", "es6" ], "jsx": "react-jsx", - "esModuleInterop": true, "jsxImportSource": "jsx-dom", + "esModuleInterop": true, "isolatedModules": true, "moduleResolution": "node", "baseUrl": ".", diff --git a/todo.org b/todo.org index 03c3745..f98a4ce 100644 --- a/todo.org +++ b/todo.org @@ -3,8 +3,11 @@ How to get it working: - [ ] Transform raw transactions into friendlier ones (i.e. date objects) - [ ] Content script that can run all the time and puts a button somewhere (statements tab, and extension icon) - [ ] Background page that downloads all the shit and combines into CSV, then 'downloads' file. - - [ ] Graphql API client to get information about user, like listing accounts. - - [ ] Get working client - - [ ] Set API key - - [ ] Set bearer token - - [ ] Intercept bearer token by yoinking it out of a request + - [ ] Build up communication message passing to background page for downloads + - [ ] Investigate persistent = false + setTimeout + - [ ] Maybe can force clear state when page reloads itself? + - [X] Graphql API client to get information about user, like listing accounts. + - [X] Get working client + - [X] Set API key + - [X] Set bearer token + - [X] Intercept bearer token by yoinking it out of a request diff --git a/yarn.lock b/yarn.lock index 426c1f5..52a47e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1076,6 +1076,11 @@ csso@^4.2.0: dependencies: css-tree "^1.1.2" +csstype@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" + integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== + date-fns@^2.29.3: version "2.29.3" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8" @@ -1317,6 +1322,13 @@ json5@^2.2.0, json5@^2.2.1: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== +jsx-dom@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/jsx-dom/-/jsx-dom-8.0.5.tgz#63b45ae2c583bec37c4e1003e608e5658c2b0f32" + integrity sha512-Dt4PLuFFm16Qj1TH0GSx6LdrfnrPSh5lEHG87Hd4lv9nDWGD3ZtUdp5RXH7GyEWI0E+19eoUDFcyO5dnJQ/4IQ== + dependencies: + csstype "^3.1.1" + level-supports@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a"