Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions work/notifications/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
# Notifications Work Area
# Notifications work area

This directory holds the public research notes for the `/notifications`
endpoint in relation to issue `#350`.
Research for `/notifications` and issue `#350`.

The protocol source of truth lives in:
Normative spec: `IETF-RFC.md`, `spec.yaml`. This directory is implementation notes and cross-stack notes under `research/`.

- `IETF-RFC.md`
- `spec.yaml`

This place keeps only the research layer:

- `research/` for implementation notes and cross-platform
observations

Current documents:
Contents:

- `research/README.md`
- `research/matrix-notification-types.md` (types + pinned code links)
- `research/examples/` (wire JSON in fenced blocks, `metadata.md`, `discrepancies.md`)
28 changes: 13 additions & 15 deletions work/notifications/research/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
# Notifications Research
# Notifications research

This directory keeps the public research notes for `/notifications`.
Research notes for `/notifications`.

Current files:
- `matrix-notification-types.md` - types and where they live in code (pinned links)
- `examples/README.md` - layout of the example files
- `examples/metadata.md` - pinned commits (reva, Nextcloud, OCM-API spec cross-check)
- `examples/nextcloud-files.md`, `examples/nextcloud-talk.md`, `examples/nextcloud-calendar.md` - wire JSON + context
- `examples/reva-ocm-notifications.md` - reva `notify` bodies
- `examples/discrepancies.md` - spec vs code, and where stacks disagree
- `nextcloud-server.md`, `nextcloud-talk.md`, `ocis-reva.md`, `cernbox-reva.md`, `opencloud-reva.md` - per-platform notes

- `nextcloud-server.md`
File-oriented notes from the Nextcloud server inspection
- `nextcloud-talk.md`
Notes on `talk-room` and resource-event use of `/notifications`
- `ocis-reva.md`
Notes on the main non-Nextcloud contrast in this inspection
- `cernbox-reva.md`
Notes on route presence versus notification behavior
- `opencloud-reva.md`
Short notes on the current openCloud / reva notification path
Notes for ocis and owncloud/reva are in `ocis-reva.md`. Example JSON under
`examples/` uses cs3org/reva permalinks; `examples/metadata.md` explains how
that relates to owncloud/reva.

The platform files also keep a small list of the notification types
seen in code and the main send and receive paths for each stack.
Platform files list notification types and send/receive paths from code review.
22 changes: 22 additions & 0 deletions work/notifications/research/examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# OCM notification examples (wire JSON)

Each example is the HTTP JSON body for `/notifications`-style traffic: one object with `notificationType`, `resourceType`, `providerId`, and nested `notification`. Shapes come from the code paths named in each file; secrets are redacted.

Provenance sits in the markdown (repo, file, method, which side sends). The fenced `json` blocks are the wire payload; metadata keys like `label` or `emission` never belong inside them.

Commits and GitHub permalinks live in `metadata.md` (reva, Nextcloud, OCM-API spec cross-check). Links use `blob/<commit>/path` so they do not break when `main` moves.

Source first; tests where they exist (reva httptest) or the manual steps in `work/notifications/research/` otherwise. Placeholders are angle brackets or `REDACTED`.

Files, Talk, Calendar, and reva `notify` at the pinned commit. More stacks can use the same layout.

| File | What |
| ---- | ---- |
| `metadata.md` | Commits (reva, Nextcloud, OCM-API for spec links) |
| `nextcloud-files.md` | `resourceType` `file` |
| `nextcloud-talk.md` | `resourceType` `talk-room` |
| `nextcloud-calendar.md` | `resourceType` `calendar` |
| `reva-ocm-notifications.md` | reva `notify` output |
| `discrepancies.md` | Spec vs code; where stacks disagree |

PR: rebase onto the target branch, run a secret scan on touched markdown, note any OpenAPI field-name mismatch beside the example.
40 changes: 40 additions & 0 deletions work/notifications/research/examples/discrepancies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Where spec text, code, and stacks disagree

Permalinks are listed in [`metadata.md`](metadata.md) (OCM-API, reva, Nextcloud).

