Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new notify mechanism and refined selfAddr semantics, rate limits API and rework sendUpdate docs and drop 'descr' #94

Merged
merged 12 commits into from
Jan 11, 2025
Merged
3 changes: 3 additions & 0 deletions src-docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
- [selfAddr & selfName](./spec/selfAddr_and_selfName.md)
- [joinRealtimeChannel](./spec/joinRealtimeChannel.md)
- [Messenger implementations](./spec/messenger.md)
- [CHANGELOG](./spec/CHANGELOG.md)

- [Shared Web Application state](./shared_state/README.md)
- [Detecting conflicts](./shared_state/conflicts.md)
- [Theory of Conflict-free Replicated Data Types (CRDTs)](./shared_state/crdts.md)
Expand All @@ -23,3 +25,4 @@
- [Packaging](./faq/packaging.md)
- [Compatibility](./faq/compat.md)
- [Storage](./faq/storage.md)

13 changes: 0 additions & 13 deletions src-docs/faq/compat.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@

# Compatibility

## Other APIs and Tags Usage Hints

Webxdc apps run in a restricted environment, but the following practices are permitted:

- `localStorage`, `sessionStorage`, `indexedDB`
- `visibilitychange` events
- `window.navigator.language`
- internal links, such as `<a href="localfile.html">`
- `mailto` links, such as `<a href="mailto:[email protected]?body=...">`
- `<meta name="viewport" ...>` is useful especially as webviews from different platforms have different defaults
- `<input type="file">` allows importing of files for further
processing; see [`sendToChat()`](../spec/sendToChat.md) for a way to export files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is moved to spec/messenger.md because it's a requirement not some hint.

### Discouraged Practises

- `document.cookie` is known not to work on desktop and iOS—use `localStorage` instead
Expand Down
31 changes: 31 additions & 0 deletions src-docs/spec/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Changelog

## [1.2] - 2024-12-15

### New APIs

- modify `webxdc.selfAddr` to return a per-app identifier
that can be used for the new "notify" list

- add new `update.notify` attribute to allow causing
a user-visible system notification to raise awareness
that something in an app changed

- add new `update.href` attribute so that clicking info messages
will provide a "deep link" into an app to ease navigation

- add new `webxdc.sendUpdateMaxInterval` and `webxdc.sendUpdateMaxSize`
rate limits which helps apps to adapt to transport characteristics/limitations


### Deprecations

- `webxdc.sendUpdate` does not take a "descr" argument anymore.


### Other changes

- shifted "supported" DOM/Javascript features from the FAQ
into the messenger spec section

- improved wording in several places
10 changes: 6 additions & 4 deletions src-docs/spec/format.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
## Webxdc Container File Format

- a Webxdc app is a **ZIP-file** with the extension `.xdc`

- the ZIP-file MUST use the default compression methods as of RFC 1950,
this is "Deflate" or "Store"

- the ZIP-file MUST contain at least the file `index.html`

