Add basically API documentation

This commit is contained in:
Jonas Lochmann 2020-05-04 02:00:00 +02:00
parent ab16134a8e
commit d021497e52
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
149 changed files with 7811 additions and 39 deletions

53
docs/api/README.md Normal file
View file

@ -0,0 +1,53 @@
# TimeLimit Server API documentation
The client communicates with the server using HTTP(S) requests
and a socket.io websocket connection.
All requests bodies (if any) and responses are encoded as JSON
if not said otherwise.
## /admin
This endpoint is for the server administrator.
Its interface is described at [admin.md](./admin.md).
## /auth
This endpoint is used for the user authentication.
Its interface is described at [auth.md](./auth.md).
## /child
This endpoint is used for by devices which are used by a child.
Its interface is described at [child.md](./child.md).
## /parent
This endpoint is used by devices which are used by a parent.
Its interface is described at [parent.md](./parent.md).
## /purchase
This endpoint is used for handling purchases from the client.
Its interface is described at [purchase.md](./purchase.md).
## /sync
This endpoint is used by clients for syncing.
Its interface is described at [sync.md](./sync.md).
## GET /time
This endpoint returns the current time of the server
as a Unix timestamp in milliseconds. This does not need
any authentication.
The response is a object with the property ``ms`` whose
value is the timestamp as number.
Example response: ``{"ms":1578311020747}``
## Websocket
The websocket is used for real time notifications from the server
to the client. The protocol is described at [websocket.md](./websocket.md).

88
docs/api/admin.md Normal file
View file

@ -0,0 +1,88 @@
# /admin
This endpoint is for the server admin.
Due to that, it requires authentication using the HTTP basic authentication.
The username can be anything, the password must be the configured admin token.
Additionally, this endpoint allows cross origin requests.
## GET /admin/status
Use this to get the server status.
## Response
This returns a JSON object with ``websocketClients`` (of the type number,
the number of clients connected using the websocket) and the map ``counters``
which maps values to numbers. You should not make any assumptions about the counter names
and their availability.
### example response
```
{
"websocketClients": 3,
"counters": {
"testCounter": 1
}
}
```
## POST /admin/reset-counters
Use this to reset the counters included in the server status.
Although this uses POST, it does not take any request body
Response: ``{"ok": true}``
## GET /admin/status-message
Use this to get the current status message.
This returns a object with the key ``statusMessage`` whose value
of the type string is the current status message.
Example response: ``{"statusMessage":""}``
### see
- [status message concept](../concept/status-message.md)
## POST /admin/status-message
Use this to set the status message.
Request body: object with ``message`` (string)
Response: ``{"ok": true}``
### see
- [status message concept](../concept/status-message.md)
## POST /admin/unlock-premium
Use this to unlock all features for one user for a specified duration.
### request
request properties: ``mail`` and ``duration``
- ``duration`` must be ``year`` or ``month``
- ``mail`` must be a mail address of any user assigned to the family for which the features should be unlocked
### response
If everything worked:
``{"ok": true}``
If the duration was invalid or no mail address was specified: HTTP status code 400 Bad Request
If there was nothing found for the mail address: HTTP status code 409 Conflict
### see
- [premium concept](../concept/premium.md)

86
docs/api/auth.md Normal file
View file

@ -0,0 +1,86 @@
# /auth
This endpoint is for the user authentication.
For this, mail addresses are used. The user starts
a authentication flow by sending the mail address.
Then the caller gets a mail login token and a
code is sent to the specified mail address.
After this, the caller can send the mail login token
and the code received by mail to get a mail auth token which can be
used at other APIs for creating a family, signing in into an existing family or
recovering a password.
## POST /auth/send-mail-login-code-v2
Use this to start authenticating.
### Request
see [this JSON schema](../schema/sendmaillogincoderequest.md)
#### example request
```
{
"mail": "test@timelimit.io",
"locale": "de"
}
```
### Response
If the request body is malformed or the mail address is invalid: HTTP status code 400 Bad Request
If the rate limit was exceeded: HTTP status code 429 Too Many Requests
If a whitelist was configured and the mail address is not within it: ``{"mailAddressNotWhitelisted": true}``
If a blacklist was configured and the mail server is within it: ``{"mailServerBlacklisted": true}``
On success: a object with a ``mailLoginToken`` of the type string
#### example response
```
{
"mailLoginToken": "dhdgfssgsdgd"
}
```
#### see
- [mail black and whitelist concept](../concept/mail-blackwhitelist.md)
## POST /auth/sign-in-by-mail-code
Use this to finish authenticating.
### Request
see [this JSON schema](../api/signinbymailcoderequest.md)
#### example request
```
{
"receivedCode": "ein test login",
"mailLoginToken": "dhdgfssgsdgd"
}
```
### Response
If the request body is malformed: HTTP status code 400 Bad Request
If there were to many wrong attempts: HTTP status code 410 Gone
If the mail login token is unknown: HTTP status code 410 Gone
If the received code is wrong and it can be tried again: HTTP status code 403 Forbidden
On success: A object with a ``mailAuthToken`` of the type string
#### example response
``{"mailAuthToken": "wthdktjdejd"}``

