# Local Storage Storage

This project implements a simple API to synchronize your localStorage between multiple devices.

## API

### API Key

While there is no automatic way to retrieve your API key right now, you need one. Ask the hoster of this instance directly. An API key will always be bound to a project identifier and a set of domains, and only allow frontends hosted on those domains to access this API using standard CORS headers. The data you need: * Project identifier (referenced in this document by `{project}`) * API key (referenced in this document by `MyApiKey`) If the API is unknown or does not match the domain or project, you'll receive an authorization error for any of the documented requests. To not leak any information no more details will be provided:
HTTP/1.1 403 Forbidden {ok: false}
All API responses contain proper CORS headers to make it psosible to access the API from the domains in the include list for the given project. `OPTION` requests are also properly answered because of this:
HTTP/1.1 200 OK Access-Control-Allow-Origin: my-domain.example Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS Access-Control-Allow-Headers: User-Agent, Authorization, Origin, Content-Type, Accept Access-Control-Expose-Headers: * Access-Control-Allow-Credentials: true Vary: Origin

### Store local storage

If there is no data stored yet, you can store data using a `PUT` request. All data will always be stored under an ID, which probably will identify the user of your application.
PUT https://local-storage-storage.io/api/{project}/{id} Origin: my-domain.example Authorization: Bearer MyApiKey {myLocalStorageData}
Reponses:
HTTP/1.1 201 Created {ok: true, revision: "{newDataRevision}"}
If the project does not exist:
HTTP/1.1 403 Forbidden {ok: false}
If there is already something stored under the given ID:
HTTP/1.1 409 Conflict {ok: false}

### Get local storage

GET https://local-storage-storage.io/api/{project}/{id} Origin: my-domain.example Authorization: Bearer MyApiKey
Responses:
HTTP/1.1 200 OK { ok: true, project: "{project}" id: "{id}", revision: "dataRevision", data: "{myLocalStorageData}", }
If the ID does not exist:
HTTP/1.1 404 Not Found {ok: false}

### Update local storage

If there is already data stored for an ID, you can update it using a `POST` request. There are no partial updates possible. For an update you have to provide the `revision` of the data. The revision is used for Multi-Version-Concurrency-Control (MVCC), which means that if multiple clients try to update the data conflicts can be detected and handled on the client side. The revision will update any time the storage is data is changed.
POST https://local-storage-storage.io/api/{project}/{id}?revision={revision} Origin: my-domain.example Authorization: Bearer MyApiKey {myLocalStorageData}
Reponses:
HTTP/1.1 200 OK {ok: true, revision: "{newDataRevision}"}
If the ID does not exist:
HTTP/1.1 404 Not Found {ok: false}
If there is already something stored under the given ID and the revision does not match:
HTTP/1.1 409 Conflict {ok: false}

### Delete local storage

If there is already data stored for an ID, you can remove it using a `DELETE` request. Like for any update you have to provide the `revision` of the data.
DELETE https://local-storage-storage.io/api/{project}/{id}?revision={revision} Origin: my-domain.example Authorization: Bearer MyApiKey
Reponses:
HTTP/1.1 200 OK {ok: true}
If the ID does not exist:
HTTP/1.1 404 Not Found {ok: false}
If there is already something stored under the given ID and the revision does not match:
HTTP/1.1 409 Conflict {ok: false}

### Proxy request

An additional API method to proxy `GET` requests to random targets through this API. This is useful for APIs which are not able to provide proper CORS headers for your current domain. Some headers of the reqeust (most importantly all Accept-headers) will be passed on to th requested URL, if provided. All headers except for CORS related headers will also be returned.
GET https://local-storage-storage.io/proxy/{project}/{url} Origin: my-domain.example Authorization: Bearer MyApiKey
Responses:
HTTP/1.1 200 OK Access-Control-Allow-Origin: my-domain.example Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS Access-Control-Allow-Headers: User-Agent, Authorization, Origin, Content-Type, Accept Access-Control-Expose-Headers: * Access-Control-Allow-Credentials: true Vary: Origin {original response from URL}
If the ID does not exist:
HTTP/1.1 404 Not Found {ok: false}