mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-14 07:04:45 -04:00
docs: Split up 2.0.md and rename to dev_notes.md
Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
parent
bec48f3c22
commit
c278f6d78b
5 changed files with 67 additions and 62 deletions
|
@ -1,60 +0,0 @@
|
||||||
# 2.0 Development Notes
|
|
||||||
This document collects notes and decisions taken during the development of HedgeDoc 2.0.
|
|
||||||
It should be converted to a properly structured documentation, but having unstructured docs
|
|
||||||
is better than having no docs.
|
|
||||||
|
|
||||||
## Supported databases
|
|
||||||
We intend to officially support and test these databases:
|
|
||||||
- SQLite (for development and smaller instances)
|
|
||||||
- PostgreSQL
|
|
||||||
- MariaDB
|
|
||||||
|
|
||||||
## Special Groups
|
|
||||||
The software provides two special groups which have no explicit users:
|
|
||||||
- `everyone` (Describing that everyone who wants to access a note can do if it is enabled in the config.)
|
|
||||||
- `loggedIn` (Describing all users which are logged in)
|
|
||||||
|
|
||||||
## Deleting notes and revisions
|
|
||||||
- The owner of a note may delete it.
|
|
||||||
- By default, this also removes all revisions and all files that were uploaded to that note.
|
|
||||||
- The owner may choose to skip deleting associated uploads, leaving them without a note.
|
|
||||||
- The frontend should show a list of all uploads that will be affected
|
|
||||||
and provide a method of skipping deletion.
|
|
||||||
- The owner of a note may delete all revisions. This effectively purges the edit
|
|
||||||
history of a note.
|
|
||||||
|
|
||||||
## Entity `create` methods
|
|
||||||
|
|
||||||
Because we need to have empty constructors in our entity classes for TypeORM to work, the actual constructor is a separate `create` method. These methods should adhere to these guidelines:
|
|
||||||
|
|
||||||
- Only require the non-optional properties of the corresponding entity
|
|
||||||
- Have no optional parameters
|
|
||||||
- Have no lists which can be empty (so probably most of them)
|
|
||||||
- Should either return a complete and fully useable instance or return a Pick/Omit type.
|
|
||||||
- Exceptions to these rules are allowed, if they are mentioned in the method documentation
|
|
||||||
|
|
||||||
## Auth tokens for the public API
|
|
||||||
The public API uses bearer tokens for authentication.
|
|
||||||
|
|
||||||
When a new token is requested via the private API, the backend generates a 64 bytes-long secret of
|
|
||||||
cryptographically secure data and returns it as a base64url-encoded string, along with an identifier.
|
|
||||||
That string can then be used by clients as a bearer token.
|
|
||||||
|
|
||||||
A SHA-512 hash of the secret is stored in the database. To validate tokens, the backend computes the hash of the provided
|
|
||||||
secret and checks it against the stored hash for the provided identifier.
|
|
||||||
|
|
||||||
### Choosing a hash function
|
|
||||||
Unfortunately, there does not seem to be any explicit documentation about our exact use-case.
|
|
||||||
Most docs describe classic password-saving scenarios and recommend bcrypt, scrypt or argon2.
|
|
||||||
These hashing functions are slow to stop brute-force or dictionary attacks, which would expose the original,
|
|
||||||
user-provided password, that may have been reused across multiple services.
|
|
||||||
|
|
||||||
We have a very different scenario:
|
|
||||||
Our API tokens are 64 bytes of cryptographically strong pseudorandom data.
|
|
||||||
Brute-force or dictionary attacks are therefore virtually impossible, and tokens are not reused across multiple services.
|
|
||||||
We therefore need to only guard against one scenario:
|
|
||||||
An attacker gains read-only access to the database. Saving only hashes in the database prevents the attacker
|
|
||||||
from authenticating themselves as a user. The hash-function does not need to be very slow,
|
|
||||||
as the randomness of the original token prevents inverting the hash. The function actually needs to be reasonably fast,
|
|
||||||
as the hash must be computed on every request to the public API.
|
|
||||||
SHA-512 (or alternatively SHA3) fits this use-case.
|
|
|
@ -6,6 +6,31 @@ All requests to the public API require authentication using a [bearer token](htt
|
||||||
This token can be generated using the profile page in the frontend
|
This token can be generated using the profile page in the frontend
|
||||||
(which in turn uses the private API to generate the token).
|
(which in turn uses the private API to generate the token).
|
||||||
|
|
||||||
|
### Token generation
|
||||||
|
|
||||||
|
When a new token is requested via the private API, the backend generates a 64 bytes-long secret of
|
||||||
|
cryptographically secure data and returns it as a base64url-encoded string, along with an identifier.
|
||||||
|
That string can then be used by clients as a bearer token.
|
||||||
|
|
||||||
|
A SHA-512 hash of the secret is stored in the database. To validate tokens, the backend computes the hash of the provided
|
||||||
|
secret and checks it against the stored hash for the provided identifier.
|
||||||
|
|
||||||
|
#### Choosing a hash function
|
||||||
|
Unfortunately, there does not seem to be any explicit documentation about our exact use-case.
|
||||||
|
Most docs describe classic password-saving scenarios and recommend bcrypt, scrypt or argon2.
|
||||||
|
These hashing functions are slow to stop brute-force or dictionary attacks, which would expose the original,
|
||||||
|
user-provided password, that may have been reused across multiple services.
|
||||||
|
|
||||||
|
We have a very different scenario:
|
||||||
|
Our API tokens are 64 bytes of cryptographically strong pseudorandom data.
|
||||||
|
Brute-force or dictionary attacks are therefore virtually impossible, and tokens are not reused across multiple services.
|
||||||
|
We therefore need to only guard against one scenario:
|
||||||
|
An attacker gains read-only access to the database. Saving only hashes in the database prevents the attacker
|
||||||
|
from authenticating themselves as a user. The hash-function does not need to be very slow,
|
||||||
|
as the randomness of the original token prevents inverting the hash. The function actually needs to be reasonably fast,
|
||||||
|
as the hash must be computed on every request to the public API.
|
||||||
|
SHA-512 (or alternatively SHA3) fits this use-case.
|
||||||
|
|
||||||
## Private API
|
## Private API
|
||||||
|
|
||||||
The private API uses a session cookie to authenticate the user.
|
The private API uses a session cookie to authenticate the user.
|
||||||
|
|
|
@ -54,7 +54,18 @@ All mentioned fields are extracted from the note content by the backend on save
|
||||||
|
|
||||||
`version` specifies if a note is an old HedgeDoc 1 note, or a new HedgeDoc 2 note. This is mainly used to redirect old notes form <https://md.example.org/noteid> to <https://md.example.org/n/noteid>.
|
`version` specifies if a note is an old HedgeDoc 1 note, or a new HedgeDoc 2 note. This is mainly used to redirect old notes form <https://md.example.org/noteid> to <https://md.example.org/n/noteid>.
|
||||||
|
|
||||||
### Conversion of HedgeDoc 1 notes
|
## Deleting Notes
|
||||||
|
|
||||||
|
- The owner of a note may delete it.
|
||||||
|
- By default, this also removes all revisions and all files that were uploaded to that note.
|
||||||
|
- The owner may choose to skip deleting associated uploads, leaving them without a note.
|
||||||
|
- The frontend should show a list of all uploads that will be affected
|
||||||
|
and provide a method of skipping deletion.
|
||||||
|
- The owner of a note may delete all revisions. This effectively purges the edit
|
||||||
|
history of a note.
|
||||||
|
|
||||||
|
|
||||||
|
## Conversion of HedgeDoc 1 notes
|
||||||
|
|
||||||
First we want to define some terms of the HedgeDoc 1 notes:
|
First we want to define some terms of the HedgeDoc 1 notes:
|
||||||
|
|
||||||
|
|
29
docs/content/dev/dev_notes.md
Normal file
29
docs/content/dev/dev_notes.md
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Development Notes
|
||||||
|
This document collects notes and decisions taken during the development of HedgeDoc 2.0.
|
||||||
|
It should be converted to a properly structured documentation, but having unstructured docs
|
||||||
|
is better than having no docs.
|
||||||
|
|
||||||
|
## Supported databases
|
||||||
|
We intend to officially support and test these databases:
|
||||||
|
|
||||||
|
- SQLite (for development and smaller instances)
|
||||||
|
- PostgreSQL
|
||||||
|
- MariaDB
|
||||||
|
|
||||||
|
## Special Groups
|
||||||
|
The software provides two special groups which have no explicit users:
|
||||||
|
|
||||||
|
- `everyone` (Describing that everyone who wants to access a note can do if it is enabled in the config.)
|
||||||
|
- `loggedIn` (Describing all users which are logged in)
|
||||||
|
|
||||||
|
## Entity `create` methods
|
||||||
|
|
||||||
|
Because we need to have empty constructors in our entity classes for TypeORM to work, the actual constructor is a separate `create` method. These methods should adhere to these guidelines:
|
||||||
|
|
||||||
|
- Only require the non-optional properties of the corresponding entity
|
||||||
|
- Have no optional parameters
|
||||||
|
- Have no lists which can be empty (so probably most of them)
|
||||||
|
- Should either return a complete and fully useable instance or return a Pick/Omit type.
|
||||||
|
- Exceptions to these rules are allowed, if they are mentioned in the method documentation
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ nav:
|
||||||
- Development:
|
- Development:
|
||||||
- Getting Started: dev/getting-started.md
|
- Getting Started: dev/getting-started.md
|
||||||
- Frontend: dev/setup/frontend.md
|
- Frontend: dev/setup/frontend.md
|
||||||
- '2.0 Development': dev/2.0.md
|
- Development Notes: dev/dev_notes.md
|
||||||
- Design Documents:
|
- Design Documents:
|
||||||
- API Authentication: dev/design_docs/api_auth.md
|
- API Authentication: dev/design_docs/api_auth.md
|
||||||
- Configuration: dev/design_docs/config.md
|
- Configuration: dev/design_docs/config.md
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue