2024-06-16 00:17:38 +00:00
|
|
|
# Share Endpoints
|
|
|
|
|
|
|
|
Share endpoints allow sharing files with other users.
|
|
|
|
|
2024-06-17 22:32:45 +00:00
|
|
|
## POST `/share` (auth required)
|
2024-06-16 00:17:38 +00:00
|
|
|
|
2024-06-17 22:32:45 +00:00
|
|
|
### Description
|
|
|
|
|
|
|
|
The `/share` endpoint shares 1 or more filesystem items
|
|
|
|
with one or more recipients. The recipients will receive
|
|
|
|
some notification about the shared item, making this
|
|
|
|
different from calling `/grant-user-user` with a permission.
|
|
|
|
|
2024-06-21 02:10:11 +00:00
|
|
|
When users are **specified by email** they will receive
|
|
|
|
a [share link](./concepts/share-link.md).
|
|
|
|
|
2024-06-25 00:13:34 +00:00
|
|
|
Each item specified in the `shares` property is a tag-typed
|
|
|
|
object of type `fs-share` or `app-share`.
|
|
|
|
|
|
|
|
#### File Shares (`fs-share`)
|
|
|
|
|
|
|
|
File shares grant permission to a file or directory. By default
|
|
|
|
this is read permission. If `access` is specified as `"write"`,
|
|
|
|
then write permission will be granted.
|
|
|
|
|
|
|
|
#### App Shares (`app-share`)
|
|
|
|
|
|
|
|
App shares grant permission to read a protected app.
|
|
|
|
|
|
|
|
##### subdomain permission
|
|
|
|
If there is a subdomain associated with the app, and the owner
|
|
|
|
of the subdomain is the same as the owner of the app, then
|
|
|
|
permission to access the subdomain will be granted.
|
|
|
|
Note that the subdomain is only associated if the subdomain
|
|
|
|
entry has `associated_app_id` set according to the app's id,
|
|
|
|
and will not be considered "associated" if only the index_url
|
|
|
|
happens to match the subdomain url.
|
|
|
|
|
|
|
|
##### appdata permission
|
|
|
|
If the app has `shared_appdata` set to `true` in its metadata
|
|
|
|
object, the recipient of the share will also get write permission
|
|
|
|
to the app owner's corresponding appdata directory. The appdata
|
|
|
|
directory must exist for this to work as expected
|
|
|
|
(otherwise the permission rewrite rule fails since the uuid
|
|
|
|
can't be determined).
|
|
|
|
|
2024-06-20 07:10:34 +00:00
|
|
|
### Example
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"recipients": [
|
|
|
|
"user_that_gets_shared_to",
|
|
|
|
"another@example.com"
|
|
|
|
],
|
|
|
|
"shares": [
|
|
|
|
{
|
|
|
|
"$": "app-share",
|
|
|
|
"name": "some-app-name"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"$": "app-share",
|
|
|
|
"uid": "app-SOME-APP-UID"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"$": "fs-share",
|
|
|
|
"path": "/some/file/or/directory"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"$": "fs-share",
|
|
|
|
"path": "SOME-FILE-UUID"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-06-17 22:32:45 +00:00
|
|
|
### Parameters
|
|
|
|
|
|
|
|
- **recipients** _- required_
|
|
|
|
- **accepts:** `string | Array<string>`
|
|
|
|
- **description:**
|
|
|
|
recipients for the filesystem entries being shared.
|
|
|
|
- **notes:**
|
|
|
|
- validation on `string`: email or username
|
|
|
|
- requirement of at least one value
|
2024-06-20 07:10:34 +00:00
|
|
|
- **shares:** _- required_
|
2024-06-20 05:16:59 +00:00
|
|
|
- **accepts:** `object | Array<object>`
|
2024-06-20 07:10:34 +00:00
|
|
|
- object is [type-tagged](./type-tagged.md)
|
|
|
|
- type is either [file-share](./types/file-share.md)
|
|
|
|
or [app-share](./types/app-share.md)
|
2024-06-17 22:32:45 +00:00
|
|
|
- **notes:**
|
2024-06-20 05:16:59 +00:00
|
|
|
- requirement that file/directory or app exists
|
|
|
|
- requirement of at least one entry
|
2024-06-17 22:32:45 +00:00
|
|
|
- **dry_run:** _- optional_
|
|
|
|
- **accepts:** `bool`
|
|
|
|
- **description:**
|
|
|
|
when true, only validation will occur
|
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
- **$:** `api:share`
|
|
|
|
- **$version:** `v0.0.0`
|
|
|
|
- **status:** one of: `"success"`, `"mixed"`, `"aborted"`
|
|
|
|
- **recipients:** array of: `api:status-report` or
|
|
|
|
`heyputer:api/APIError`
|
|
|
|
- **paths:** array of: `api:status-report` or
|
|
|
|
`heyputer:api/APIError`
|
|
|
|
- **dry_run:** `true` if present
|
|
|
|
|
2024-06-17 22:44:21 +00:00
|
|
|
### Request Example
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
await fetch("http://puter.localhost:4100/share", {
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
"Authorization": `Bearer ${puter.authToken}`,
|
|
|
|
},
|
|
|
|
body: JSON.stringify({
|
2024-06-20 07:10:34 +00:00
|
|
|
recipients: [
|
|
|
|
"user_that_gets_shared_to",
|
|
|
|
"another@example.com"
|
|
|
|
],
|
|
|
|
shares: [
|
|
|
|
{
|
|
|
|
$: "app-share",
|
|
|
|
name: "some-app-name"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
$: "app-share",
|
|
|
|
uid: "app-SOME-APP-UID"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
$: "fs-share",
|
|
|
|
path: "/some/file/or/directory"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
$: "fs-share",
|
|
|
|
path: "SOME-FILE-UUID"
|
|
|
|
}
|
|
|
|
]
|
2024-06-17 22:44:21 +00:00
|
|
|
}),
|
|
|
|
method: "POST",
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2024-06-17 22:32:45 +00:00
|
|
|
### Success Response
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"$": "api:share",
|
|
|
|
"$version": "v0.0.0",
|
|
|
|
"status": "success",
|
|
|
|
"recipients": [
|
|
|
|
{
|
|
|
|
"$": "api:status-report",
|
|
|
|
"status": "success"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"paths": [
|
|
|
|
{
|
|
|
|
"$": "api:status-report",
|
|
|
|
"status": "success"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"dry_run": true
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Error response (missing file)
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"$": "api:share",
|
|
|
|
"$version": "v0.0.0",
|
|
|
|
"status": "mixed",
|
|
|
|
"recipients": [
|
|
|
|
{
|
|
|
|
"$": "api:status-report",
|
|
|
|
"status": "success"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"paths": [
|
|
|
|
{
|
|
|
|
"$": "heyputer:api/APIError",
|
|
|
|
"code": "subject_does_not_exist",
|
|
|
|
"message": "File or directory not found.",
|
|
|
|
"status": 404
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"dry_run": true
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Error response (missing user)
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"$": "api:share",
|
|
|
|
"$version": "v0.0.0",
|
|
|
|
"status": "mixed",
|
|
|
|
"recipients": [
|
|
|
|
{
|
|
|
|
"$": "heyputer:api/APIError",
|
|
|
|
"code": "user_does_not_exist",
|
|
|
|
"message": "The user `non_existing_user` does not exist.",
|
|
|
|
"username": "non_existing_user",
|
|
|
|
"status": 422
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"paths": [
|
|
|
|
{
|
|
|
|
"$": "api:status-report",
|
|
|
|
"status": "success"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"dry_run": true
|
|
|
|
}
|
|
|
|
```
|
2024-06-21 02:10:11 +00:00
|
|
|
|
|
|
|
## POST `/sharelink/check` (no auth)
|
|
|
|
|
|
|
|
### Description
|
|
|
|
|
|
|
|
The `/sharelink/check` endpoint verifies that a token provided
|
|
|
|
by a share link is valid.
|
|
|
|
|
|
|
|
### Example
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
await fetch(`${config.api_origin}/sharelink/check`, {
|
|
|
|
"headers": {
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
"Authorization": `Bearer ${puter.authToken}`,
|
|
|
|
},
|
|
|
|
"body": JSON.stringify({
|
|
|
|
token: '...',
|
|
|
|
}),
|
|
|
|
"method": "POST",
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
### Parameters
|
|
|
|
|
|
|
|
- **token:** _- required_
|
|
|
|
- **accepts:** `string`
|
|
|
|
The token from the querystring parameter
|
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
A type-tagged object, either of type `api:share` or `api:error`
|
|
|
|
|
|
|
|
### Success Response
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"$": "api:share",
|
|
|
|
"uid": "836671d4-ac5d-4bd3-bc0a-ec357e0d8f02",
|
|
|
|
"email": "asdf@example.com"
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Error Response
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"$": "api:error",
|
|
|
|
"message":"Field `token` is required.",
|
|
|
|
"key":"token",
|
|
|
|
"code":"field_missing"
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## POST `/sharelink/apply` (no auth)
|
|
|
|
|
|
|
|
### Description
|
|
|
|
|
|
|
|
The `/sharelink/apply` endpoint applies a share to the current
|
|
|
|
user **if and only if** that user's email is confirmed and matches
|
|
|
|
the email associated with the share.
|
|
|
|
|
|
|
|
### Example
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
await fetch(`${config.api_origin}/sharelink/apply`, {
|
|
|
|
"headers": {
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
"Authorization": `Bearer ${puter.authToken}`,
|
|
|
|
},
|
|
|
|
"body": JSON.stringify({
|
|
|
|
uid: '836671d4-ac5d-4bd3-bc0a-ec357e0d8f02',
|
|
|
|
}),
|
|
|
|
"method": "POST",
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
### Parameters
|
|
|
|
|
|
|
|
- **uid:** _- required_
|
|
|
|
- **accepts:** `string`
|
|
|
|
The uid of an existing share, received using `/sharelink/check`
|
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
A type-tagged object, either of type `api:status-report` or `api:error`
|
|
|
|
|
|
|
|
### Success Response
|
|
|
|
|
|
|
|
```json
|
|
|
|
{"$":"api:status-report","status":"success"}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Error Response
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"message": "This share can not be applied to this user.",
|
|
|
|
"code": "can_not_apply_to_this_user"
|
|
|
|
}
|
|
|
|
```
|
2024-06-24 05:05:18 +00:00
|
|
|
|
|
|
|
## POST `/sharelink/request` (no auth)
|
|
|
|
|
|
|
|
### Description
|
|
|
|
|
|
|
|
The `/sharelink/request` endpoint requests the permissions associated
|
|
|
|
with a share link to the issuer of the share (user that sent the share).
|
|
|
|
This can be used when a user is logged in, but that user's email does
|
|
|
|
not match the email associated with the share.
|
|
|
|
|
|
|
|
### Example
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
await fetch(`${config.api_origin}/sharelink/request`, {
|
|
|
|
"headers": {
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
"Authorization": `Bearer ${puter.authToken}`,
|
|
|
|
},
|
|
|
|
"body": JSON.stringify({
|
|
|
|
uid: '836671d4-ac5d-4bd3-bc0a-ec357e0d8f02',
|
|
|
|
}),
|
|
|
|
"method": "POST",
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
### Parameters
|
|
|
|
|
|
|
|
- **uid:** _- required_
|
|
|
|
- **accepts:** `string`
|
|
|
|
The uid of an existing share, received using `/sharelink/check`
|
|
|
|
|
|
|
|
### Response
|
|
|
|
|
|
|
|
A type-tagged object, either of type `api:status-report` or `api:error`
|
|
|
|
|
|
|
|
### Success Response
|
|
|
|
|
|
|
|
```json
|
|
|
|
{"$":"api:status-report","status":"success"}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Error Response
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"message": "This share is already valid for this user; POST to /apply for access",
|
|
|
|
"code": "no_need_to_request"
|
|
|
|
}
|
|
|
|
```
|