79
docs/api/child.md Normal file
View file

@ -0,0 +1,79 @@
# /child
This endpoint is used for by devices which are used by a child.
## POST /child/add-device
Use this during the setup to add a device to an existing family using an add device code.
### request
see [this JSON schema](../schema/registerchilddevicerequest.md)
### response
On a invalid request body: HTTP status code 400 Bad request
On a invalid add device token: HTTP status code 401 Unauthorized
On success: a JSON object with the properties ``deviceAuthToken`` and ``ownDeviceId``,
both of the type string
## POST /child/update-primary-device
Use this to (un)set the calling device as primary device.
### request
see [this JSON schema](../schema/updateprimarydevicerequest.md)
### response
On a invalid request body: HTTP status code 400 Bad request
On a invalid auth token: HTTP status code 401 Unauthorized
If the transmitted ``currentUserId`` is empty or does not match the current user of the device:
HTTP status code 409 Conflict
If the transmitted ``currentUserId`` does not match a valid user: HTTP status code 409 Conflict
If trying to unset the device as primary device and the device is not the current device of the user:
HTTP status code 409 Conflict
Otherwise: a JSON object with the property ``status`` (string)
``status`` can have the following values:
- ``assigned to other device`` (if the user is assigned to an other device)
- ``requires full version``
- ``success``
### see
- [primary device concept](../concept/primary-device.md)
## POST /child/logout-at-primary-device
Use this to request unsetting the current primary device of the user
which is currently assigned to the calling device. This triggers a websocket
message to the current primary device of the user.
### request
see [this JSON schema](../schema/requestwithauthtoken.md)
### response
On a invalid request body: HTTP status code 400 Bad request
On a invalid auth token: HTTP status code 401 Unauthorized
If there is no user assigned to the calling device or
if there is no existing current primary device: HTTP status code 409 Conflict
On success: ``{"ok": true}``
### see
- [primary device concept](../concept/primary-device.md)

167
docs/api/parent.md Normal file
View file

