Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API-Authentication? #39

Open
ThreeCO opened this issue Nov 13, 2024 · 8 comments
Open

API-Authentication? #39

ThreeCO opened this issue Nov 13, 2024 · 8 comments

Comments

@ThreeCO
Copy link
Contributor

ThreeCO commented Nov 13, 2024

At first I have to say what a great project you started here! I found it by accident but I'm quite sure I'll love it!

I'm thinking about building iOS-Automations to ex-/import my last weight and latest activities; that should be possible using the API, I assume. Right now I'm struggling how you want the API-Authentication to happen.

  • Presumably I'll need to talk to the backend directly, when I want to use the Api?
  • How exactly should I authenticate against the API in order to get the tokens?

could you please give a short (complete) example or point me to a certain link or something?

Many thanks in advance!

@joaovitoriasilva
Copy link
Owner

joaovitoriasilva commented Nov 13, 2024

Hello. Thanks for reaching out and thanks for the feedback.

Regarding your question, I really love it. I have an iOS device and I never thought of this. To be honest I never used iOS automations so I am kind of a noob there.

As stated in the readme:

  • For web apps, the backend sends access/refresh tokens as HTTP-only cookies.
  • For mobile apps, tokens are included in the response body.
  • Add a header: Every request must include an X-Client-Type header with either web or mobile as the value. Requests with other values will receive a 403 error.
  • Activity Upload: Use the /activities/create/upload endpoint (expects a .gpx or .fit file).

For authentication the endpoint is /token and for the refresh token action the endpoint is /refresh. The access token is short lived (15min) and the refresh token is long lived (7days).

So in order to reach the API, and assuming you are using the default port, for authentication you have to call something like http://localhost:98/token or http://server-ip-address:98/token or https://domain/token

Then for the automation the automation should check if access and refresh token exists, if yes do a request with the access token, for example upload an activity. If the server responds with 401 or 403, call the refresh endpoint and get a new pair and then call the original endpoint. If no pair exists call the /token to get the pair.

Makes sense?

If you make it work I would love your contribution in documenting this for other people to use it.

@ThreeCO
Copy link
Contributor Author

ThreeCO commented Nov 15, 2024

First things first: Thanks for the hints. It works like a charm!

Basically you'll need to follow these steps

  1. Create a Shortcut in the App
  2. click on "i" and select "Show in Share-Sheet"
  3. Login using "Get Content From URL" [method = post; header "X-Content-Type" = mobile; FORM; username=xx; password=yy]
  4. Use a Dictionary to extract access_token and refresh_token
  5. Send file using "Get Content From URL" [method=post; header "X-Content-Type"=mobile; header "Authorization"=Bearer access_token; FORM; file = select file from top (ShareSheet)

These are the steps. since i don't know how to save access-/refresh token the script always performs a new login; i don't think that's bad. Of course you'll need another app that lets you export .fit or .gpx files - personally i use HealthFit for that.

using the same way of authentication we could write heartrate, weight etc. from apple health to endurain. is there an api for that already?

@joaovitoriasilva
Copy link
Owner

Hi. Thanks for the response.

For weight it can be used the "/health/weight" endpoint.

The endpoint expects this class:
class HealthData(BaseModel):
id: int | None = None
user_id: int | None = None
created_at: date | None = None
weight: float | None = None

You should only need to specify weight and created_at, where created_at is the date when the weight was taken.

Regarding health data, only weight is currently supported, but I intend to support others stats in the future.

@ThreeCO
Copy link
Contributor Author

ThreeCO commented Nov 15, 2024

Indeed works using the same authentication workflow.
in order to submit my weight I had to send an JSON-Object (instead of FORM)
{ weight: <weight>, created_at: <date: yyyy-mm-dd>}

@joaovitoriasilva
Copy link
Owner

Awesome. Glad it worked out. I am creating a documentation site using MKDocs integrated with GitHub Pages. Would you be interested in contributing to it with a guide with screenshots and etc regarding this?

@ThreeCO
Copy link
Contributor Author

ThreeCO commented Nov 16, 2024

For sure I will support your awesome project 👍 How will it work? Probably not as usual with forking and merging?!

@joaovitoriasilva
Copy link
Owner

Yes, the usual. I will release v0.6.0 next week probably and the /docs folder will have content (currently is empty) and you will be able to contribute for the docs editing in there.

Also, in v0.6.0, the api endpoints will have the prefix "/api/v1" so for example the token endpoint will be "/api/v1/token" instead of only "/token". This is in preparation for the AIO docker image.

@joaovitoriasilva
Copy link
Owner

Hello. v0.6.0 is released and the new docs page is available at https://docs.endurain.com.
Docs logic is inside the /docs folder https://github.com/joaovitoriasilva/endurain/tree/master/docs

Thanks again for being available to contribute on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants