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

docs: add app docs #38

Merged
merged 13 commits into from
Mar 1, 2024
42 changes: 42 additions & 0 deletions docs/developer/apps/1-general-concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: General concepts
---


Graasp can embed web applications as a resource. They should be added as an item of type `app` to access the Graasp API and get authenticated with a token.

When an app is added as a resource, it is linked to an item. Therefore, two added apps will correspond to two different items, which leads them to have different item ids, and different app data.

## Features

### App Context {#app-context}

The app context contains additional information which might be interesting for your app such as `members` or `item`.

The `members` key contains the list of users that have a permission on the item, this does not include users viewing the app in public mode. You can use this list to display the name of a user that has created some data in your app for example.

The `item` key contains the properties of the item (the app instance) such as `name`, `description`, `path` etc.

### App Actions {#app-actions}

App actions are analytic traces the app might save.

You can only GET and POST app actions, it is not possible to delete app actions after their creation.

### App Data {#app-data}

App data are all data the app might save. App Data are created by a member and are available to in a given scope.

- **Visibility**: Availability of the app data, either `member` or `item` (default: `member`)
- `member`: the app data can be managed by the creator and members with admin permission. Members with write permission can view them but cannot modify them.
- `item`: the app data can be managed by the creator and members with admin permission. All other members can view them but cannot modify them.

### App Settings

App settings store the app configuration. Only members with the admin permission can create, update and delete them. The other members can only fetch the app settings.

If the related item is copied, its app settings are copied alongside, opposed to app data.

### File Upload

Apps can upload files, as (app) data or (app) setting.
56 changes: 56 additions & 0 deletions docs/developer/apps/10-local-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Local development

Developing an app locally requires some initial data in the database. Then your app needs to apply the login process

1. Change your `hosts` file so that `apps.localhost` redirects to `localhost`.
2. Run the following SQL query to add the necessary instance for running apps locally:

```sql
DO $$
DECLARE
# random UUID
publisher_id UUID := '98e4bcb8-6caf-4af8-988b-600aa3af5a86';
publisher_name varchar := 'Graasp';
# random UUID
app_id UUID := '3211293d-5e8e-4f5a-9576-7df30c2175c3';
app_name varchar := 'MyApp';
app_port int := 3012;
app_origin varchar := 'http://apps.localhost:' || app_port;
found_publisher boolean := FALSE;
BEGIN
-- Check if publisher already exists
SELECT EXISTS (
SELECT 1 FROM publisher WHERE id = publisher_id
) INTO found_publisher;

IF found_publisher THEN
-- Update existing publisher with new origin
UPDATE publisher
SET origins = origins || ARRAY[app_origin]::text[]
WHERE id = publisher_id;
ELSE
-- Insert data into publisher
INSERT INTO publisher (id, name, origins)
VALUES (
publisher_id,
publisher_name,
ARRAY[app_origin]::text[]
);
END IF;

-- Insert data into app
INSERT INTO app (id, key, name, description, url, publisher_id)
VALUES (
app_id,
app_id,
app_name,
app_name,
app_origin,
publisher_id
);

END $$;
```

3. Then you will need to add an app item with url `http://apps.localhost:3012`.
4. Run your app on `http://apps.localhost:3012`. Set the env variable `VITE_GRAASP_APP_KEY` to the key you used to register your app in the database (here `3211293d-5e8e-4f5a-9576-7df30c2175c3`).
48 changes: 48 additions & 0 deletions docs/developer/apps/15-communication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Authentication Process