@ -0,0 +1,167 @@
# /parent
This endpoint is used by devices which are used by a parent.
## see
- [auth API](./auth.md) for obtaining mail auth tokens which are needed at some APIs here
## POST /parent/get-status-by-mail-address
Use this to check the status of a mail auth token and the linked mail address.
### request
see [this JSON schema](../schema/mailauthtokenrequestbody.md)
### response
On a invalid request body: HTTP status code 400 Bad Request
If the mail auth token is invalid/ expired: HTTP status code 401 Unauthorized
On success: a object with the properties ``status`` (string), ``mail`` (string) and
``canCreateFamily`` (boolean)
- ``status`` is ``with family`` or ``without family``
- ``mail`` is the mail address for which the auth token was created
- ``canCreateFamily`` is false if the sign up of new families was disabled and otherwise true
## POST /parent/create-family
Use this to register a new family.
### request
see [this JSON schema](../schema/createfamilybymailtokenrequest.md)
### response
On a invalid request body: HTTP status code 400 Bad Request
If the mail auth token is invalid/ expired: HTTP status code 401 Unauthorized
If there is already a user with the mail address of the mail auth token: HTTP status code 409 Conflict
On success: object with ``deviceAuthToken`` (string) and ``ownDeviceId`` (string)
## POST /parent/sign-in-into-family
Use this to sign in into an existing family using a mail auth token.
### request
see [this JSON schema](../schema/signintofamilyrequest.md)
### response
On a invalid request body: HTTP status code 400 Bad Request
If there is no user with the mail address of the mail auth token: HTTP status code 409 Conflict
On success: object with ``deviceAuthToken`` (string) and ``ownDeviceId`` (string)
## POST /parent/can-recover-password
Use this to check if the parent password can be recovered. This checks that the
mail auth token matches the mail address of the parent user.
### request
see [this JSON schema](/schema/canrecoverpasswordrequest.md)
### response
On a invalid request body: HTTP status code 400 Bad Request
If the mail auth token is invalid/ expired: HTTP status code 401 Unauthorized
On success: object with the property ``canRecover`` (boolean)
## POST /parent/recover-parent-password
Use this to set the password for a user without knowing the old password.
### request
see [this JSON schema](../schema/recoverparentpasswordrequest.md)
### response
On a invalid request body: HTTP status code 400 Bad Request
If the mail auth token is invalid/ expired: HTTP status code 401 Unauthorized
On success: ``{"ok": true}``
## POST /parent/create-add-device-token
Use this to create a token which can be used by ``/child/add-device``.
### request
see [this JSON schema](../schema/createregisterdevicetokenrequest.md)
in case of a device used by a parent with disabled password checks, use ``device`` as ``secondPasswordHash``
### response
On a invalid request body: HTTP status code 400 Bad Request
If the device auth token is invalid: HTTP status code 401 Unauthorized
If the ``secondPasswordHash`` is invalid: HTTP status code 401 Unauthorized
On success: object with ``token`` and ``deviceId``
``token`` is the add device token
``deviceId`` is the device id which the new device will get if it uses the token
## POST /parent/link-mail-address
Use this to link a mail address to an existing parent user.
### request
see [this JSON schema](../schema/linkparentmailaddressrequest.md)
### response
On a invalid request body: HTTP status code 400 Bad Request
If the device auth token is invalid: HTTP status code 401 Unauthorized
If the mail auth token is invalid/ expired: HTTP status code 401 Unauthorized
If there is already a user with the mail address of the mail auth token: HTTP status code 409 Conflict
If there is no user with the specified ``parentId`` (user id): HTTP status code 409 Conflict
If there is already a mail address for the user: HTTP status code 409 Conflict
If the ``parentPasswordSecondHash`` is invalid: HTTP status code 409 Conflict
On success: ``{"ok": true}``
## POST /parent/remove-device
Use this to remove a device from a family.
### request
see [this JSON schema](../schema/removedevicerequest.md)
in case of a device used by a parent with disabled password checks, use ``device`` as ``secondPasswordHash``
### response
On a invalid request body: HTTP status code 400 Bad Request
If the device auth token is invalid: HTTP status code 401 Unauthorized
If there is no device with the specified ``deviceId``: HTTP status code 409 Conflict
If the ``secondPasswordHash`` is invalid: HTTP status code 401 Unauthorized
On success: ``{"ok": true}``

53
docs/api/purchase.md Normal file
View file

@ -0,0 +1,53 @@
# /purchase
This endpoint is used for handling purchases from the client.
It currently only supports purchases using Google Play in app purchases.
## see
- [premium concept](../concept/premium.md)
## POST /purchase/can-do-purchase
Use this before a purchase to check if a purchase is possible.
### request
see [this JSON schema](../schema/candopurchaserequest.md)
### response
On a invalid request body: HTTP status code 400 Bad request
On a invalid auth token: HTTP status code 401 Unauthorized
On success: a JSON object with the property ``canDoPurchase`` of the type string
possible values of ``canDoPurchase``:
- ``yes``
- ``no due to old purchase``
- ``no because not supported by the server``
## POST /purchase/finish-purchase-by-google-play
Use this to report a purchase to the server/ unlock all features after a purchase
using Google Play.
### request
see [this JSON schema](../schema/finishpurchasebygoogleplayrequest.md)
### response
On a invalid request body: HTTP status code 400 Bad request
On a invalid auth token: HTTP status code 401 Unauthorized
On a invalid purchase: HTTP status code 409 Conflict
On success: ``{"ok": true}``
### error handling
- if the purchase was already added (for the same or an other family), then this request is ignored and success is returned

117
docs/api/sync.md Normal file
View file

