diff --git a/docs/endpoints.MD b/docs/endpoints.MD new file mode 100644 index 00000000..942c1dae --- /dev/null +++ b/docs/endpoints.MD @@ -0,0 +1,326 @@ +# Endpoints + +This documentation is focused on the behaviour of Userstyles world(USw)'s `/api` endpoints. +URL's are referred as ex. `/user` and thereby will mean the endpoint is located at `https://userstyles.world/api/user/`. + +## Basic information + +All requests are returned as `application/json` regardless of the `Accept` header. +All responses are compressed by default, based on the `Accept-Encoding` header. +All _correct_ GET-response are returned within a `data` property of the returned JSON, +please note that the example response won't show this. + + +### Retrieve user's information + +**Authorization is required** +``` +GET /user +``` +Get the user's information. + +Example response +```JSON +{ + "username": "Gusted", + "email": "notmyemail@example.com", + "biography": "I'm _one_ of the UserStyles World Developers.\nBe aware, **I'm gay** 🌈.", + "role": "Moderator", + "socials": { + "github": "gusted", + "gitlab": "gusted", + "codeberg": "gusted" + } +} +``` + +_**Note:** The email field can be empty when a user has registered through an OAuth provider._ + +### Retrieve a specific user's information +``` +GET /user/ +``` +or +``` +GET /user/ +``` +Gets a specific user's information, specified with the user's ID/username. The username is capitalization-sensitive. + +Example response of id=8/username="Gusted" +```json +{ + "username": "Gusted", + "biography": "I'm _one_ of the UserStyles World Developers.\nBe aware, **I'm gay** 🌈.", + "role": "Moderator", + "socials": { + "github": "gusted", + "gitlab": "gusted", + "codeberg": "gusted" + } +} +``` + +### List styles + +**Authorization is required** +``` +GET /styles +``` + +Gets the user's styles and list them with basic information. + +Example response +```JSON +[ + { + "ID": 1, + "CreatedAt": "2021-04-01T23:44:27.067587104+02:00", + "UpdatedAt": "2021-04-06T21:54:08.396097219Z", + "Name": "UserStyles.world Tweaks", + "Description": "Various tweaks for UserStyles.world that might end up being upstreamed.", + "Notes": "After you install this userstyle, you can configure it from _configuration menu_ in Stylus' popout menu by clicking on the icon on your toolbar.", + "Code": "Left out due to length in this example.", + "License": "MIT", + "Preview": "https://user-images.githubusercontent.com/18245694/111090605-9cc4ce00-8530-11eb-8716-2c1df40f32e1.png", + "Homepage": "https://github.com/userstyles-world/tweaks", + "Archived": false, + "Featured": true, + "Category": "userstyles.world", + "Original": "https://raw.githubusercontent.com/userstyles-world/tweaks/main/tweaks.user.styl", + "MirrorCode": true, + "MirrorMeta": false, + "UserID": 1, + "Username": "vednoc" + }, + { + "ID": 2, + "CreatedAt": "2021-04-02T17:20:59.830991125+02:00", + "UpdatedAt": "2021-04-02T17:25:03.430384406+02:00", + "Name": "Dark-GitHub", + "Description": "Dark and light, very customizable theme for GitHub.", + "Notes": "", + "Code": "Left out due to length in this example.", + "License": "MIT", + "Preview": "https://user-images.githubusercontent.com/18245694/109351173-18f4bb80-7879-11eb-998f-3fc31d2abb55.png", + "Homepage": "https://github.com/vednoc/dark-github", + "Archived": false, + "Featured": true, + "Category": "github.com", + "Original": "https://raw.githubusercontent.com/vednoc/dark-github/main/github.user.styl", + "MirrorCode": true, + "MirrorMeta": false, + "UserID": 1, + "Username": "vednoc" + } +] +``` + +### Retrieve specific style's information +``` +GET /style/ +``` +Gets a specific style's information, specified with the style's ID. + +Example response ID=29 +```JSON +{ + "ID": 29, + "CreatedAt": "2021-04-03T17:49:35.16120309Z", + "UpdatedAt": "2021-04-18T00:53:52.35042565Z", + "Name": "Userstyles.World Tweaks!", + "Description": "Tweaks for Userstyles.World!", + "Notes": "", + "Code": "Left out due to length in this example.", + "License": "", + "Preview": "https://codeberg.org/Freeplay/UserStyles/raw/branch/main/images/userstyles.world_tweaks-1.png", + "Homepage": "https://codeberg.org/Freeplay/UserStyles", + "Archived": false, + "Featured": true, + "Category": "Userstyles.world", + "Original": "https://codeberg.org/Freeplay/UserStyles/raw/branch/main/Userstyles.world_tweaks.user.css", + "MirrorCode": true, + "MirrorMeta": false, + "UserID": 11, + "Username": "Freeplay" +} +``` + +### Edit specific style + +**Authorization is required** +``` +POST /style/ +``` + +Edit a user's style specified with the style's ID. +The only changes that will be changing are the ones that are being sent, +this means you can send partial information. + +Example request +```JSON +{ + "name": "The changed name of the style", + "description": "A wordy description of the edited style", + "notes": "Hey, if you install this make sure to remember X", + "code": "Some actually valid UserCSS code here", + "preview": "https://i.ytimg.com/vi/-Cv68B-F5B0/maxresdefault.jpg", + "homepage": "https://github.com/userstyles-world/userstyles.world/", + "license": "WTFPL", + "category": "youtube.com" +} +``` + +Example response +```JSON +Status: 200 +{ + "info": "Succesful edited style!" +} +``` +or +```JSON +Status: 406 +{ + "err": "Homepage validation is wrong." +} +``` + +### Add new style + +**Authorization is required** +``` +POST /style/new +``` + +Add a new style on the user's behalf. + +Example request +```JSON +{ + "name": "The name of the style", + "description": "A wordy description of the new style", + "notes": "Hey, if you install this make sure to remember X", + "code": "Some actually valid UserCSS code here", + "preview": "https://i.ytimg.com/vi/-Cv68B-F5B0/maxresdefault.jpg", + "homepage": "https://github.com/userstyles-world/userstyles.world/", + "license": "WTFPL", + "category": "youtube.com" +} +``` + +Example response +```JSON +Status: 200 +{ + "info": "Succesful added the style! With ID: 69" +} +``` +or +```JSON +Status: 406 +{ + "err": "Homepage validation is wrong." +} +``` + +### Delete a style + +**Authorization is required** +``` +DELETE /style/ +``` +Deletes an style of the user. + +Example response +```JSON +Status: 200 +{ + "info": "Succesful removed the style!" +} +``` +or +```JSON +Status: 403 +{ + "err": "This style doesn't belong to you! ╰༼⇀︿⇀༽つ-]═──" +} +``` + +### Retrieve strong ETAG of style +``` +HEAD /style/.user.css +``` +Returns strong ETAG header of specified style. + +### Get style's source code +``` +GET /style/.user.css +``` +Returns raw source code of specified style, +this is normally used as updateURL and installation URL. + +### Get style's preview +``` +GET /style/preview/. +``` +Gets an optimized webp/jpeg version of the style's preview. + +### List all styles +``` +GET /index/ +``` +List all available styles on USw. +When format(_optional_) is specified it will go through formating: +```JSON +`uso-format` +Special format that the USo-Archive uses as well. +Meant for stylus +[ + { + "i": 1, + "n": "UserStyles.world Tweaks", + "c": "userstyles.world", + "u": 1617746048, + "t": 5, + "w": 5, + "an": "vednoc", + "sn": "https://userstyles.world/api/style/preview/1.webp" + } +] +``` + +### Search for style +``` +GET /search/ +``` +Retrieve all styles based on the text query. + +Example response query=userstyles-world +```json +[ + { + "id": "29", + "username": "Freeplay", + "name": "Userstyles.World Tweaks!", + "description": "Tweaks for Userstyles.World!", + "preview": "https://codeberg.org/Freeplay/UserStyles/raw/branch/main/images/userstyles.world_tweaks-1.png", + "notes": "" + }, + { + "id": "1", + "username": "vednoc", + "name": "UserStyles.world Tweaks", + "description": "Various tweaks for UserStyles.world that might end up being upstreamed.", + "preview": "https://user-images.githubusercontent.com/18245694/111090605-9cc4ce00-8530-11eb-8716-2c1df40f32e1.png", + "notes": "After you install this userstyle, you can configure it from _configuration menu_ in Stylus' popout menu by clicking on the icon on your toolbar." + }, + { + "id": "36", + "username": "Freeplay", + "name": "Cleaner Stylus", + "description": "Tweaks for Userstyles.World!", + "preview": "https://codeberg.org/Freeplay/UserStyles/raw/branch/main/images/cleaner-stylus-1.png", + "notes": "" + } +] +``` diff --git a/docs/oauth.MD b/docs/oauth.MD new file mode 100644 index 00000000..deeed114 --- /dev/null +++ b/docs/oauth.MD @@ -0,0 +1,75 @@ +# OAuth documentation + +This documentation is focussed on the OAuth workflow, you should find all steps/information about the OAuth of Userstyles world(USw) +within this documentation and _all_ related coded is within the `oauth_provider/` folder. + +_**Note:** currently headless OAuth isn't supported._ + +## Basic OAuth workflow + +### 1 >> Let the user authorize with the given parameters +``` +GET https://usestyles.world/oauth/authorize +``` + +#### Parameters + +| Name | Type | Required | Description | +| :---: | :---: | :---: | +| client_id | string | Yes | The client ID that is generated when you've registered for an USw application. | +| state | string | Recommended | An unguessable random string. It is used to protect against [[https://en.wikipedia.org/wiki/Cross-site_request_forgery][cross-site request forgery]] attacks. | +| redirect_uri | string | No | Specify which URL should be used after the authorization is finished. When not specified, default value within the application would be used. | +| scope | string | No | A comma-delimited list of the [[./oauth.MD#scopes][scopes]], when not specified the default scopes will be used based on the application's setting. | + + +### 2 >> Users are sent to redirect_uri + +_When the user accepts your request, USw redirects back to your site with a temporary code in a `code` parameter. This temporary code will expire after 10 minutes. When in the previous step the `state` parameter was provided, it will be sent back in the `state` parameter, When the states don't match, then a third party created the request, and you should abort the process._ + +``` +POST https://userstyles.world/oauth/access_token +``` + +#### Parameters + +| Name | Type | Required | Description | +| :--- | :--- | :--- | +| client_id | string | Yes | The client ID that is generated when you've registered for an USw application. | +| client_secret | string | Yes | The client secret that is generated when you've registered for an USw application. | +| code | string | Yes | The code that you've received as a parameter to Step 1. +| state | string | No | The unguessable random string you've provided in Step 1. | + + +#### Response + +Depending on the `Accept` header that was sent. +It will by default, send the `text/plain` format. + +``` +access_token=usw_IamAveryRandomAccesTokkeennAndImNotAfraid&token_type=bearer +``` + +Otherwise when specified: +```json +Accept: application/json +{"access_token":"usw_IamAveryRandomAccesTokkeennAndImNotAfraid", "token_type":"bearer"} +``` + +### 3 >> Using the access token + +The access token will allow you to make requests to endpoints on behalf of the user. +The endpoints are specified [[./endpoints.MD][here]]. + +``` +Authorization: TOKEN_TYPE ACCESS_TOKEN +GET https://userstyles.world/api/user/ +``` + +## Scopes + +_**Note:** Scopes may, later on, be split down into more specific scopes._ + +| Name | Description | +| :--- | :--- | +| `style` | Allow to add/edit/delete styles of the user. | +| `user` | Allow retrieving information of the user. | diff --git a/readme.org b/readme.org index 734d438c..d8467aff 100644 --- a/readme.org +++ b/readme.org @@ -22,8 +22,12 @@ what we're working on, and feel free to open an issue to request new features. - Userstyle deletion and editing of all available fields - Style statistics in form of views, and weekly/total installs -*** Small (for now) testing API: -- Style index, style details, and style source code endpoints +*** API: +- Style index, style details, and style source code endpoints. +- OAuth support to make certain actions on the user behalf. + +*** Documentation: +_Please see [[./docs/][docs/]] folder for relevant documentation on features._ ** License Source code released under the [[./license][AGPL-3.0 License]].