chore: Port FreeSewing.dev to docusaurus
The replaces the NextJS site powering FreeSewing.dev with a Docusaurus setup. It's part of my efforts to simplify FreeSewing's setup so we can focus on our core value proposition.
This commit is contained in:
parent
497633d1d3
commit
ab3204f9f1
692 changed files with 11037 additions and 20674 deletions
|
@ -1,113 +0,0 @@
|
|||
---
|
||||
title: Confirm an account
|
||||
---
|
||||
|
||||
Confirms a newly created User account.
|
||||
If confirmation is successful this will also result in a (passwordless) sign-in.
|
||||
|
||||
## Endpoints
|
||||
|
||||
Confirming a new User account is possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/confirm/signup/:id` | None |
|
||||
|
||||
<Note compact>This endpoint requires no authentication</Note>
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the confirmation ID that was E-mailed to the E-mail
|
||||
address used for the signup. It replaces the `:id` placeholder in the
|
||||
[endpoint listed above](#endpoints).
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `consent` | Number | An integer representing the consent given by the user to process their data |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="404"/> | the confirmation was not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `token` | String | A JSON web token (JWT) token to authenticate with |
|
||||
| `account.id` | Number | The ID of the User |
|
||||
| `account.bio` | String | The bio of the User |
|
||||
| `account.consent` | Number | The consent given by the User |
|
||||
| `account.control` | Number | The control desired by the User |
|
||||
| `account.createdAt` | String | Date string indicating the moment the User was created |
|
||||
| `account.email` | String | The E-mail address currently tied to the User |
|
||||
| `account.github` | String | The GitHub username of the User |
|
||||
| `account.img` | String | The URL to the image stored with this User |
|
||||
| `account.imperial` | Boolean| Whether or not the User prefers imperial units |
|
||||
| `account.initial` | String | The E-mail address that the User was created with |
|
||||
| `account.language` | String | The language preferred by the user |
|
||||
| `account.lastSignIn`| String | Date string indicating them moment the User last signed in |
|
||||
| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled |
|
||||
| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter |
|
||||
| `account.patron` | Number | The level of patronage the user provides to FreeSewing |
|
||||
| `account.role` | String | The role of the User |
|
||||
| `account.status` | Number | The status of the user |
|
||||
| `account.updatedAt` | String | Date string indicating the last time the User was updated |
|
||||
| `account.username` | String | The username of the User |
|
||||
| `account.lusername` | String | A lowercased version of the username of the User |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const confirm = await axios.post(
|
||||
'https://backend.freesewing.org/confirm/signup/3985f312-e407-458a-a78c-4596c361d284',
|
||||
{ consent: 2 },
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5c...truncated",
|
||||
"account": {
|
||||
"id": 14,
|
||||
"bio": "",
|
||||
"consent": 1,
|
||||
"control": 1,
|
||||
"createdAt": "2022-11-19T18:15:22.642Z",
|
||||
"email": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"github": "",
|
||||
"img": "https://freesewing.org/avatar.svg",
|
||||
"imperial": false,
|
||||
"initial": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"language": "en",
|
||||
"lastSignIn": "2022-11-19T18:15:22.668Z",
|
||||
"mfaEnabled": false,
|
||||
"newsletter": false,
|
||||
"patron": 0,
|
||||
"role": "user",
|
||||
"status": 1,
|
||||
"updatedAt": "2022-11-19T18:15:22.668Z",
|
||||
"username": "user-14",
|
||||
"lusername": "user-14"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,66 +0,0 @@
|
|||
---
|
||||
title: Create an account
|
||||
---
|
||||
|
||||
Creates a new User account. The User account will remain inactive
|
||||
until [it is confirmed](/reference/backend/account/confirm).
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new User account is possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/signup` | None |
|
||||
|
||||
<Note compact>This endpoint requires no authentication</Note>
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `email` | `string` | The E-mail address of the User |
|
||||
| `language` | `boolean`| The language code for the User |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `email` | String | The E-mail address where the confirmation email was sent to |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const signup = await axios.post(
|
||||
'https://backend.freesewing.org/signup',
|
||||
{
|
||||
email: "joost@joost.at",
|
||||
language: "en"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"email": "joost@joost.at"
|
||||
}
|
||||
```
|
|
@ -1,94 +0,0 @@
|
|||
---
|
||||
title: Account
|
||||
---
|
||||
|
||||
From an end-user's point of view, their account holds all of their data. From
|
||||
an API point of view, these endpoints deal with data in the User table.
|
||||
|
||||
As the endpoints typically use `/account` we tend to use _account_ more often
|
||||
than _user_.
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
### The `consent` field is about data protection
|
||||
|
||||
The `consent` field holds a number indicating to which level the user has
|
||||
agreed to the processing of their data:
|
||||
|
||||
- `0` : No consent given (yet)
|
||||
- `1` : Consent given for processing profile data
|
||||
- `2` : Consent given for processing profile & people data
|
||||
- `3` : Consent given for processing profile & people data, and for publishing
|
||||
anonymized measurements as open data
|
||||
|
||||
Providing a consent value (that is higher than `0`) is a requirement for
|
||||
confirming a User account. In other words, without sufficient consent, you
|
||||
can't sign up.
|
||||
|
||||
### The `control` field is about keeping it simple
|
||||
|
||||
The `control` field holds a number indicating to which level the user wants to
|
||||
be in control of the FreeSewing platform. It was added as a way to allow for
|
||||
progressive disclosure of (more) advanced features and settings on the
|
||||
FreeSewing website.
|
||||
|
||||
Possible values are:
|
||||
|
||||
- `1` : Hide all but the most crucial features. Make it as simple as possible.
|
||||
- `2` : Hide the majority of features. Make it simple, but not too much.
|
||||
- `3` : Reveal the majority of features, but not all. Balance simplicity with
|
||||
power.
|
||||
- `4` : Reveal everything, but keep handrails and safety checks. Only intervene
|
||||
when I'm about to do something dangerous.
|
||||
- `5` : Reveal everything, remove the handrails and safety checks. Get out of
|
||||
my way, I know what I'm doing.
|
||||
|
||||
### The `ihash` and `ehash` fields are for search
|
||||
|
||||
Because we encrypt a lot of data at rest, it can be difficult for support or
|
||||
administrators to find users when they don't know or remember their username
|
||||
because we cannot search on their E-mail address since that data is encrypted.
|
||||
|
||||
That is why we store a hash of the (lowercased) email address. This way, we can
|
||||
hash the email provided to us, and search the hash instead.
|
||||
|
||||
The `ehash` and `ihash` fields hold the hash for the `email` and `initial`
|
||||
fields.
|
||||
|
||||
### The `imperial` property is a Boolean
|
||||
|
||||
If the `imperial` property is `false`, the user wants metric units.
|
||||
|
||||
If the `imperial` property is `true`, the user wants imperial units.
|
||||
|
||||
### The `initial` field guards against account takeover
|
||||
|
||||
The `initial` field will be set to the E-mail address the account was
|
||||
registered with. It can never be changed.
|
||||
|
||||
This ensures that when there's an account takeover dispute, we can always know
|
||||
what E-mail address was used to create the account, even if the E-mail address
|
||||
associated with the account was changed.
|
||||
|
||||
### The `lusername` field should be unique
|
||||
|
||||
For the backend users `Joost` and `joost` are -- strictly speaking -- two
|
||||
different users. This tends to lead to confusion and possible impersonation.
|
||||
So we enforce uniqueness on the `lusername` field which holds a lowercased
|
||||
version of the `username` field..
|
||||
|
||||
In other words, lowercased username must be unique.
|
||||
|
||||
### The `status` field holds the account status
|
||||
|
||||
Possible values are:
|
||||
|
||||
- `0` : The account is not active (yet)
|
||||
- `1` : The account is active
|
||||
- `-1` : The account was disabled by the user
|
||||
- `-2` : The account was administratively disabled
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
---
|
||||
title: MFA
|
||||
---
|
||||
|
||||
Enable of disable Multi-Factor Authentication (MFA) on the User account.
|
||||
|
||||
- [Setup MFA](#setup-mfa)
|
||||
- [Confirm MFA](#confirm-mfa)
|
||||
- [Disable MFA](#disable-mfa)
|
||||
|
||||
## Endpoints
|
||||
|
||||
Enabling, confirming, and disabling MFA is all possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/account/mfa/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/account/mfa/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Setup MFA
|
||||
|
||||
### Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `mfa` | `boolean`| Set to `true` to enable MFA |
|
||||
|
||||
### Response status codes
|
||||
|
||||
Possible status codes for this endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | access denied |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
### Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| -------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `mfa.secret` | String | The shared secret for generating one-time password (OTP) tokens |
|
||||
| `mfa.otpauth` | String | The OTP Auth URI that is encoded in the QR code |
|
||||
| `mfa.qrcode` | String | SVG to display a QR code with the otpauth URI encoded |
|
||||
|
||||
<Tip>
|
||||
##### Styling the SVG
|
||||
The SVG returned by the backend uses `currentColor` for the QR code, so you can
|
||||
style it with CSS if you embed it in the page.
|
||||
</Tip>
|
||||
|
||||
### Example request
|
||||
|
||||
```js
|
||||
const mfa = await axios.post(
|
||||
'https://backend.freesewing.org/account/mfa/jwt',
|
||||
{ mfa: true },
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"mfa": {
|
||||
"secret": "KBTSKUKRDJPEGCZK",
|
||||
"otpauth": "otpauth://totp/FreeSewing:user-294?secret=KBTSKUKRDJPEGCZK&period=30&digits=6&algorithm=SHA1&issuer=FreeSewing",
|
||||
"qrcode": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 53 53\" shape-rendering=\"crispEdges\"><path fill=\"none\" d=\"M0 0h53v53H0z\"/><path stroke=\"currentColor\" d=\"M4 4.5h7m1 0h1m3 0h1m1 0h3m2 0h1m1 0h1m1 0h1m1 0h2m1 0h5m3 0h1m1 0h7M4 5.5h1m5 0h1m1 0h4m1 0h2m4 0h1m2 0h3m3 0h1m2 0h2m2 0h1m2 0h1m5 0h1M4 6.5h1m1 0h3m1 0h1m1 0h2m1 0h3m4 0h2m1 0h2m3 0h4m2 0h1m2 0h1m2 0h1m1 0h3m1 0h1M4 7.5h1m1 0h3m1 0h1m7 0h1m6 0h3m3 0h1m1 0h1m5 0h2m1 0h1m1 0h3m1 0h1M4 8.5h1m1 0h3m1 0h1m1 0h1m1 0h3m1 0h3m1 0h8m3 0h1m2 0h1m1 0h3m1 0h1m1 0h3m1 0h1M4 9.5h1m5 0h1m7 0h1m1 0h3m1 0h1m3 0h1m2 0h3m1 0h1m1 0h1m4 0h1m5 0h1M4 10.5h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7M14 11.5h2m3 0h4m1 0h1m3 0h4m2 0h1m1 0h3m1 0h1M4 12.5h1m2 0h6m1 0h2m6 0h1m1 0h5m1 0h1m1 0h2m1 0h1m3 0h1m1 0h1m2 0h1m1 0h3M5 13.5h3m3 0h2m1 0h2m5 0h2m1 0h2m2 0h5m1 0h2m2 0h1m2 0h4m1 0h2M5 14.5h1m1 0h2m1 0h1m5 0h1m2 0h1m2 0h1m1 0h3m10 0h2m2 0h1m3 0h1m1 0h2M5 15.5h2m2 0h1m2 0h4m1 0h1m4 0h3m2 0h1m2 0h3m1 0h1m2 0h4m2 0h6M5 16.5h1m4 0h1m2 0h4m1 0h3m1 0h2m1 0h1m3 0h4m2 0h1m2 0h2m3 0h2M5 17.5h3m1 0h1m1 0h1m3 0h2m2 0h3m5 0h2m2 0h1m2 0h1m2 0h1m1 0h2m1 0h2m2 0h1M4 18.5h2m1 0h2m1 0h2m4 0h5m5 0h1m2 0h5m1 0h1m5 0h3m3 0h2M4 19.5h1m1 0h2m3 0h2m2 0h1m1 0h1m1 0h1m1 0h2m3 0h1m2 0h3m1 0h1m1 0h1m1 0h2m1 0h1m1 0h3m1 0h3M6 20.5h1m1 0h3m1 0h1m2 0h1m1 0h1m1 0h4m1 0h1m3 0h1m1 0h3m2 0h3m1 0h1m1 0h1m1 0h1m2 0h1M4 21.5h1m1 0h2m1 0h1m3 0h5m2 0h1m4 0h2m1 0h1m1 0h2m2 0h1m4 0h2m3 0h2m1 0h2M4 22.5h5m1 0h2m3 0h1m1 0h1m3 0h2m9 0h3m1 0h1m2 0h1m3 0h1m2 0h2M4 23.5h1m1 0h1m1 0h1m3 0h1m2 0h1m2 0h1m1 0h2m1 0h2m2 0h4m1 0h3m8 0h2M4 24.5h1m1 0h9m2 0h1m1 0h2m1 0h7m2 0h1m3 0h3m1 0h7M6 25.5h1m1 0h1m3 0h1m1 0h4m1 0h3m2 0h1m3 0h1m1 0h2m3 0h1m3 0h2m3 0h4M4 26.5h1m1 0h1m1 0h1m1 0h1m1 0h2m2 0h1m1 0h1m1 0h1m3 0h1m1 0h1m1 0h3m1 0h2m3 0h4m1 0h1m1 0h3m1 0h1M4 27.5h1m1 0h1m1 0h1m3 0h1m5 0h1m2 0h1m1 0h2m3 0h2m3 0h3m1 0h1m1 0h2m3 0h1m1 0h2M5 28.5h1m2 0h8m2 0h2m4 0h5m1 0h1m1 0h4m4 0h5M8 29.5h1m2 0h2m3 0h1m2 0h1m2 0h1m2 0h2m1 0h1m1 0h2m3 0h1m1 0h1m2 0h2m1 0h1m3 0h1M4 30.5h3m1 0h1m1 0h1m1 0h1m1 0h1m3 0h1m2 0h1m1 0h3m4 0h1m1 0h2m2 0h1m2 0h1m1 0h2m2 0h2M4 31.5h1m1 0h1m2 0h1m2 0h1m1 0h1m2 0h3m1 0h1m5 0h4m1 0h1m1 0h1m1 0h5m2 0h1m2 0h1M6 32.5h1m2 0h3m2 0h1m1 0h2m1 0h1m1 0h2m2 0h1m2 0h1m3 0h1m4 0h1m2 0h3m1 0h1M4 33.5h1m1 0h2m1 0h1m2 0h1m2 0h1m1 0h1m1 0h3m3 0h3m2 0h1m2 0h1m4 0h2m3 0h2m2 0h2M7 34.5h1m2 0h5m1 0h5m1 0h2m1 0h1m2 0h1m4 0h4m2 0h1m2 0h1m1 0h2m1 0h1M4 35.5h2m2 0h1m2 0h1m1 0h1m1 0h1m2 0h8m2 0h2m1 0h4m3 0h2m1 0h1m5 0h2M9 36.5h5m1 0h5m3 0h1m1 0h1m1 0h5m5 0h1m7 0h2M5 37.5h2m2 0h1m2 0h3m6 0h1m1 0h2m3 0h1m1 0h2m1 0h3m2 0h5m4 0h1M8 38.5h1m1 0h1m1 0h3m2 0h1m3 0h2m1 0h1m1 0h1m2 0h1m1 0h1m3 0h1m2 0h2m1 0h5M5 39.5h4m5 0h1m2 0h4m3 0h1m2 0h4m1 0h1m2 0h2m3 0h1m1 0h1m1 0h2M4 40.5h1m2 0h2m1 0h1m1 0h2m4 0h12m3 0h1m1 0h1m2 0h7m3 0h1M12 41.5h1m1 0h3m1 0h3m3 0h1m3 0h1m2 0h1m3 0h1m2 0h1m1 0h1m3 0h1m1 0h2M4 42.5h7m1 0h1m2 0h4m1 0h3m1 0h1m1 0h1m1 0h2m1 0h1m2 0h2m4 0h1m1 0h1m1 0h1m1 0h2M4 43.5h1m5 0h1m1 0h1m1 0h1m1 0h2m1 0h3m2 0h1m3 0h3m2 0h6m1 0h1m3 0h3M4 44.5h1m1 0h3m1 0h1m1 0h1m2 0h2m1 0h2m1 0h1m2 0h6m3 0h1m3 0h1m2 0h6m2 0h1M4 45.5h1m1 0h3m1 0h1m1 0h5m3 0h2m1 0h3m1 0h3m3 0h3m1 0h2m4 0h2m1 0h1m1 0h1M4 46.5h1m1 0h3m1 0h1m3 0h5m3 0h5m1 0h2m1 0h2m2 0h1m1 0h1m1 0h3m1 0h1m1 0h4M4 47.5h1m5 0h1m2 0h1m2 0h1m1 0h1m2 0h1m4 0h2m2 0h1m3 0h2m1 0h3m1 0h3m2 0h3M4 48.5h7m1 0h5m2 0h3m3 0h1m2 0h1m1 0h3m1 0h2m2 0h1m1 0h1m1 0h2m1 0h1\"/></svg>\n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Confirm MFA
|
||||
|
||||
To confirm the MFA, we need to provide an MFA token to ensure the user can
|
||||
generate them.
|
||||
|
||||
### Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `mfa` | `boolean`| Must be set to `true` to confirm MFA |
|
||||
| `secret` | `boolean`| The secret returned when setting up MFA |
|
||||
| `token` | `boolean`| Must be set to `true` to confirm MFA |
|
||||
|
||||
### Response status codes
|
||||
|
||||
Possible status codes for this endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | access denied |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
### Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| -------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
|
||||
### Example request
|
||||
|
||||
```js
|
||||
import { authenticator } from '@otplib/preset-default'
|
||||
|
||||
const confirm = await axios.post(
|
||||
'https://backend.freesewing.org/account/mfa/jwt',
|
||||
{
|
||||
mfa: true,
|
||||
secret: mfa.secret,
|
||||
token: authenticator.generate(mfa.secret)
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Example response
|
||||
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
}
|
||||
```
|
||||
## Disable MFA
|
||||
|
||||
To disable MFA, you need to provide both the account password and a valid token.
|
||||
|
||||
### Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `mfa` | `boolean`| Must be set to `false` to disable MFA |
|
||||
| `password` | `boolean`| The User's password |
|
||||
| `token` | `boolean`| Must be set to `true` to confirm MFA |
|
||||
|
||||
### Response status codes
|
||||
|
||||
Possible status codes for this endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | access denied |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
### Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| -------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
|
||||
### Example request
|
||||
|
||||
```js
|
||||
import { authenticator } from '@otplib/preset-default'
|
||||
|
||||
const confirm = await axios.post(
|
||||
'https://backend.freesewing.org/account/mfa/jwt',
|
||||
{
|
||||
mfa: false,
|
||||
password: "I like big bewbs and I just can't lie",
|
||||
token: authenticator.generate(mfa.secret)
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Example response
|
||||
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
}
|
||||
```
|
|
@ -1,113 +0,0 @@
|
|||
---
|
||||
title: Sign In
|
||||
---
|
||||
|
||||
Sign in as a User with username and password, and optional MFA token.
|
||||
|
||||
## Endpoints
|
||||
|
||||
Password-based sign-in is possible via this endpoint:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/signin` | None |
|
||||
|
||||
<Note compact>This endpoint requires no authentication</Note>
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `username` | `string` | The E-mail address of the User |
|
||||
| `password` | `boolean`| The language code for the User |
|
||||
| `token` | `boolean`| The MFA token |
|
||||
|
||||
<Note compact>An MFA token is required (only) when the User enabled MFA</Note>
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | authentication failed |
|
||||
| <StatusCode status="403"/> | MFA token missing |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `token` | String | A JSON web token (JWT) token to authenticate with |
|
||||
| `account.id` | Number | The ID of the User |
|
||||
| `account.bio` | String | The bio of the User |
|
||||
| `account.consent` | Number | The consent given by the User |
|
||||
| `account.control` | Number | The control desired by the User |
|
||||
| `account.createdAt` | String | Date string indicating the moment the User was created |
|
||||
| `account.email` | String | The E-mail address currently tied to the User |
|
||||
| `account.github` | String | The GitHub username of the User |
|
||||
| `account.img` | String | The URL to the image stored with this User |
|
||||
| `account.imperial` | Boolean| Whether or not the User prefers imperial units |
|
||||
| `account.initial` | String | The E-mail address that the User was created with |
|
||||
| `account.language` | String | The language preferred by the user |
|
||||
| `account.lastSignIn`| String | Date string indicating them moment the User last signed in |
|
||||
| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled |
|
||||
| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter |
|
||||
| `account.patron` | Number | The level of patronage the user provides to FreeSewing |
|
||||
| `account.role` | String | The role of the User |
|
||||
| `account.status` | Number | The status of the user |
|
||||
| `account.updatedAt` | String | Date string indicating the last time the User was updated |
|
||||
| `account.username` | String | The username of the User |
|
||||
| `account.lusername` | String | A lowercased version of the username of the User |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const signup = await axios.post(
|
||||
'https://backend.freesewing.org/signup',
|
||||
{
|
||||
username: "jimmy",
|
||||
language: "I like big bewbs and I just can't lie",
|
||||
token: 231586
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5c...truncated",
|
||||
"account": {
|
||||
"id": 14,
|
||||
"bio": "",
|
||||
"consent": 1,
|
||||
"control": 1,
|
||||
"createdAt": "2022-11-19T18:15:22.642Z",
|
||||
"email": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"github": "",
|
||||
"img": "https://freesewing.org/avatar.svg",
|
||||
"imperial": false,
|
||||
"initial": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"language": "en",
|
||||
"lastSignIn": "2022-11-19T18:15:22.668Z",
|
||||
"mfaEnabled": false,
|
||||
"newsletter": false,
|
||||
"patron": 0,
|
||||
"role": "user",
|
||||
"status": 1,
|
||||
"updatedAt": "2022-11-19T18:15:22.668Z",
|
||||
"username": "jimmy",
|
||||
"lusername": "jimmy"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,126 +0,0 @@
|
|||
---
|
||||
title: Update account
|
||||
---
|
||||
|
||||
Updates an existing User account.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to update your own User account
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** account
|
||||
|
||||
## Endpoints
|
||||
|
||||
Updating an existing User account is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method put /> | `/account/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method put /> | `/account/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `bio` | `string` | The User's bio |
|
||||
| `consent` | `string` | A number that indicates [the consent given by the user](/reference/backend/account#the-consent-field-is-about-data-protection) |
|
||||
| `control` | `string` | A number that indicates [the level of control the user prefers](/reference/backend/account#the-control-field-is-about-keeping-it-simple) |
|
||||
| `github` | `string` | The User's username on GitHub |
|
||||
| `imperial` | `boolean`| Whether or not the User prefers imperial units |
|
||||
| `newsletter`| `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) |
|
||||
| `img` | `string` | An image [data-uri][duri] to store with this Person |
|
||||
| `password` | `string` | The (new) password for the User |
|
||||
| `username` | `string` | The (new) username for the User |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `account.id` | Number | The ID of the User |
|
||||
| `account.bio` | String | The bio of the User |
|
||||
| `account.consent` | Number | The consent given by the User |
|
||||
| `account.control` | Number | The control desired by the User |
|
||||
| `account.createdAt` | String | Date string indicating the moment the User was created |
|
||||
| `account.email` | String | The E-mail address currently tied to the User |
|
||||
| `account.github` | String | The GitHub username of the User |
|
||||
| `account.img` | String | The URL to the image stored with this User |
|
||||
| `account.imperial` | Boolean| Whether or not the User prefers imperial units |
|
||||
| `account.initial` | String | The E-mail address that the User was created with |
|
||||
| `account.language` | String | The language preferred by the user |
|
||||
| `account.lastSignIn`| String | Date string indicating them moment the User last signed in |
|
||||
| `account.mfaEnabled`| Boolean| Whether or not the User has MFA enabled |
|
||||
| `account.newsletter`| Boolean| Whether or not the User is subscribed to the FreeSewing newsletter |
|
||||
| `account.patron` | Number | The level of patronage the user provides to FreeSewing |
|
||||
| `account.role` | String | The role of the User |
|
||||
| `account.status` | Number | The status of the user |
|
||||
| `account.updatedAt` | String | Date string indicating the last time the User was updated |
|
||||
| `account.username` | String | The username of the User |
|
||||
| `account.lusername` | String | A lowercased version of the username of the User |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const udpate = await axios.put(
|
||||
'https://backend.freesewing.org/account/jwt',
|
||||
{
|
||||
bio: "I like imperial now",
|
||||
imperial: true,
|
||||
username: "ImperialLover"
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"account": {
|
||||
"id": 14,
|
||||
"bio": "I like imperial now",
|
||||
"consent": 1,
|
||||
"control": 1,
|
||||
"createdAt": "2022-11-19T18:15:22.642Z",
|
||||
"email": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"github": "",
|
||||
"img": "https://freesewing.org/avatar.svg",
|
||||
"imperial": true,
|
||||
"initial": "test_54c6856275aaa8a1@freesewing.dev",
|
||||
"language": "en",
|
||||
"lastSignIn": "2022-11-19T18:15:22.668Z",
|
||||
"mfaEnabled": false,
|
||||
"newsletter": false,
|
||||
"patron": 0,
|
||||
"role": "user",
|
||||
"status": 1,
|
||||
"updatedAt": "2022-11-19T18:15:22.668Z",
|
||||
"username": "ImperialLover",
|
||||
"lusername": "imperiallover"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,97 +0,0 @@
|
|||
---
|
||||
title: Create an API key
|
||||
---
|
||||
|
||||
Creates a new API key. An API key can be used to authenticate against the
|
||||
backend API.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to create an API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new API key is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/apikeys/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/apikeys/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `name` | `string` | A name for the API key |
|
||||
| `level` | `number` | A privilege level from 0 to 8. |
|
||||
| `expiresIn` | `number` | The number of seconds until the API key expires |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
<Warning>
|
||||
##### Make sure to save the secret
|
||||
The response body is the only time the API key's secret will be revealed.
|
||||
</Warning>
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | Either `success` or `error` |
|
||||
| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.secret` | `string` | The API secret |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const apiKey = axios.post(
|
||||
'https://backend.freesewing.org/apikeys/jwt',
|
||||
{
|
||||
name: 'My first API key',
|
||||
level: 2, // Read only
|
||||
expiresIn: 3600, // One hour
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"apikey": {
|
||||
"key": "7ea12968-7758-40b6-8c73-75cc99be762b",
|
||||
"secret": "503d7adbdb3ec18ab27adfcd895d8b47a8d6bc8307d548500fbf9c05a5a8820e",
|
||||
"level": 3,
|
||||
"expiresAt": "2022-11-06T15:57:30.190Z",
|
||||
"name": "My first API key",
|
||||
"userId": 61
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,58 +0,0 @@
|
|||
---
|
||||
title: Delete an API key
|
||||
---
|
||||
|
||||
Deletes an existing API key.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to delete an API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
Deleting an API key is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method delete /> | `/apikeys/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method delete /> | `/apikeys/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the API key you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="204"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
await axios.delete(
|
||||
'https://backend.freesewing.org/apikeys/7ea12968-7758-40b6-8c73-75cc99be762b/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
|
||||
```204.json
|
||||
```
|
||||
<Note>
|
||||
These endpoints return status code <StatusCode status="204"/> (no content) on
|
||||
success, with no response body.
|
||||
</Note>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
---
|
||||
title: API Keys
|
||||
---
|
||||
|
||||
API keys are a way to authenticate to the API with basic authentication.
|
||||
They are intended to be used when interacting with the API in an automated
|
||||
way such as from a script or a CI/CD pipeline.
|
||||
|
||||
They are an alternative to JSON Web Tokens (JWT) which is typically used
|
||||
to authenticate users in a browser session.
|
||||
|
||||
The FreeSewing backend REST API supports authentication both with JSON Web
|
||||
Tokens (JWT) as with API keys (KEY). This describes the endpoints that deal
|
||||
with creating, reading, and removing API keys. For authentication details,
|
||||
refer to [the section on
|
||||
authenticating](/reference/backend/authentication).
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
The following is good to keep in mind when working with API keys:
|
||||
|
||||
### API keys are immutable
|
||||
|
||||
Once created, API keys cannot be updated.
|
||||
You should remove them and re-create a new one if you want to make a change.
|
||||
|
||||
### API keys have an expiry
|
||||
|
||||
API keys have an expiry date. The maximum validity for an API key is 1 year.
|
||||
|
||||
### API keys have a permission level
|
||||
|
||||
API keys have a permission level. You can never create an API key with a higher
|
||||
permission level than your own permission level.
|
||||
|
||||
### Circumstances that will trigger your API keys to be revoked
|
||||
|
||||
As a precaution, all your API keys will be revoked when:
|
||||
|
||||
- Your role is downgraded to a role with fewer privileges
|
||||
- Your account is (b)locked
|
||||
- You revoke your consent for FreeSewing to process your data
|
||||
|
||||
<Note>
|
||||
This is not an exhaustive list. For example, if we find your use of our API to
|
||||
be excessive, we might also revoke your API keys to shield us from the
|
||||
financial impact of your use of our API.
|
||||
</Note>
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
---
|
||||
title: Read an API key
|
||||
---
|
||||
|
||||
Reads an existing API key. Note that the API secret can only be retrieved at
|
||||
the moment the API key is created.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `4` or higher is required to read an API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
Reading an API key is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/apikeys/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method get /> | `/apikeys/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the API key you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="404"/> | API key not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | `success` on success, and `error` on error |
|
||||
| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const keyInfo = await axios.get(
|
||||
'https://backend.freesewing.org/apikeys/7ea12968-7758-40b6-8c73-75cc99be762b/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"apikey": {
|
||||
"key": "7ea12968-7758-40b6-8c73-75cc99be762b",
|
||||
"level": 3,
|
||||
"expiresAt": "2022-11-06T15:57:30.190Z",
|
||||
"name": "My first API key",
|
||||
"userId": 61
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
title: Read the current API key
|
||||
---
|
||||
|
||||
Reads the current API key used to authenticate the request.
|
||||
For obvious reasons, this endpoint is only available with API key authentication.
|
||||
However, there's an equivalent endpoint for JWT authentication.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `0` or higher is required to read the current API key
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/whoami/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | `string` | `success` on success, and `error` on error |
|
||||
| `error` | `string` | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `apikey.key` | `string` | The API key |
|
||||
| `apikey.level` | `number` | The privilege level of the API key |
|
||||
| `apikey.expiresAt` | `string` | A string representation of the moment the API key expires |
|
||||
| `apikey.name` | `string` | The name of the API key |
|
||||
| `apikey.userId` | `number` | The ID of the user who created the API key |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const keyInfo = await axios.get(
|
||||
'https://backend.freesewing.org/whoami/key',
|
||||
{
|
||||
auth: {
|
||||
username: apikey.key,
|
||||
password: apikey.secret,
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"apikey": {
|
||||
"key": "7ea12968-7758-40b6-8c73-75cc99be762b",
|
||||
"level": 3,
|
||||
"expiresAt": "2022-11-06T15:57:30.190Z",
|
||||
"name": "My first API key",
|
||||
"userId": 61
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
---
|
||||
title: Authentication
|
||||
---
|
||||
|
||||
The FreeSewing backend API requires authentication for all but a handful of
|
||||
endpoints.
|
||||
|
||||
The API supports two different types of authentication:
|
||||
|
||||
| Type | Name | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| [JSON Web Tokens](#jwt-authentication) | `jwt` | This is typically used to authenticate humans in a browser session. |
|
||||
| [API Keys](#key-authentication) | `key` | This is typically used to interact with the API in an automated way. Like in a script, a CI/CD context, a serverless runner, and so on. |
|
||||
|
||||
While the API supports both, they are not supported on the same endpoint.
|
||||
Instead, add the authentication type you want to use as the final part of
|
||||
endpoint:
|
||||
|
||||
- `/some/endpoint/jwt` : Authenticate with a JSON Web Token
|
||||
- `/some/endpoint/key` : Authenticate with an API key and secret
|
||||
|
||||
## `jwt` authentication
|
||||
|
||||
The use of JSON Web Tokens ([jwt](https://jwt.io)) is typically used in a
|
||||
browser context where we want to establish a *session*.
|
||||
|
||||
To get a token, you must first authenticate at the [`/signin`](/reference/backend/account/signin) endpoint.
|
||||
You will receive a JSON Web Token (jwt) as part of the response.
|
||||
|
||||
In subsequent API calls, you must then include this token in the
|
||||
`Authorization` header prefixed by `Bearer `. Like his:
|
||||
|
||||
```js
|
||||
const account = await axios.get(
|
||||
`https://backend.freesewing.org/account/jwt`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## `key` authentication
|
||||
|
||||
The combination of API key & secret serves as a username & password for [HTTP
|
||||
basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication).
|
||||
|
||||
<Note>
|
||||
In basic authentication, the password is sent
|
||||
unencrypted. To guard against this, this API should only be served over a
|
||||
connection that is encrypted with TLS. (a URL starting with `https://`).
|
||||
</Note>
|
||||
|
||||
Sending a username and password with a request like this is supported
|
||||
pretty much everywhere. In addition, there is no need to establish a session
|
||||
first, so this make the entire transaction stateless.
|
||||
|
||||
Below is an example using curl:
|
||||
|
||||
```sh
|
||||
curl -u api-key-here:api-secret-here \
|
||||
https://backend.freesewing.org/account/key
|
||||
```
|
|
@ -1,67 +0,0 @@
|
|||
---
|
||||
title: Backend REST API
|
||||
---
|
||||
|
||||
This is the reference documentation for the FreeSewing backend REST API.
|
||||
|
||||
<Fixme compact>
|
||||
This documentation is under construction as we are re-working this API for v3.
|
||||
</Fixme>
|
||||
|
||||
## REST API docs
|
||||
|
||||
<ReadMore />
|
||||
|
||||
<Tip>
|
||||
|
||||
##### Also available as OpenAPI specification
|
||||
|
||||
The backend hosts its own auto-generated (Swagger) documentation based
|
||||
on the OpenAPI specification (v3): [backend3.freesewing.org/docs/
|
||||
](https://backend3.freesewing.org/docs/)
|
||||
|
||||
</Tip>
|
||||
|
||||
## About the FreeSewing backend
|
||||
|
||||
The FreeSewing backend handles all user data. Prior to version 3 of FreeSewing,
|
||||
the backend was only used internally as the data store for our frontend, the
|
||||
FreeSewing.org website.
|
||||
|
||||
In version 3, we have rewritten the backend with the explicit goal to offer it
|
||||
as a service to users and developers. This allows integration with other tools
|
||||
such as hosted instances of our lab, CLI tools, serverless runners, CI/CD
|
||||
environments and so on.
|
||||
|
||||
In other words, we no longer merely provide our own frontend, you can now also
|
||||
use our backend as a service to build your own projects.
|
||||
|
||||
<Warning>
|
||||
|
||||
##### Use, don't abuse
|
||||
|
||||
Our backend API runs in a cloud environment and while we do not charge for
|
||||
access to the API, we do need to pay the bills of said cloud provider.
|
||||
|
||||
As such, please be mindful of the amount of requests you generate. And if you
|
||||
have big plans, please reach out to us to discuss them first.
|
||||
|
||||
We will monitor the use of our backend API and we may at any moment decide to
|
||||
revoke API keys if we feel the use is beyond what we can or want to support.
|
||||
|
||||
</Warning>
|
||||
|
||||
## Database schema
|
||||
|
||||
The database schema for the backend is available in the [prisma.schema][prisma]
|
||||
file in our monorepo.
|
||||
|
||||
## Under the hood
|
||||
|
||||
The FreeSewing backend is written in [NodeJS](https://nodejs.org/en/) on top of
|
||||
[Express](https://expressjs.com/). It uses [Prisma](https://www.prisma.io/) to
|
||||
interface with a [SQLite database](https://www.sqlite.org/) database,
|
||||
[Sanity](https://www.sanity.io/) to store images, [AWS SES](
|
||||
https://aws.amazon.com/ses/) to send out emails, and
|
||||
[pino](https://github.com/pinojs/pino) for logging.
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
---
|
||||
title: Clone a Pattern
|
||||
---
|
||||
|
||||
Create a new Pattern by cloning an existing one.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to clone a
|
||||
Pattern depends on:
|
||||
|
||||
- Whether the Pattern is `public`
|
||||
- Who created the Pattern
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public Patterns | Non-Public Patterns |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `3` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/patterns/:id/clone/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/patterns/:id/clone/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const clone = axios.post(
|
||||
'https://backend.freesewing.org/patterns/10/clone/jwt',
|
||||
null,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 19,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": true,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:29:33.346Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,121 +0,0 @@
|
|||
---
|
||||
title: Create a Pattern
|
||||
---
|
||||
|
||||
Creates a new Pattern. This is typically used when users choose to save a pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to create a Pattern
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/patterns/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/patterns/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
The request body is a JSON object with the following properties:
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `data` | `object` | Any additional data to store with the pattern |
|
||||
| `design` | `string` | The name of the design this Pattern is an instance of |
|
||||
| `img` | `object` | An image [data-uri][duri] to store with this Pattern |
|
||||
| `name` | `string` | A name for the Pattern |
|
||||
| `notes` | `string` | User notes for the pattern |
|
||||
| `person` | `object` | The ID of the person to associate with this pattern |
|
||||
| `settings` | `object` | The settings object to (re-)create the Pattern |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const pattern = await axios.post(
|
||||
'https://backend.freesewing.org/patterns/jwt',
|
||||
{
|
||||
data: {
|
||||
some: 'value',
|
||||
}
|
||||
design: "aaron",
|
||||
img: "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...truncated",
|
||||
name: "Just a test",
|
||||
notes: "These are my notes",
|
||||
person: 17,
|
||||
public: true,
|
||||
settings: {
|
||||
sa: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 10,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": true,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:29:35.023Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,58 +0,0 @@
|
|||
---
|
||||
title: Delete a Pattern
|
||||
---
|
||||
|
||||
Deletes an existing Pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to delete a Pattern
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to delete **another user's** Pattern
|
||||
|
||||
## Endpoints
|
||||
|
||||
Deleting a Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method delete /> | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method delete /> | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="204"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
await axios.delete(
|
||||
'https://backend.freesewing.org/patterns/10/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
|
||||
```204.json
|
||||
```
|
||||
<Note>
|
||||
These endpoints return status code <StatusCode status="204"/> (no content) on
|
||||
success, with no response body.
|
||||
</Note>
|
|
@ -1,33 +0,0 @@
|
|||
---
|
||||
title: Patterns
|
||||
---
|
||||
|
||||
Patterns hold information on and settings for a user's patterns.
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
### The `design` property should hold the design
|
||||
|
||||
The `design` property should hold the name of the FreeSewing design.
|
||||
For example, `aaron`.
|
||||
|
||||
### The `notes` vs `data` properties
|
||||
|
||||
Both the `data` and `notes` properties can hold additional information about
|
||||
the pattern.
|
||||
|
||||
Keep in mind that:
|
||||
- The `notes` property is intended to be used by the user to add notes about
|
||||
their pattern. It will only accept data of type `string`.
|
||||
- The `data` property is intended to allow frontend developers to store
|
||||
additional data about the pattern. It will only accept data of type `object`.
|
||||
|
||||
### The `settings` property should hold the pattern settings
|
||||
|
||||
The `settings` property should hold [a settings object](/reference/settings)
|
||||
that can be passed to [the Pattern
|
||||
constructor](/reference/api/pattern#creating-a-pattern).
|
|
@ -1,109 +0,0 @@
|
|||
---
|
||||
title: Read a Pattern
|
||||
---
|
||||
|
||||
Reads an existing Pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to read a
|
||||
Pattern depends on:
|
||||
|
||||
- Whether the Pattern is `public`
|
||||
- Who created the Pattern
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public Patterns | Non-Public Patterns |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `1` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Reading a Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method get /> | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to read.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="404"/> | API key not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const pattern = await axios.get(
|
||||
'https://backend.freesewing.org/patterns/10/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 10,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": true,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:29:35.023Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,118 +0,0 @@
|
|||
---
|
||||
title: Update a Pattern
|
||||
---
|
||||
|
||||
Updates an existing Pattern.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to update a Pattern
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** Pattern
|
||||
|
||||
## Endpoints
|
||||
|
||||
Updating an existing Pattern is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method put /> | `/patterns/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method put /> | `/patterns/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Pattern you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `data` | `object` | Any additional data to store with the pattern |
|
||||
| `design` | `string` | The name of the design this Pattern is an instance of |
|
||||
| `img` | `object` | An image [data-uri][duri] to store with this Pattern |
|
||||
| `name` | `string` | A name for the Pattern |
|
||||
| `notes` | `string` | User notes for the pattern |
|
||||
| `person` | `object` | The ID of the person to associate with this pattern |
|
||||
| `settings` | `object` | The settings object to (re-)create the Pattern |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `pattern.id` | Number | The ID of the Pattern |
|
||||
| `pattern.createdAt` | String | Date string indicating the moment the pattern was created |
|
||||
| `pattern.data` | Object | Any additional data that was stored with Pattern data |
|
||||
| `pattern.design` | String | The name of the design of which this Pattern is an instance |
|
||||
| `pattern.img` | String | The URL to the image stored with this Pattern |
|
||||
| `pattern.name` | String | The name of the Pattern |
|
||||
| `pattern.notes` | String | The notes stored with the Pattern |
|
||||
| `pattern.personId` | Number | The ID of the Person for whom the Pattern was created |
|
||||
| `pattern.public` | Boolean| Indicates whether the Pattern is publicly accessible or not |
|
||||
| `pattern.settings` | Object | The settings used to (re-)create the Pattern |
|
||||
| `pattern.userId` | Number | The ID of the user who created the Pattern |
|
||||
| `pattern.updatedAt` | String | Date string indicating the last time the pattern was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const udpate = await axios.put(
|
||||
'https://backend.freesewing.org/patterns/10/jwt',
|
||||
{
|
||||
data: {
|
||||
some: 'new value',
|
||||
}
|
||||
public: false,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"pattern": {
|
||||
"id": 10,
|
||||
"createdAt": "2022-11-19T16:29:33.346Z",
|
||||
"data": {
|
||||
"some": "new value"
|
||||
},
|
||||
"design": "aaron",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"name": "Just a test",
|
||||
"notes": "These are my notes",
|
||||
"personId": 17,
|
||||
"public": false,
|
||||
"settings": {
|
||||
"sa": 5
|
||||
},
|
||||
"userId": 10,
|
||||
"updatedAt": "2022-11-19T16:43:39.223Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,103 +0,0 @@
|
|||
---
|
||||
title: Clone a Person
|
||||
---
|
||||
|
||||
Create a new Person by cloning an existing one.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to clone a
|
||||
Person depends on:
|
||||
|
||||
- Whether the Person is `public`
|
||||
- Who created the Pattern
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public Patterns | Non-Public Patterns |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `3` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/people/:id/clone/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/people/:id/clone/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Person you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const clone = axios.post(
|
||||
'https://backend.freesewing.org/people/27/clone/jwt',
|
||||
null,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 32,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": false,
|
||||
"name": "Someone",
|
||||
"notes": "These are some notes",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,110 +0,0 @@
|
|||
---
|
||||
title: Create a Person
|
||||
---
|
||||
|
||||
Creates a new Person.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to create a Person
|
||||
|
||||
## Endpoints
|
||||
|
||||
Creating a new Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method post /> | `/people/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method post /> | `/people/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `img` | `string` | An image [data-uri][duri] to store with this Person |
|
||||
| `imperial` | `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) |
|
||||
| `name` | `string` | A name for the Person |
|
||||
| `notes` | `string` | User notes for the person |
|
||||
| `measies` | `object` | The measurements for this person |
|
||||
| `public` | `string` | The name of the design this Pattern is an instance of |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="201"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="201" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const person = await axios.post(
|
||||
'https://backend.freesewing.org/people/jwt',
|
||||
{
|
||||
name: "Someone",
|
||||
notes: "These are some notes",
|
||||
measies: {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
public: true,
|
||||
imperial: false,
|
||||
img: "data:image/png;base64,iVBORw0KGgoAAAANSUhEU...truncated"
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```201.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 27,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": false,
|
||||
"name": "Someone",
|
||||
"notes": "These are some notes",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,58 +0,0 @@
|
|||
---
|
||||
title: Delete a Person
|
||||
---
|
||||
|
||||
Deletes an existing Person.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to delete a Person
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to delete **another user's** Person
|
||||
|
||||
## Endpoints
|
||||
|
||||
Deleting a Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method delete /> | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method delete /> | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Person you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="204"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
await axios.delete(
|
||||
'https://backend.freesewing.org/people/27/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
|
||||
```204.json
|
||||
```
|
||||
<Note>
|
||||
These endpoints return status code <StatusCode status="204"/> (no content) on
|
||||
success, with no response body.
|
||||
</Note>
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
title: People
|
||||
---
|
||||
|
||||
A Person hold information and measurements on the people we generate patterns
|
||||
for.
|
||||
|
||||
## Endpoints
|
||||
|
||||
<ReadMore />
|
||||
|
||||
## Notes
|
||||
|
||||
### The `imperial` property is a Boolean
|
||||
|
||||
- If the `imperial` property is `false`, the person wants metric units.
|
||||
- If the `imperial` property is `true`, the person wants imperial units.
|
||||
|
||||
### The `measies` property holds measurements
|
||||
|
||||
These measurements should be structured as an object that can be used for the
|
||||
`measurements` key in the [pattern settings
|
||||
object](/reference/settings/measurements).
|
||||
|
||||
The backend will only accept known measurements listed in the configuration file.
|
||||
|
||||
<Comment by="joost">
|
||||
##### Why we use measies instead of measurements
|
||||
First of all, _measies_ is a cute and adorable alternative for _measurements_
|
||||
coined by Karen. She deserves all the credit.
|
||||
|
||||
But also, I am slightly dyslexic and for some reason, I often drop the middle
|
||||
_e_ when typing measurements' (sic).
|
||||
|
||||
Those typos lead to bugs and I find it much easier to write _measies_.
|
||||
So because fewer bugs, plus did I mention it's cute?
|
||||
|
||||
</Comment>
|
||||
|
||||
### The `settings` property should hold the pattern settings
|
||||
|
||||
The `settings` property should hold [a settings object](/reference/settings)
|
||||
that can be passed to [the Pattern
|
||||
constructor](/reference/api/pattern#creating-a-pattern).
|
|
@ -1,103 +0,0 @@
|
|||
---
|
||||
title: Read a Person
|
||||
---
|
||||
|
||||
Reads an existing Person.
|
||||
|
||||
## Access control
|
||||
|
||||
The [Permission level](/reference/backend/rbac) required to read a
|
||||
Person depends on:
|
||||
|
||||
- Whether the Person is `public`
|
||||
- Who created the Person
|
||||
|
||||
The details are outlined in the table below:
|
||||
|
||||
| | Public People | Non-Public People |
|
||||
| ---------------: | :-------------: | :-----------------: |
|
||||
| **Your own** | `0` or higher | `4` or higher |
|
||||
| **Other user's** | `0` or higher | `5` or higher |
|
||||
|
||||
## Endpoints
|
||||
|
||||
Reading a Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method get /> | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method get /> | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request url
|
||||
|
||||
The url should contain the ID of the Person you wish to read.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="404"/> | API key not found |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const person = await axios.get(
|
||||
'https://backend.freesewing.org/people/27/jwt',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 27,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": false,
|
||||
"name": "Someone",
|
||||
"notes": "These are some notes",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,109 +0,0 @@
|
|||
---
|
||||
title: Update a Person
|
||||
---
|
||||
|
||||
Updates an existing Person.
|
||||
|
||||
## Access control
|
||||
|
||||
- [Permission level](/reference/backend/rbac) `3` or higher is required to update a Person
|
||||
- [Permission level](/reference/backend/rbac) `8` is required to update **another user's** Person
|
||||
|
||||
## Endpoints
|
||||
|
||||
Updating an existing Person is possible via these endpoints:
|
||||
|
||||
| Method | Path | Authentication |
|
||||
| --------: | :--- | :------------- |
|
||||
| <Method put /> | `/people/:id/jwt` | [JSON Web Token](/reference/backend/authentication#jwt-authentication) |
|
||||
| <Method put /> | `/people/:id/key` | [API Key & Secret](/reference/backend/authentication#key-authentication) |
|
||||
|
||||
## Request URL
|
||||
|
||||
The URL should contain the ID of the Person you wish to remove.
|
||||
It replaces the `:id` placeholder in the [endpoints listed above](#endpoints).
|
||||
|
||||
## Request body
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------: | :------- | :---------- |
|
||||
| `img` | `string` | An image [data-uri][duri] to store with this Person |
|
||||
| `imperial` | `boolean`| Whether this Person prefers imperial measurements (`true`) or not (`false`) |
|
||||
| `name` | `string` | A name for the Person |
|
||||
| `notes` | `string` | User notes for the person |
|
||||
| `measies` | `object` | The measurements for this person |
|
||||
| `public` | `string` | The name of the design this Pattern is an instance of |
|
||||
|
||||
## Response status codes
|
||||
|
||||
Possible status codes for these endpoints are:
|
||||
|
||||
| Status code | Description |
|
||||
| ----------: | :---------- |
|
||||
| <StatusCode status="200"/> | success |
|
||||
| <StatusCode status="400"/> | the request was malformed |
|
||||
| <StatusCode status="401"/> | the request lacks authentication |
|
||||
| <StatusCode status="403"/> | authentication failed |
|
||||
| <StatusCode status="500"/> | server error |
|
||||
|
||||
<Note>
|
||||
If the status code is not <StatusCode status="200" /> the `error` property
|
||||
in the response body should indicate the nature of the problem.
|
||||
</Note>
|
||||
|
||||
## Response body
|
||||
|
||||
| Value | Type | Description |
|
||||
| ------------------- | -------- | ----------- |
|
||||
| `result` | String | Either `success` or `error` |
|
||||
| `error` | String | Will give info on the nature of the error. Only set if an error occurred. |
|
||||
| `person.id` | Number | The ID of the Person |
|
||||
| `person.createdAt` | String | Date string indicating the moment the Person was created |
|
||||
| `person.img` | String | The URL to the image stored with this Person |
|
||||
| `person.name` | String | The name of the Person |
|
||||
| `person.notes` | String | The notes stored with the Person |
|
||||
| `person.userId` | Number | The ID of the user who created the Person |
|
||||
| `person.measies` | Object | The measurements of the Person |
|
||||
| `person.public` | Boolean| Indicates whether the Person is publicly accessible or not |
|
||||
| `person.updatedAt` | String | Date string indicating the last time the Person was updated |
|
||||
|
||||
## Example request
|
||||
|
||||
```js
|
||||
const udpate = await axios.put(
|
||||
'https://backend.freesewing.org/people/27/jwt',
|
||||
{
|
||||
notes: "Turns out some people like imperial",
|
||||
imperial: true,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Example response
|
||||
```200.json
|
||||
{
|
||||
"result": "success",
|
||||
"person": {
|
||||
"id": 27,
|
||||
"createdAt": "2022-11-19T17:36:41.342Z",
|
||||
"img": "https://cdn.sanity.io/images/hl5bw8cj/production/a1565c8c6c70cfe7ea0fdf5c65501cd885adbe78-200x187.png",
|
||||
"imperial": true,
|
||||
"name": "Someone",
|
||||
"notes": "Turns out some people like imperial",
|
||||
"userId": 12,
|
||||
"measies": {
|
||||
"chest": 930,
|
||||
"neck": 360
|
||||
},
|
||||
"public": true,
|
||||
"updatedAt": "2022-11-19T17:36:41.342Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[duri]: https://en.wikipedia.org/wiki/Data_URI_scheme
|
|
@ -1,42 +0,0 @@
|
|||
---
|
||||
title: Access control
|
||||
---
|
||||
|
||||
The backend API implements role-based access control (RBAC). Each
|
||||
user has a role and that role determines what they can and cannot do.
|
||||
|
||||
## Roles vs levels
|
||||
|
||||
In practice, the different user roles map to a permission level between
|
||||
`0` and `8`.
|
||||
The available roles and their privilege levels are:
|
||||
|
||||
- **user**: `4`
|
||||
- **bughunter**: `5`
|
||||
- **support**: `6`
|
||||
- **admin**: `8`
|
||||
|
||||
We offer more fine-grained control over the permission level when
|
||||
authenticating with API keys. When you create an API key, you can choose any
|
||||
permissioning level that is equal or lower than your own role's permission level.
|
||||
|
||||
This allows you to -- for example -- generate an API key that only have read
|
||||
access to your data.
|
||||
|
||||
## Permission levels
|
||||
|
||||
The table below lists the privilege of all levels as well as their
|
||||
corresponding <small><small><b>`role`</b></small></small>
|
||||
|
||||
| Level | Abilities | <small><small>`user`</small></small> | <small><small>`bughunter`</small></small> | <small><small>`support`</small></small> | <small><small>`admin`</small></small> |
|
||||
| --: | -- | :--: | :--: | :--: | :--: |
|
||||
| `0` | authenticate | ✅ | ✅ | ✅ | ✅ |
|
||||
| `1` | **read** people and patterns | ✅ | ✅ | ✅ | ✅ |
|
||||
| `2` | **read all** account data | ✅ | ✅ | ✅ | ✅ |
|
||||
| `3` | **write** people or patterns | ✅ | ✅ | ✅ | ✅ |
|
||||
| `4` | **write all** account data | ✅ | ✅ | ✅ | ✅ |
|
||||
| `5` | **read** people or patterns of **other users** | ❌ | ✅ | ✅ | ✅ |
|
||||
| `6` | **read all** account data of **other users** | ❌ | ❌ | ✅ | ✅ |
|
||||
| `7` | **write** account data of **other users** through **specific support methods** | ❌ | ❌ | ✅ | ✅ |
|
||||
| `8` | impersonate other users, **full write access** | ❌ | ❌ | ❌ | ✅ |
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue