aboutsummaryrefslogtreecommitdiffstats
path: root/proposals/0000-http-pinning-service-api.md
blob: 75dff6c6377a9082392d1cbb002cfc4854148f4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

Title: **DEP-0000: HTTP Pinning Service API**

Short Name: `0000-http-pinning-service-api`

Type: Standard

Status: Draft (as of 2018-03-31)

Github PR: https://github.com/datprotocol/DEPs/pull/19

Authors: Paul Frazee


# Summary
[summary]: #summary

An HTTP API for adding and removing Dat data.


# Motivation
[motivation]: #motivation

Users frequently make use of "pinning services" to keep their Dat data online
independently of their personal devices. By specifying a standard API for
accessing pinning services, we can integrate interfaces for these services to
Dat clients (including the Dat CLI and Beaker Browser). For example, in the Dat
CLI, it will be possible to execute commands such as:

```
dat publish --name myarchive my-pinning-service.com
```


# Service description (PSA) document
[service-description]: #service-description

Servers should host the PSA service-description document at `/.well-known/psa`.
It may be fetched using a GET request. This document will fit the following schema:

```json
{
  "PSA": 1,
  "title": "My Pinning Service",
  "description": "Keep your Dats online!",
  "links": [{
    "rel": "user-accounts-api.com/v1",
    "title": "User accounts API",
    "href": "/v1/accounts"
  }, {
    "rel": "datprotocol.com/deps/0000-http-pinning-service-api",
    "title": "Dat pinning API",
    "href": "/v1/dats"
  }]
}
```

You can read more about the [PSA Service Discovery
Protocol](https://github.com/beakerbrowser/beaker/wiki/PSA-Web-Service-Discovery-Protocol).

The PSA document must provide links to two API resources: the User Accounts
API, and the Dat Pinning API. These resources should be indicated by the
`user-accounts-api.com/v1` and `datprotocol.com/deps/0000-http-pinning-service-api`
rel-types, respectively. (These rel-types will need to be updated
with the final URLs for their specifications.) If either API is absent from
the PSA document, the service will be rejected.


# User accounts API
[user-accounts-api]: #user-accounts-api

The user-accounts API should provide the following resources:

```
POST /login     Create a new session with an existing account.
POST /logout    End a session.
GET  /account   Get information about the account attached to the current session.
```

Full documentation for this API should be made available at https://user-accounts-api.com.

## POST /login
[user-accounts-api-post-login]: #user-accounts-api-post-login

Create a new session with an existing account.

Request body (JSON). All fields required:

```
{
  username: String
  password: String
}
```

Handler should generate a session and return the identifier in the response.
Response body (JSON):

```
{
  sessionToken: String
}
```

## POST /logout
[user-accounts-api-post-logout]: #user-accounts-api-post-logout

End a session.

Request should include [authentication header](#authentication).

## GET /account
[user-accounts-api-get-account]: #user-accounts-api-get-account

Get information about the account attached to the current session.

Request should include [authentication header](#authentication).

Response body (JSON):

```
{
  email: String, the accounts email (required)
  username: String, the accounts username (required)
  diskUsage: Number, how much disk space has the user's data taken? (optional)
  diskQuota: Number, how much disk space can the user's data take? (optional)
  updatedAt: Number, the Unix timestamp of the last time the user account was updated (optional)
  createdAt: Number, the Unix timestamp of the last time the user account was updated (optional)
}
```

If `diskQuota` is not included or is set to 0, the service is acting as a "registry" and will not host the files.


# Dat pinning API
[dat-pinning-api]: #dat-pinning-api

The dat pinning API should provide the following resources:

```
GET  /            List all Dat data pinned by this account.
POST /add         Add a Dat to this account's list of pins.
POST /remove      Remove a Dat from this account's list of pins.
GET  /item/:key   Get information about a Dat in the account's list of pins.
POST /item/:key   Update information about a Dat in the account's list of pins.
```

## GET /
[dat-pinning-api-get-root]: #dat-pinning-api-get-root

List all Dat data pinned by this account.

Request should include [authentication header](#authentication).

Response body (JSON):

```
{
  items: [{
    url: String, dat url
    name: String, optional shortname assigned by the user
    title: String, optional title extracted from the dat's manifest file
    description: String, optional description extracted from the dat's manifest file
    urls: Array of Strings, optional list of URLs the dat can be accessed at
  }]
}
```

## POST /add
[dat-pinning-api-post-add]: #dat-pinning-api-post-add

Add a Dat to this account's list of pins.

Request should include [authentication header](#authentication).
Request body (JSON):

```
{
  url: String, required url/key of the dat
  name: String, optional shortname for the archive
  domains: Array of Strings, optional list of domain-names the dat should be made available at
}
```

## POST /remove
[dat-pinning-api-post-remove]: #dat-pinning-api-post-remove

Remove a Dat from this account's list of pins.

Request should include [authentication header](#authentication).
Request body (JSON):

```
{
  url: String, required url/key of the dat
}
```

## GET /item/:key
[dat-pinning-api-get-item]: #dat-pinning-api-get-item

Get information about a Dat in the account's list of pins. Key must be the
pubkey of the dat.

Response body (JSON):

```
{
  url: String, dat url
  name: String, optional shortname assigned by the user
  title: String, optional title extracted from the dat's manifest file
  description: String, optional description extracted from the dat's manifest file
  urls: Array of Strings, optional list of URLs the dat can be accessed at
}
```

## POST /item/:key
[dat-pinning-api-post-item]: #dat-pinning-api-post-item

Update information about a Dat in the account's list of pins. Key must be the
pubkey of the dat.

Request body (JSON):

```
{
  name: String, optional shortname for the archive
  domains: Array of Strings, optional list of domain-names the dat should be made available at
}
```


# Authentication
[authentication]: #authentication

Clients should use the [User accounts API](#user-accounts-api) to fetch a
session token from the service. This token should be included in the
`Authentication` header using the `Bearer` scheme.


# Error responses
[error-responses]: #error-responses

All error responses should respond with a JSON body which matches the
following schema:

```
{
  message: String
}
```

The content of `message` will be displayed to the user. It should explain the
error and, if appropriate, give steps for solving the issue. Other fields may
be included in the response.


# Rationale and alternatives
[alternatives]: #alternatives

- The motivations and drawbacks of the PSA Service Document are discussed
[here](https://github.com/beakerbrowser/beaker/wiki/PSA-Web-Service-Discovery-Protocol#motivation).
Without a description format, it becomes difficult to handle user
authentication. We would probably need to use the HTTP Basic scheme and remove
any mechanisms for registering new accounts.


# Unresolved questions
[unresolved]: #unresolved-questions

- Does the registration flow need to be included in the spec?


# Changelog
[changelog]: #changelog

- YYYY-MM-DD: First complete draft submitted for review