I keep two things separate on purpose. [`ocis-reva.md`](../ocis-reva.md) describes owncloud/ocis and owncloud/reva at the commits I inspected: how the OCM service is wired, what the `/ocm/notifications` handler expects, and what still looked rough. The JSON examples in this folder use [cs3org/reva](https://github.com/cs3org/reva) permalinks because that is the tree the links in this repo point at. The same commit hash often appears on owncloud/reva when both forks carry the same revision. The split between these files is by topic (product wiring versus example JSON), not a claim about which fork is authoritative.

## When servers do not match each other

This section is informal notes from comparing implementations. It is not a complete interoperability matrix.

- Reva `notify` emits `SHARE_CHANGE_PERMISSION`. Nextcloud Files uses `RESHARE_CHANGE_PERMISSION` on the file path ([`matrix-notification-types.md`](../matrix-notification-types.md) section 1). The OpenAPI [`notificationType` MAY list](https://github.com/cs3org/OCM-API/blob/2de5068e0b4755794b54670655d625bbd78615fc/spec.yaml#L768-L777) lists `RESHARE_CHANGE_PERMISSION`. Interoperation requires a mapping if peers compare `notificationType` as a plain string.
- Nextcloud Files uses `sharedSecret` heavily in outbound file traffic (matrix section 1). The oCIS / reva receive path in [`ocis-reva.md`](../ocis-reva.md) expects `grantee` and, for permission changes, `notification.protocol`. The remote has to send what the receiver implements, which is not always the same as the draft text.
- Nextcloud Files sends and receives many `notificationType` values. The reva `notify` switch I pinned only implements `SHARE_UNSHARED` and `SHARE_CHANGE_PERMISSION` ([`reva-ocm-notifications.md`](reva-ocm-notifications.md), matrix section 3). A type string that exists only on the Nextcloud side can fail on reva.
- On the Nextcloud Files receive path, `RESHARE_CHANGE_PERMISSION` calls `updateResharePermissions`, which throws (`HintException`, updating reshares not allowed) in the tree I read. Other layers may still report success. See matrix section 1.1 and [`nextcloud-server.md`](../nextcloud-server.md).
- [CERN / cs3org reva](../cernbox-reva.md) and [openCloud / reva](../opencloud-reva.md) were different in my pass: the route existed, but typed handling was minimal or absent. Check those files before assuming parity with Nextcloud or a full ocmd receiver.

The per-codebase map lives in [`matrix-notification-types.md`](../matrix-notification-types.md) and the platform files under `research/`.

## Reva `protocol` on notifications

Share Creation defines `protocol` as one JSON **object**, not an array:

- [`spec.yaml` `protocol`](https://github.com/cs3org/OCM-API/blob/2de5068e0b4755794b54670655d625bbd78615fc/spec.yaml#L555-L572)
- [`IETF-RFC.md` Share Creation](https://github.com/cs3org/OCM-API/blob/2de5068e0b4755794b54670655d625bbd78615fc/IETF-RFC.md#L873-L897)

For permission-change notifications:

- [`NewNotification`](https://github.com/cs3org/OCM-API/blob/2de5068e0b4755794b54670655d625bbd78615fc/spec.yaml#L761-L801) does not document `notification.protocol`.
- [`IETF-RFC.md` Share Updating](https://github.com/cs3org/OCM-API/blob/2de5068e0b4755794b54670655d625bbd78615fc/IETF-RFC.md#L1293-L1301): `RESHARE_CHANGE_PERMISSION` payload and side effects are out of scope.
- [`notificationType` MAY list](https://github.com/cs3org/OCM-API/blob/2de5068e0b4755794b54670655d625bbd78615fc/spec.yaml#L768-L777): `RESHARE_CHANGE_PERMISSION`; reva sends `SHARE_CHANGE_PERMISSION`.

Reva fills `notification.protocol` with the same object encoding as Share Creation via [`protocols.go`](https://github.com/cs3org/reva/blob/823c2f1c2593ad310f49da2f68e35b757fb49e15/internal/http/services/ocmd/protocols.go) (reva pin in `metadata.md`).

## Nextcloud envelope

Nextcloud keeps the top-level fields stable (`notificationType`, `resourceType`, `providerId`, nested `notification`). Files and Talk diverge inside `notification`. The builder is [`CloudFederationNotification.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/lib/private/Federation/CloudFederationNotification.php) `setMessage`.

## Talk `MESSAGE_POSTED`

`messageData` / `unreadInfo` track the federated chat sync story; keys move with Spreed. I used [`BackendNotifier.php`](https://github.com/nextcloud/spreed/blob/76fd45d40827f76619942c9cd0a3323188dc6e42/lib/Federation/BackendNotifier.php) `sendMessageUpdate` at the Spreed pin.
73 changes: 73 additions & 0 deletions work/notifications/research/examples/metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Commits I pinned for these examples

Label: `ocm-notifications-implementation-examples`

Commits for the server, Spreed, and reva trees these notes came from. Use them when you diff the PHP or Go against the markdown and JSON in this folder.

---

## Nextcloud server (Files + Calendar)

| | |
| --- | --- |
| Repo | [nextcloud/server](https://github.com/nextcloud/server) |
| Branch | `master` |
| Commit | `f5faddaf31ebabd6f722e7b29f35d1f28c947259` |
| Version string (from `version.php` at the time) | `34.0.0 dev` |

---

## Nextcloud Spreed (Talk)

| | |
| --- | --- |
| Repo | [nextcloud/spreed](https://github.com/nextcloud/spreed) |
| Branch | `main` |
| Commit | `76fd45d40827f76619942c9cd0a3323188dc6e42` |

---

## Reva (notify samples)

The examples in this folder use [cs3org/reva](https://github.com/cs3org/reva)
for `blob/` links. [`ocis-reva.md`](../ocis-reva.md) is written against
[owncloud/reva](https://github.com/owncloud/reva) when the tree matched that
commit. The hash is the same in both places; only the GitHub org in the URL
changes. Line numbers can still drift between forks, so verify before you rely
on a permalink.

The hash below exists on cs3org/reva; other forks may not match line-for-line.

| | |
| --- | --- |
| Commit | `823c2f1c2593ad310f49da2f68e35b757fb49e15` |
| Branch | `main` |
| Open on GitHub | [cs3org/reva @ that commit](https://github.com/cs3org/reva/commit/823c2f1c2593ad310f49da2f68e35b757fb49e15) |

---

## OCM-API (OpenAPI and IETF draft text)

Cross-checks in `discrepancies.md` and `reva-ocm-notifications.md` use this tree.

| | |
| --- | --- |
| Repo | [cs3org/OCM-API](https://github.com/cs3org/OCM-API) |
| Commit | `2de5068e0b4755794b54670655d625bbd78615fc` |
| Open on GitHub | [commit](https://github.com/cs3org/OCM-API/commit/2de5068e0b4755794b54670655d625bbd78615fc) |

---

## Reva paths I keep pointing at

Same commit as in the previous section. Permalinks all start from `https://github.com/cs3org/reva/blob/823c2f1c2593ad310f49da2f68e35b757fb49e15/`.

| What | Path |
| ---- | ---- |
| Notify client tests | [`pkg/ocm/client/notify_payload_test.go`](https://github.com/cs3org/reva/blob/823c2f1c2593ad310f49da2f68e35b757fb49e15/pkg/ocm/client/notify_payload_test.go) |
| `notify` in the gRPC service | [`internal/grpc/services/ocmshareprovider/ocmshareprovider.go`](https://github.com/cs3org/reva/blob/823c2f1c2593ad310f49da2f68e35b757fb49e15/internal/grpc/services/ocmshareprovider/ocmshareprovider.go) (`notify`) |
| Protocol JSON shape | [`internal/http/services/ocmd/protocols.go`](https://github.com/cs3org/reva/blob/823c2f1c2593ad310f49da2f68e35b757fb49e15/internal/http/services/ocmd/protocols.go) |

---

When you change a pin, update the permalinks in the same change. If you move the OCM-API pin, refresh every `blob/2de5068...` link under `work/notifications/research/examples/`.
22 changes: 22 additions & 0 deletions work/notifications/research/examples/nextcloud-calendar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Nextcloud Calendar: wire JSON for notifications

Use the Nextcloud server commit from `metadata.md`. This file only documents one notification type.

---

## SYNC_CALENDAR

The notifier is [`CalendarFederationNotifier.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/dav/lib/CalDAV/Federation/CalendarFederationNotifier.php) and the traffic is outbound. `providerId` is the fixed string `calendar` because that is what [`CalendarFederationProvider.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/dav/lib/CalDAV/Federation/CalendarFederationProvider.php) exposes as `PROVIDER_ID`.

```json
{
"notificationType": "SYNC_CALENDAR",
"resourceType": "calendar",
"providerId": "calendar",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"shareWith": "<CLOUD_ID_STRING>",
"calendarUrl": "https://<HOST>/remote.php/dav/remote-calendars/<...>"
}
}
```
134 changes: 134 additions & 0 deletions work/notifications/research/examples/nextcloud-files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Nextcloud Files: wire JSON for notifications

The server commit and permalink base are in `metadata.md` under Nextcloud server. Above each fenced block I point to the PHP file; inside the fence is the POST body (`Content-Type: application/json`) and nothing else.

Placeholders are angle brackets, not real credentials.

---

## REQUEST_RESHARE

Same server commit as in `metadata.md`. Built in [`Notifications.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/federatedfilesharing/lib/Notifications.php), sent outbound to the remote peer.

```json
{
"notificationType": "REQUEST_RESHARE",
"resourceType": "file",
"providerId": "<REMOTE_SHARE_ID>",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"shareWith": "<USER>@<REMOTE_HOST>",
"senderId": "<LOCAL_SENDER_ID>",
"shareType": "user",
"message": "Ask owner to reshare the file"
}
}
```

---

## SHARE_UNSHARED (owner to recipient)

Again [`Notifications.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/federatedfilesharing/lib/Notifications.php), outbound.

```json
{
"notificationType": "SHARE_UNSHARED",
"resourceType": "file",
"providerId": "<REMOTE_SHARE_ID>",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"message": "file is no longer shared with you"
}
}
```

---

## RESHARE_UNDO

Same [`Notifications.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/federatedfilesharing/lib/Notifications.php), still outbound.

```json
{
"notificationType": "RESHARE_UNDO",
"resourceType": "file",
"providerId": "<REMOTE_SHARE_ID>",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"message": "reshare was revoked"
}
}
```

---

## SHARE_ACCEPTED (re-share chain toward owner)

[`CloudFederationProviderFiles.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php) emits this only in the re-share chain situations (owner vs sharedBy and the rest; read the file for the exact gate), and it is sent outbound like the other file notifications.

```json
{
"notificationType": "SHARE_ACCEPTED",
"resourceType": "file",
"providerId": "<REMOTE_ID_FOR_OWNER>",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"message": "Recipient accepted the re-share"
}
}
```

---

## SHARE_DECLINED (re-share chain toward owner)

Same file and gating as the previous entry. [`CloudFederationProviderFiles.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php).

```json
{
"notificationType": "SHARE_DECLINED",
"resourceType": "file",
"providerId": "<REMOTE_ID_FOR_OWNER>",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"message": "Recipient declined the re-share"
}
}
```

---

## SHARE_ACCEPTED (incoming external share)

This one is built in [`External/Manager.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/files_sharing/lib/External/Manager.php) and sent outbound.

```json
{
"notificationType": "SHARE_ACCEPTED",
"resourceType": "file",
"providerId": "<REMOTE_ID_FROM_SENDER>",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"message": "Recipient accept the share"
}
}
```

---

## SHARE_DECLINED (incoming external share)

Same [`Manager.php`](https://github.com/nextcloud/server/blob/f5faddaf31ebabd6f722e7b29f35d1f28c947259/apps/files_sharing/lib/External/Manager.php) as the previous section, also outbound.

```json
{
"notificationType": "SHARE_DECLINED",
"resourceType": "file",
"providerId": "<REMOTE_ID_FROM_SENDER>",
"notification": {
"sharedSecret": "<PLACEHOLDER_TOKEN>",
"message": "Recipient declined the share"
}
}
```
Loading
Loading