jhonderson / actual-http-api

Basic Actual Budget API exposed through HTTP endpoints
MIT License
40 stars 9 forks source link

Fetch API cannot load due to access control checks. #14

Closed culpeppers closed 3 months ago

culpeppers commented 3 months ago

I currently have Actual and actual-http-api running in Docker, using Host network, on Unraid. When using Swagger, after entering the API key and budget sync ID for any of the methods: I get the following error on the page: TypeError: Load failed

Checking the browser console shows the following: [Error] Could not connect to the server. [Error] Fetch API cannot load due to access control checks. [Error] Failed to load resource: Could not connect to the server. (accounts, line 0)

Any help would be greatly appreciated, thank you!

culpeppers commented 3 months ago

Additional info, when trying on another browser I get: TypeError: NetworkError when attempting to fetch resource.

Console shows: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at <actual-http-api method path. (Reason: CORS request did not succeed). Status code: (null).

jhonderson commented 3 months ago

Hey, I’ve seen this happening when you put the Actual URL in the swagger host server variable. Instead you should put the Actual API URL, I.e actualapi.myhosting.com

Let me know if this is the case

culpeppers commented 3 months ago

I think I have it all configured correctly, if not let me know.

Screenshot 2024-05-30 at 9 04 21 AM Screenshot 2024-05-30 at 9 05 43 AM
smdion commented 3 months ago

I ran into this as well, its because the API browser is locked to localhost for HTTP and you are using a different computer/IP to access it. You need to put the API behind a reverse proxy/https and use the servers dropdown at the top to add the FQDN via the reverse proxy (npm/swag). Also, hello fellow unraid user.

image

culpeppers commented 3 months ago

@smdion hello!

That is really interesting, thank you. To be honest, that really doesn't feel right that I need to expose it like that just to use it.

FreddyAbrego commented 3 months ago

It's not using the swagger page, but I've had success using Postman to perform the API requests

smdion commented 3 months ago

@smdion hello!

That is really interesting, thank you. To be honest, that really doesn't feel right that I need to expose it like that just to use it.

You can lock it down to just local/lan with

allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
deny all;

And then don't resolve it externally.

culpeppers commented 3 months ago

I just tried Postman and I am getting a different error now.

From actual-http-api logs: Error accessing Actual Server, check Actual Server password Error: Could not get remote files at handlers.api/download-budget (/usr/src/app/node_modules/@actual-app/api/dist/app/bundle.api.js:34770:31) Ignoring unhandledRejection caused by Actual api library

I have verified that the URL and password are correct.

smdion commented 3 months ago

I just tried Postman and I am getting a different error now.

From actual-http-api logs: Error accessing Actual Server, check Actual Server password Error: Could not get remote files at handlers.api/download-budget (/usr/src/app/node_modules/@actual-app/api/dist/app/bundle.api.js:34770:31) Ignoring unhandledRejection caused by Actual api library

I have verified that the URL and password are correct.

I got this the first time I ran it, but not every subsequent time....

culpeppers commented 3 months ago

It happens every time I try to use the API. I can't figure out if its a password issue, or an issue connecting to Actual, or something else.

I appreciate everyone's help!

FreddyAbrego commented 3 months ago

I don't know if it makes much of a difference. But try ending the ACTUAL_SERVER_URL with a '/' ?

culpeppers commented 3 months ago

Fair thought. Just tried that, same issue.

Looking through this code and the logs, it's looking like the actualAPI object is being initialized correctly. So I'm guessing that means it can connect to the server at least. For some reason, though, its having trouble getting the remote files.

FreddyAbrego commented 3 months ago

I'm unfamiliar with, I think it's unraid you're using, does it restart the container after the variables change? If not restart it.

If that doesn't help, can you send a pic of your request in postman?

culpeppers commented 3 months ago

It does, but I've restarted it manually also with no luck. Here's my postman request

Screenshot 2024-05-31 at 1 31 02 PM
FreddyAbrego commented 3 months ago

Are there are any special characters like a / or ' in your ACTUAL_SERVER_PASSWORD, maybe something is escaping it early?

culpeppers commented 3 months ago

The only special character is an exclamation point.

jhonderson commented 3 months ago

Hey @culpeppers , can you check/try these?:

  1. Create a dummy budget file with no encryption, and change the password of Actual server to a simpler password temporarily (i.e no special characters). Then try to access the dummy budget through api. You can always change the password back to what it was I think
  2. Is your budget encrypted? (probably not since you would have mentioned it, but just checking)

If the api can't access the dummy budget, then we would discard the password/encryption part at least.

culpeppers commented 3 months ago

Hi @jhonderson!

I created a dummy budget, and changed the server password to 'password'. No encryption on the dummy budget.

Same error: "Error accessing Actual Server, check Actual Server password" Actual api client initialized successfully Error accessing Actual Server, check Actual Server password Error: Could not get remote files at handlers.api/download-budget (/usr/src/app/node_modules/@actual-app/api/dist/app/bundle.api.js:34770:31) Ignoring unhandledRejection caused by Actual api library

jhonderson commented 3 months ago

Well then the problem might be either a network issue or a version mismatch issue between actual api and actual budget. Can you try ssh’ing to your actual api container and pinging/curl the actual budget server curl http://<ip>:5006/login ? This is to see if the server is reachable from the api container (If they are in the same machine you can try using http://localhost:5006/ as server url too).

For the second option, what version of actual budget and actual api are you using ? Usually the container manager shows you the digest/sha code of each container.

culpeppers commented 3 months ago

I was able to ping my actual container from the api container.

Actual Budget: Client version: v24.5.0 Server version: v24.5.0

Actual API: I dont see a version in the manager, but its showing as pulling latest from https://hub.docker.com/r/jhonderson/actual-http-api/ and the api-docs show 1.0.0

jhonderson commented 3 months ago

Thanks.

I was reading the actual code to see what the problem could be, and I see some errors are not propagated nor traced into the logs: https://github.com/actualbudget/actual/blob/master/packages/loot-core/src/server/main.ts#L1505

Can you enter your actual-api container and do this curl:

curl 'http://<ip>:5006/account/login' -X POST \
-H 'Content-Type: application/json'\
--data-raw '{"password":"<your-password>"}'

This could show us the real reason why actual can't store the user token in the storage layer. If this succeeds my options would be over, and it might be a good idea to try to follow the steps from the actual-api nodejs documentation, and try to open a ticket to actual team, since your should face the exact same problem while using the nodejs api.

culpeppers commented 3 months ago

Well, I figured out the issue and it is definitely not what I expected...

'curl' wasn't installed in the container...once I installed it, everything started working perfectly. Can't thank you and everyone enough for your help.

Admittedly I am not super well-versed in Docker: is that something on your end, or in how the container is installed on Unraid?

jhonderson commented 3 months ago

Strange, since the actual api doesn’t need curl to work properly. Maybe restarting the container helped, or installing curl cleaned up some temporary files somewhere 🤔. Anyways I am glad it worked. Thanks all!

(feel free to close)