CI: Remove documentation in favor of notion.so
This also means we no longer need the publish to pub.dev script because it just removes the docs as a workaround and does nothing more.
This commit is contained in:
parent
b4c922f49c
commit
f36299c3d7
|
|
@ -98,37 +98,6 @@ code_quality:
|
|||
paths:
|
||||
- code-quality-report.json
|
||||
|
||||
build_doc:
|
||||
tags:
|
||||
- docker
|
||||
stage: builddocs
|
||||
image: registry.gitlab.com/larodar/mdbook-dtmo:latest
|
||||
script:
|
||||
- cd docs
|
||||
- mdbook-dtmo build -d public
|
||||
- mv public ../doc-public
|
||||
artifacts:
|
||||
paths:
|
||||
- doc-public
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
|
||||
pages:
|
||||
tags:
|
||||
- linux
|
||||
stage: deploy
|
||||
image: alpine:latest
|
||||
script:
|
||||
- mv doc-public ./home/doc
|
||||
- mv home public
|
||||
dependencies:
|
||||
- build_doc
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
|
||||
dry-run:
|
||||
stage: publish
|
||||
image: google/dart
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
[book]
|
||||
title = "Famedly Matrix SDK Documentation"
|
||||
description = "Famedly Matrix SDK Documentation"
|
||||
|
||||
[preprocessor.mermaid]
|
||||
command = "mdbook-mermaid"
|
||||
renderer = ["html"]
|
||||
|
||||
[preprocessor.toc]
|
||||
command = "mdbook-toc"
|
||||
|
||||
[output.html]
|
||||
additional-css = ["mermaid.css"]
|
||||
additional-js = ["mermaid.min.js", "mermaid-init.js"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
mermaid.initialize({startOnLoad:true});
|
||||
351
docs/mermaid.css
351
docs/mermaid.css
|
|
@ -1,351 +0,0 @@
|
|||
/* Flowchart variables */
|
||||
/* Sequence Diagram variables */
|
||||
/* Gantt chart variables */
|
||||
.mermaid .mermaid .label {
|
||||
color: #333;
|
||||
}
|
||||
.mermaid .node rect,
|
||||
.mermaid .node circle,
|
||||
.mermaid .node ellipse,
|
||||
.mermaid .node polygon {
|
||||
fill: #ECECFF;
|
||||
stroke: #CCCCFF;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.mermaid .arrowheadPath {
|
||||
fill: #333333;
|
||||
}
|
||||
.mermaid .edgePath .path {
|
||||
stroke: #333333;
|
||||
}
|
||||
.mermaid .edgeLabel {
|
||||
background-color: #e8e8e8;
|
||||
}
|
||||
.mermaid .cluster rect {
|
||||
fill: #ffffde !important;
|
||||
rx: 4 !important;
|
||||
stroke: #aaaa33 !important;
|
||||
stroke-width: 1px !important;
|
||||
}
|
||||
.mermaid .cluster text {
|
||||
fill: #333;
|
||||
}
|
||||
.mermaid .actor {
|
||||
stroke: #CCCCFF;
|
||||
fill: #ECECFF;
|
||||
}
|
||||
.mermaid text.actor {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.mermaid .actor-line {
|
||||
stroke: grey;
|
||||
}
|
||||
.mermaid .messageLine0 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: #333;
|
||||
}
|
||||
.mermaid .messageLine1 {
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: "2 2";
|
||||
stroke: #333;
|
||||
}
|
||||
.mermaid #arrowhead {
|
||||
fill: #333;
|
||||
}
|
||||
.mermaid #crosshead path {
|
||||
fill: #333 !important;
|
||||
stroke: #333 !important;
|
||||
}
|
||||
.mermaid .messageText {
|
||||
fill: #333;
|
||||
stroke: none;
|
||||
}
|
||||
.mermaid .labelBox {
|
||||
stroke: #CCCCFF;
|
||||
fill: #ECECFF;
|
||||
}
|
||||
.mermaid .labelText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.mermaid .loopText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
}
|
||||
.mermaid .loopLine {
|
||||
stroke-width: 2;
|
||||
stroke-dasharray: "2 2";
|
||||
marker-end: "url(#arrowhead)";
|
||||
stroke: #CCCCFF;
|
||||
}
|
||||
.mermaid .note {
|
||||
stroke: #aaaa33;
|
||||
fill: #fff5ad;
|
||||
}
|
||||
.mermaid .noteText {
|
||||
fill: black;
|
||||
stroke: none;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
/** Section styling */
|
||||
.mermaid .section {
|
||||
stroke: none;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.mermaid .section0 {
|
||||
fill: rgba(102, 102, 255, 0.49);
|
||||
}
|
||||
.mermaid .section2 {
|
||||
fill: #fff400;
|
||||
}
|
||||
.mermaid .section1,
|
||||
.mermaid .section3 {
|
||||
fill: white;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.mermaid .sectionTitle0 {
|
||||
fill: #333;
|
||||
}
|
||||
.mermaid .sectionTitle1 {
|
||||
fill: #333;
|
||||
}
|
||||
.mermaid .sectionTitle2 {
|
||||
fill: #333;
|
||||
}
|
||||
.mermaid .sectionTitle3 {
|
||||
fill: #333;
|
||||
}
|
||||
.mermaid .sectionTitle {
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
text-height: 14px;
|
||||
}
|
||||
/* Grid and axis */
|
||||
.mermaid .grid .tick {
|
||||
stroke: lightgrey;
|
||||
opacity: 0.3;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.mermaid .grid path {
|
||||
stroke-width: 0;
|
||||
}
|
||||
/* Today line */
|
||||
.mermaid .today {
|
||||
fill: none;
|
||||
stroke: red;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
/* Task styling */
|
||||
/* Default task */
|
||||
.mermaid .task {
|
||||
stroke-width: 2;
|
||||
}
|
||||
.mermaid .taskText {
|
||||
text-anchor: middle;
|
||||
font-size: 11px;
|
||||
}
|
||||
.mermaid .taskTextOutsideRight {
|
||||
fill: black;
|
||||
text-anchor: start;
|
||||
font-size: 11px;
|
||||
}
|
||||
.mermaid .taskTextOutsideLeft {
|
||||
fill: black;
|
||||
text-anchor: end;
|
||||
font-size: 11px;
|
||||
}
|
||||
/* Specific task settings for the sections*/
|
||||
.mermaid .taskText0,
|
||||
.mermaid .taskText1,
|
||||
.mermaid .taskText2,
|
||||
.mermaid .taskText3 {
|
||||
fill: white;
|
||||
}
|
||||
.mermaid .task0,
|
||||
.mermaid .task1,
|
||||
.mermaid .task2,
|
||||
.mermaid .task3 {
|
||||
fill: #8a90dd;
|
||||
stroke: #534fbc;
|
||||
}
|
||||
.mermaid .taskTextOutside0,
|
||||
.mermaid .taskTextOutside2 {
|
||||
fill: black;
|
||||
}
|
||||
.mermaid .taskTextOutside1,
|
||||
.mermaid .taskTextOutside3 {
|
||||
fill: black;
|
||||
}
|
||||
/* Active task */
|
||||
.mermaid .active0,
|
||||
.mermaid .active1,
|
||||
.mermaid .active2,
|
||||
.mermaid .active3 {
|
||||
fill: #bfc7ff;
|
||||
stroke: #534fbc;
|
||||
}
|
||||
.mermaid .activeText0,
|
||||
.mermaid .activeText1,
|
||||
.mermaid .activeText2,
|
||||
.mermaid .activeText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
/* Completed task */
|
||||
.mermaid .done0,
|
||||
.mermaid .done1,
|
||||
.mermaid .done2,
|
||||
.mermaid .done3 {
|
||||
stroke: grey;
|
||||
fill: lightgrey;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.mermaid .doneText0,
|
||||
.mermaid .doneText1,
|
||||
.mermaid .doneText2,
|
||||
.mermaid .doneText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
/* Tasks on the critical line */
|
||||
.mermaid .crit0,
|
||||
.mermaid .crit1,
|
||||
.mermaid .crit2,
|
||||
.mermaid .crit3 {
|
||||
stroke: #ff8888;
|
||||
fill: red;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.mermaid .activeCrit0,
|
||||
.mermaid .activeCrit1,
|
||||
.mermaid .activeCrit2,
|
||||
.mermaid .activeCrit3 {
|
||||
stroke: #ff8888;
|
||||
fill: #bfc7ff;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.mermaid .doneCrit0,
|
||||
.mermaid .doneCrit1,
|
||||
.mermaid .doneCrit2,
|
||||
.mermaid .doneCrit3 {
|
||||
stroke: #ff8888;
|
||||
fill: lightgrey;
|
||||
stroke-width: 2;
|
||||
cursor: pointer;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.mermaid .doneCritText0,
|
||||
.mermaid .doneCritText1,
|
||||
.mermaid .doneCritText2,
|
||||
.mermaid .doneCritText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
.mermaid .activeCritText0,
|
||||
.mermaid .activeCritText1,
|
||||
.mermaid .activeCritText2,
|
||||
.mermaid .activeCritText3 {
|
||||
fill: black !important;
|
||||
}
|
||||
.mermaid .titleText {
|
||||
text-anchor: middle;
|
||||
font-size: 18px;
|
||||
fill: black;
|
||||
}
|
||||
.mermaid g.classGroup text {
|
||||
fill: #9370DB;
|
||||
stroke: none;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 10px;
|
||||
}
|
||||
.mermaid g.classGroup rect {
|
||||
fill: #ECECFF;
|
||||
stroke: #9370DB;
|
||||
}
|
||||
.mermaid g.classGroup line {
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid svg .classLabel .box {
|
||||
stroke: none;
|
||||
stroke-width: 0;
|
||||
fill: #ECECFF;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.mermaid svg .classLabel .label {
|
||||
fill: #9370DB;
|
||||
font-size: 10px;
|
||||
}
|
||||
.mermaid .relation {
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
.mermaid .composition {
|
||||
fill: #9370DB;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #compositionStart {
|
||||
fill: #9370DB;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #compositionEnd {
|
||||
fill: #9370DB;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid .aggregation {
|
||||
fill: #ECECFF;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #aggregationStart {
|
||||
fill: #ECECFF;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #aggregationEnd {
|
||||
fill: #ECECFF;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #dependencyStart {
|
||||
fill: #9370DB;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #dependencyEnd {
|
||||
fill: #9370DB;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #extensionStart {
|
||||
fill: #9370DB;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid #extensionEnd {
|
||||
fill: #9370DB;
|
||||
stroke: #9370DB;
|
||||
stroke-width: 1;
|
||||
}
|
||||
.mermaid .node text {
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 14px;
|
||||
}
|
||||
.mermaid div.mermaidTooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
max-width: 200px;
|
||||
padding: 2px;
|
||||
font-family: 'trebuchet ms', verdana, arial;
|
||||
font-size: 12px;
|
||||
background: #ffffde;
|
||||
border: 1px solid #aaaa33;
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,2 +0,0 @@
|
|||
[About](readme.md)
|
||||
[End-to-end encryption](e2ee.md)
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
# End-to-end encryption
|
||||
|
||||
End-to-end encryption is rather complicated. Beyond the
|
||||
[bare-bones implementation](https://matrix.org/docs/guides/end-to-end-encryption-implementation-guide)
|
||||
and [advanced e2ee features](https://matrix.org/docs/guides/implementing-more-advanced-e-2-ee-features-such-as-cross-signing)
|
||||
a lot of miscellaneous small tricks have been added to make the e2ee experience smoother. This file
|
||||
acts as a list of said tricks, in no particular order.
|
||||
|
||||
## Rotate of megolm sessions
|
||||
Megolm sessions are rotated (cleared) after encrypting 100 messages or one week, whatever happens
|
||||
earlier. Additionally, megolm sessions are rotated if a device leaves the room. If a new device joins
|
||||
the room the megolm session is re-used and it is sent at a later index to that device.
|
||||
|
||||
## Requesting known SSSS secrets
|
||||
Upon new login you can either self-verify and cache SSSS secrets with your recovery passphrase / recovery
|
||||
key to get the cross-signing and megolm backup keys, or you can self-verify via emoji and afterwards
|
||||
requests from other devices, after successful self-verification.
|
||||
|
||||
For SSSS secrets we want to cache (self-signing key, user-signing key, megolm backup key) we automatically
|
||||
request those secrets from other devices after successful self-verification, if we weren't verified
|
||||
before and we don't have them cached.
|
||||
|
||||
Additionally, if we still don't have the secrets cached, we try to intelligently guess if other of
|
||||
our own verified devices are online, max. once per 15 min. This is triggered on receiving `to_device`
|
||||
events from ourself and getting messages down `/sync` from ourself that weren't sent by us.
|
||||
|
||||
## Starting megolm sessions while typing
|
||||
In order to speed up sending of messages in e2ee rooms, megolm sessions are already created and sent
|
||||
while a user is typing in the room. While this in theory can result in a megolm session being used to
|
||||
encrypt zero messages (a device of the room is being removed between typing and sending), in most cases
|
||||
this will increase sending performance.
|
||||
|
||||
## Auto-reply to foreign key requests
|
||||
When sending a megolm session we record to which device at which index we send the megolm session. On
|
||||
key requests from other users, we automatically forward the megolm session at the index noted, as in
|
||||
theory they should have that key anyways. This helps to improve recovery from unable to decrypts.
|
||||
|
||||
## Chunked priority sending of megolm keys
|
||||
In the background we record the last activity time of all devices. This is determined on when we
|
||||
received the last encrypted `to_device` message of that device. (It could be optimized by also including
|
||||
encrypted room events). Now, when creating a megolm session, we sort the device list, and chunk it into
|
||||
chunks of 20. We wait for the first chunk to send, and send the remaining chunks in the background.
|
||||
This way we make sure that the devices active right now get the key for sure right away, and then,
|
||||
prioritized by activity, the next devices get the keys seemlessly in the background.
|
||||
|
||||
As we implemented auto-reply to foreign key requests other devices can already request the key before
|
||||
it got received, also ensuring high-availability in case of a badly sorted list.
|
||||
|
||||
## OTK (One-Time Key) upload and failure
|
||||
Because libolm can only hold up to 100 OTKs at all times, we must not upload 100 OTKs. If we were to
|
||||
do that then another person might claim an OTK and, before they send you a `to_device` message, you'd
|
||||
upload a new OTK to fill up the 100 OTKs again, forgetting the OTK the other person used. So, we try
|
||||
to keep the OTKs uploaded at roughly 2/3, so 66 keys.
|
||||
|
||||
Additionally, we must make sure that we do not lose any OTKs uploaded, even if the upload request
|
||||
failed. So we store the olm account, and thus the OTKs, both before and after requesting. We only
|
||||
mark the OTKs as uploaded after the request was successful.
|
||||
|
||||
If now the upload fails, we already stored the non-uploaded OTKs. Thus, next time when attempting to
|
||||
upload, we take the non-uploaded OTKs into account for how many to create, and then re-try the
|
||||
uploading.
|
||||
|
||||
```mermaid
|
||||
graph
|
||||
sync(Sync response says more than half of all OTKs have been used) --> generate(Generate new OTKs, so that we have up to 2/3rd of all full)
|
||||
generate --> store(Store Olm-Account and OTKs in database)
|
||||
store --> upload(Attempt to upload OTKs)
|
||||
upload -- Success --> mark(Mark OTKs as uploaded)
|
||||
mark --> store2(Store Olm-Account and OTKs in database)
|
||||
upload -- Failure --> fail(Don't do anything)
|
||||
fail --> sync
|
||||
```
|
||||
|
||||
## Auto-recreate corrupted olm sessions
|
||||
If we receive an encrypted `to_device` message that we can't decrypt, that means the olm session with
|
||||
the remote device got corrupted. So, we create a new olm session and send an encrypted `m.dummy` via
|
||||
`to_device` messaging to signal the new olm session.
|
||||
|
||||
## Replay of sent `to_device` messages
|
||||
As olm is a double-ratchet the ratchet on the receiving and the sending client must be the same. So,
|
||||
a lost `to_device` event could be fatal to the olm session. Thus, we record all sent `to_device` messages
|
||||
that failed to send. Before sending the next `to_device` message (and periodically after `/sync`) we
|
||||
empty that queue, to make sure that the `to_device` messages are sent, and thus the olm ratchets stay
|
||||
in sync.
|
||||
|
||||
```mermaid
|
||||
graph
|
||||
trigger(Trigger to send a to_device message) --> queue(Attempt to re-send all existing to_device messages from the queue)
|
||||
queue -- Failure --> add_queue(Add to_device message to queue)
|
||||
queue -- Success --> remove_queue(Remove sent to_device messages from queue)
|
||||
remove_queue --> send(Attempt to actually send the to_device message)
|
||||
send -- Success --> Done
|
||||
send -- Failure --> add_queue
|
||||
```
|
||||
|
||||
Additionally, when sending an encrypted `to_device` event to a device, we remember that content, one
|
||||
message per recipient device. Now, if we receive an encrypted `m.dummy`, this usually indicates that
|
||||
the remote device started a new olm session, likely due to corruption. So, we re-send the saved
|
||||
content, as it might e.g. contain a megolm key needed to decrypt messages.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Some notes
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh -e
|
||||
mv docs .docs
|
||||
flutter pub publish --dry-run
|
||||
flutter pub publish
|
||||
mv .docs docs
|
||||
Loading…
Reference in New Issue