- the ZIP-file MAY contain a `manifest.toml` and `icon.png` or
`icon.jpg` files
- if the webxdc app is started, `index.html` MUST be opened in a [restricted webview](./messenger.md#webview-constraints-for-running-apps) that only allows accessing
resources from the ZIP-file.


### The manifest.toml File

If the ZIP-file contains a `manifest.toml` in its root directory,
the following basic information MUST be read from it:
the following basic information MUST be read from it:

```toml
name = "My App Name"
Expand All @@ -27,7 +29,7 @@ source_code_url = "https://example.org/orga/repo"
Messenger implementors may make the url accessible via a "Help" menu in the webxdc window.


### Icon Files
### Icon Files

If the ZIP-root contains an `icon.png` or `icon.jpg`,
these files are used as the icon for the webxdc.
Expand Down
2 changes: 2 additions & 0 deletions src-docs/spec/joinRealtimeChannel.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Calling `setListener` a second time will replace the previous listener.
## `realtimeChannel.send(data)`

Send a `Uint8Array` data item to connected peers.
The size of the array must not exceed 128000 bytes.

There is no guarantee anyone is receiving sent data
because there might be no currently listening peers,
or network connections fail.
Expand Down
72 changes: 46 additions & 26 deletions src-docs/spec/messenger.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,69 @@ The same webxdc container file shared in two separate chat messages
will be regarded as two separate "webxdc apps"
and the two apps can not communicate with, or even know about, each other.

### Webview Constraints for Running Apps
### Webview Constraints

When starting a web view for a webxdc app to run, messenger implementors:
When starting a web view for a webxdc app to run, messenger implementors

- MUST run the [webxdc container file](./format.md) in a constrained,
network-isolated webview that
MUST deny all forms of internet access.
If you don't do this
unsuspecting users may leak data of their private interactions to outside third parties.
You do not need to offer "privacy" or "cookie" consent screens as
there is no way a webxdc app can implicitly transfer user data to the internet.
- MUST serve all resources from the [webxdc container file](./format.md)
to the webxdc application.

- on initial opening, MUST open root URL for the webview with `index.html` appended
- MUST implement the [Webxdc Javascript API](api.md)
and serve a `webxdc.js` file accordingly.

- MUST deny all forms of Internet access;
if you don't restrict internet access
unsuspecting users may run 3rd party apps
that leak data of private interactions to outside third parties.
See ["Bringing E2E privacy to the web"](https://delta.chat/en/2023-05-22-webxdc-security)
which contains a deep discussion of the unique privacy guarantees of webxdc.

- MUST support `localStorage`, `sessionStorage` and `indexedDB`

- MUST isolate all storage and state of one webxdc app from any other

- MUST support `visibilitychange` events

- MUST allow unrestricted use of DOM storage (local storage, indexed db and co),
but make sure it is scoped to each webxdc app so they can not delete or modify
the data of other webxdc content.
- MUST support `window.navigator.language`

- MUST inject `webxdc.js` and implement the
[Webxdc Javascript API](api.md) so that messages are relayed and shown in chats.
- MUST support `window.location.href` but you can not specify or assume anything
about the protocol scheme or domain part of the url.

- MUST make sure the standard JavaScript API works as described at
[Other APIs and Tags Usage Hints](../faq/compat.md#other-apis-and-tags-usage-hints).
- MUST support HTML links such as `<a href="localfile.html">`

- MUST support `mailto` links, such as `<a href="mailto:[email protected]?body=...">`

- MUST support `<meta name="viewport" ...>` is useful especially as webviews from different platforms have different defaults

- MUST support `<input type="file">` to allow importing of files;
see [`sendToChat()`](../spec/sendToChat.md) for a way to export files.

In ["Bringing E2E privacy to the web"](https://delta.chat/en/2023-05-22-webxdc-security)
Delta Chat developers discuss the unique privacy guarantees of webxdc,
and which mitigations messengers using Chromium webviews need to implement to satisfy them.

### UI Interactions in Chats

- Text from `update.info` SHOULD be shown in the chats
and tapping them should jump to their webxdc message
and tapping them SHOULD open the webxdc app directly.
If `update.href` was set then the webxdc app MUST
be started with the root URL for the webview with
the value of `update.href` appended.

- The most recent text from `update.document` and `update.summary` SHOULD be shown inside the webxdc message,
- The most recent text from `update.document`
and `update.summary` SHOULD be shown inside the webxdc message,
together with name and icon.
Only one line of text SHOULD be shown and truncation is fine
as webxdc devs SHOULD NOT be encouraged to send long texts here.
as webxdc application developers SHOULD NOT be encouraged to send long texts here.

- A "Start" button MUST be offered that runs the webxdc app.
Note that there is no need to ask for "privacy" or "cookie" consent because
there is no way a webxdc app can implicitly transfer user data to the internet.

- A "Start" button SHOULD run the webxdc app.

### Example Messenger Implementations

- [Android using Java](https://github.com/deltachat/deltachat-android/blob/master/src/org/thoughtcrime/securesms/WebxdcActivity.java)
- [Delta Chat Android using Java](https://github.com/deltachat/deltachat-android/blob/master/src/org/thoughtcrime/securesms/WebxdcActivity.java)

- [iOS using Swift](https://github.com/deltachat/deltachat-ios/blob/master/deltachat-ios/Controller/WebxdcViewController.swift)
- [Delta Chat iOS using Swift](https://github.com/deltachat/deltachat-ios/blob/master/deltachat-ios/Controller/WebxdcViewController.swift)

- [Desktop using TypeScript](https://github.com/deltachat/deltachat-desktop/blob/786b7514d69ffb723bbe6e706494852a2641bfcd/src/main/deltachat/webxdc.ts)
- [Delta Chat Desktop using TypeScript](https://github.com/deltachat/deltachat-desktop/blob/786b7514d69ffb723bbe6e706494852a2641bfcd/src/main/deltachat/webxdc.ts)

73 changes: 61 additions & 12 deletions src-docs/spec/selfAddr_and_selfName.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,76 @@
# selfAddr & selfName

## selfName

```js
window.webxdc.selfName
```

`selfName` is the nick or display name for the user
which the webxdc application may show in its user interface.


## selfAddr

```js
window.webxdc.selfAddr
```

A string with an unique ID identifying the user in the current webxdc.
Every user of an webxdc must get a different ID
and that ID must be the same if the webxdc is started again later for the same user.
The same user in different webxdc, however, may have different IDs.
`selfAddr` is a unique string within a webxdc application that

Especially useful if you want to differentiate between different peers -
just send the ID along with the payload,
and, if needed, compare the payload addresses against `selfAddr` later on.
- has no meaning outside the webxdc app,

## selfName
- can be used in other webxdc APIs,

- should not be shown in the user interface of the webxdc application,

- is identical across multiple invocations of the same webxdc application,

- is identical on multiple devices of the user using the same webxdc application.

- is not linkable to addresses in other webxdc apps:
even if a web app manipulates users to share addresses via copy+paste with another web app,
addresses between the two web apps can not be correlated.


## Example using selfAddr and selfName

Here is a simple chat app that sends out a reply using the display names
but uses the addresses for notifications.

```js
window.webxdc.selfName
```

Name of the current account, as defined in settings.
If empty, this defaults to the peer's address.
// Receive a message from anyone in the chat
let users = new Set();

setUpdateListener((update) => {
const prompt = `${update.payload.senderName} (${update.payload.senderAddr}):`;
users.add(update.payload.senderAddr);
console.log(`${prompt} ${update.message}`);
})

// start some user interface which calls the following function for
// message sending

sendMessage(text) => {
let payload = {
senderAddr: webxdc.selfAddr,
senderName: webxdc.selfName,
message: text
};

// notify all users who ever sent a message in the chat app
let notify = {};
for (const addr of users) {
notify[addr] = `new message from ${webxdc.selfName}`;
}

sendUpdate({
payload: payload,
notify: notify
})
})
```


[`sendUpdate()`]: ./sendUpdate.html
Loading