:::info[React Framework]
We provide a library for React based apps, to easily connect to the API. Go to the [query client](./7-apps-query-client.md) or take a look at this [repository](https://github.com/graasp/graasp-apps-query-client).
:::

In order to access the API and get the app token, the apps should fullfil the following requirements:

- be registered as publisher in the database. If you are using our instance, you will need to contact us in order to be added. You will need to provide a `name` and `origin` urls where you will host your applications.
- have an `APP_ID` provided by Graasp. If you are using our instance, you will need to contact us in order for us to generate a valid key you can use.

### Procedure

Here are the steps to request a token:

1. **Request a context**: The app is iframed in the Graasp platform. It can access it's parent window's context by sending a `postMessage`.

```js
postMessage(
JSON.stringify({
type: 'GET_CONTEXT',
}
);
```

The response will contain one of the `port` of the `MessageChannel` you will use from now on to communicate with the parent window.

This endpoint is available for any apps, even if you don't fullfil the requirements.

2. **Request a token:** Once you have access to the `MessageChannel`'s `port` you can request a token as follows:

```js
port.postMessage(
JSON.stringify({
type: 'GET_AUTH_TOKEN',
payload: {
key: <app key>,
origin: <app origin>,
},
})
);
```

The response will contain `token` you will be using to request your app's data.

3. **Use the API**: From now on you can freely use your token to access the API and fetch various data. See the [API Documentation](./api-reference).

4. **Refetch the token**: The token might expire. In this case, redo step 2.
231 changes: 231 additions & 0 deletions docs/developer/apps/20-api-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
---
title: API Reference
slug: api-reference
---


All following requests need an authentication token received as described in the [guide](./communication).

Therefore, don't forget to use `Authorization: Bearer <token>` in your request's headers.

Please refer to [the General Concepts](./general-concepts)'s vocabulary to understand the concepts.

### Query strings

Within Graasp, the apps are given some information by query string:

- itemId: item id of the corresponding item

---

<a name="app-actions"></a>

## App Actions

- `id`: the app action id
- `memberId`: the member id related to the app action (default: current authenticated member id)
- `itemId`: the item id corresponding to the current app
- `data`: object containing any necessary data
- `type`: the related action related to the data
- `createdAt`: creation timestamp of the app action

### GET App Action

`GET <apiHost>/app-items/<item-id>/app-action`

- return value: an array of all app data related to `itemId`

### GET App Action for multiple items

`TODO`

### POST App Action

`POST <apiHost>/app-items/<item-id>/app-action`

- body: `{ data: { ... }, type, [memberId], [visibility] }`
- returned value: created app action

---

<a name="app-data"></a>

## App Data

- `id`: the app data id
- `memberId`: the member id related to the data (default: current authenticated member id)
- `itemId`: the item id corresponding to the current app
- `data`: object containing any necessary data
- `type`: the related action related to the data
- `creator`: the member id who created the app data
- `visibility`: `member` or `item`
- `createdAt`: creation timestamp of the app data
- `updatedAt`: update timestamp of the app data

### GET App Data

`GET <apiHost>/app-items/<item-id>/app-data`

- return value: an array of all app data related to `itemId`

### GET App Data for multiple items

`TODO`

### POST App Data

`POST <apiHost>/app-items/<item-id>/app-data`

- body: `{ data: { ... }, type, [memberId], [visibility] }`
- returned value: created app data

### PATCH App Data

`PATCH <apiHost>/app-items/<item-id>/app-data/<app-data-id>`

- body: `{ data: { ... } }`
- returned value: patched app data

### DELETE App Data

`DELETE <apiHost>/app-items/<item-id>/app-data/<app-data-id>`

- returned value: deleted app data

### Upload a file as an app data

`POST <apiHost>/app-items/upload?id=<item-id>`

- it is not possible to patch a file app setting
- send files as form data, the name of the file will be the name of the app setting
- returned value: created app setting

### Download a file from an app data

`GET <apiHost>/app-items/<app-data-id>/download`

- returned value: signed url of the file

---

<a name="app-context"></a>

## App Context

- `members`: a list of all the members having access to the app's parent and the app itself
- `item`: all corresponding item properties

### GET App Action

`GET <apiHost>/app-items/<item-id>/context`

- return value: the context of the corresponding item

---

<a name="app-settings"></a>

## App Settings

- `id`: the app setting id
- `name`: the app setting name
- `itemId`: the item id corresponding to the current app
- `data`: object containing any necessary setting
- `creator`: the member id who created the app setting
- `createdAt`: creation timestamp of the app setting
- `updatedAt`: update timestamp of the app setting

### GET App Setting

`GET <apiHost>/app-items/<item-id>/app-settings`

- return value: an array of all app settings related to `itemId`

### POST App Setting

`POST <apiHost>/app-items/<item-id>/app-settings`

- body: `{ name, data: { ... } }`
- returned value: created app setting

### PATCH App Setting

`PATCH <apiHost>/app-items/<item-id>/app-settings/<app-setting-id>`

- body: `{ data: { ... } }`
- permission: only member with the admin permission can patch an app setting
- it is not possible to patch a file app setting
- returned value: patched app setting

### DELETE App Setting

`DELETE <apiHost>/app-items/<item-id>/app-settings/<app-setting-id>`

- returned value: deleted app data
- permission: only member with the admin permission can delete an app setting

### Upload a file as an app setting

`POST <apiHost>/app-items/app-settings/upload?id=<item-id>`

- it is not possible to patch a file app setting
- send files as form data, the name of the file will be the name of the app setting
- returned value: created app setting

### Download a file from an app setting

`GET <apiHost>/app-items/app-settings/<app-setting-id>/download`

- returned value: signed url of the file

---

<a name="parent-window"></a>

## Parent Window

Since apps are embedded in Graasp with an iframe, it is possible to communicate with the parent window using both regular `window.postMessage` and `MessageChannel`. One should first use `window.postMessage` to get the context, as well as the `MessageChannel`'s port to continue the process (see [guide](./communication)).

### `window.postMessage`

### GET Context

:::warning
Context is different from App Context! Context (sometimes called Local Context) is always available to the app, even without using Graasp API, while App Context can only be fetched with a token.
:::

```js
postMessage(
JSON.stringify({
type: 'GET_CONTEXT',
}
);
```

- return values:
- `apiHost`: the api host origin
- `context`: where the app is running (eg: `builder`, `explorer`, `standalone`, ...)
- `itemId`: item id which corresponds to your app resource id
- `lang`: language
- `memberId`: the current authenticated user using the app
- `permission`: the current member's permission
- `settings`: the corresponding item settings
- as well as the `port` of the `MessageChannel` you will use from now on to communicate with the parent window.

### `MessageChannel`

### GET Authentication Token

```js
port.postMessage(
JSON.stringify({
type: 'GET_AUTH_TOKEN',
payload: {
key: <app key>,
origin: <app origin>,
},
})
);
```

- return value: authentication token
5 changes: 5 additions & 0 deletions docs/developer/apps/30-deployement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
:::warning
Doc under construction.
:::

Add instructions on how we deploy apps with S3 release-please and the workflows
Loading