@ -0,0 +1,117 @@
# /sync
This endpoint is used by clients for syncing.
## the sync process
- the client pushes all actions (eventually in chunks)
- all actions are numbered so that the server can ignore it if the client sends an action multiple times (e.g. due to connectivity issues)
- in case something goes wrong, the server asks the client to do a full query when pulling the status the next time
- the client pulls the status
- the client sends a summary of the current status
- the server does not send the data which the client already knows
- in case the client is unauthorized, then the client checks against /sync/is-device-removed
- if it tells the client that it was really removed, then the client resets itself
## possible sync triggers
- periodically/ by the time (e.g. every hour, not all 10 seconds)
- the [websocket](./websocket.md) for syncing as soon as something was changed by an other client
- changes/ actions at the client itself
## POST /sync/push-actions
Use this to sync actions to the server.
### request
see [this JSON schema](../schema/clientpushchangesrequest.md)
the encoded actions are stringified JSON objects of one of this schemes:
- [serialized app logic action](../schema/serializedapplogicaction.md)
- [serialized parent action](../schema/serializedparentaction.md)
- [serialized child action](../schema/serializedchildaction.md)
The request must not contain more than 50 actions. The request may contain less than 50
actions.
The sequence numbers must be a increasing sequence per device.
#### integrity
The integrity field of a action may have got one of the following values:
- an empty string when no user authentication is required/ for app logic actions (e.g. incrementing the used time)
- the string ``device`` in case of parent actions if a parent is assigned to the device and asking for the password was disabled
- ``sha512(sequence number as string with the base 10 + the device id as string + the hash of the user password using the second salt as string + the encoded action as string)`` for parent and child actions
In case of a invalid integrity value, the action is ignored and the client is told to do a full sync
### response
On a invalid request body: HTTP status code 400 Bad request
On a invalid auth token: HTTP status code 401 Unauthorized
On success: JSON object with the property ``shouldDoFullSync`` - example: ``{"shouldDoFullSync": false}``
### error handling
If a action has got a invalid ``integrity`` or ``encodedAction``, then only this action
is ignored and ``shouldDoFullSync`` will be true.
## POST /sync/pull-status
Use this to pull the current status from the server.
### request
see [this JSON schema](../schema/clientpullchangesrequest.md)
### response
On a invalid request body: HTTP status code 400 Bad request
On a invalid auth token: HTTP status code 401 Unauthorized
On success: see [this JSON schema](../schema/serverdatastatus.md)
## POST /sync/report-removed
Use this to report that TimeLimit is/ was reset.
### request
see [this JSON schema](../schema/requestwithauthtoken.md)
### response
On a invalid request body: http status code 400 Bad request
On a invalid/ unknown auth token: http status code 500 Internal Server Error
On success: ``{"ok": true}``
### error handling
If a removed device reports that it is removed, then it is ignored and handled
as success.
## POST /sync/is-device-removed
Use this to check if the device was removed.
Background: This checks if the auth token is in a list of known old auth tokens.
This ensures that an empty database at the server does not trigger the client reset feature.
### request
see [this JSON schema](../schema/requestwithauthtoken.md)
### response
On a invalid request body: http status code 400 bad request
object with the property ``isDeviceRemoved`` of the type boolean
example response: ``{"isDeviceRemoved": false}``

36
docs/api/websocket.md Normal file
View file

@ -0,0 +1,36 @@
# Websocket
The websocket is used for real time notifications from the server
to the client. For this, socket.io is used which internally
uses the ``/socket.io`` endpoint. It is highly recommend to only
use the websocket transport and to not use the polling transport.
Upon connecting, the client should emit ``devicelogin`` with one or two parameters.
The first parameter must be the device auth token and the second one can be an ack
function. After handling the connection, the server calls the ack function.
Clients should only do one ``devicelogin`` per connection. Doing it multiple
times per connection can result in missing events. Invalid auth tokens are ignored/
do not receive notifications.
## events from the server
### should sync
The server can emit ``should sync`` with one parameter of the type object.
This object has the boolean property ``isImportant``.
The client should sync after receiving this. If it is not important, then the client
can wait until to user opens the UI the next time.
### sign out
The server can emit ``sign out`` without any parameters. This tells the device
if it is the primary device for a user that it should leave that role if possible.
see the [primary device concept](../concept/primary-device.md)
### connected devices
The server can emit ``connected devices`` with one parameter of the type array of string.
This array contains the device ids of the devices which should be shown as connected.