This is a implementation of #4277. The core idea is that any activity (where activity is defined as anything that ends up in the `action` table) will be wrapped in an `ap.Note`, and sent to followers. Similarly, the inbox of local users now accepts such Notes. Additionally, there's now a "Feeds" tab on the user profile page, which displays the received notes. # Preview  # How to Try? The PR can be tried using a single Forgejo instance, but two distinct ones probably shows how it works better. For the sake of simplicity, lets try with a single instance. This is how to get started: 1. Enable federation 2. Subscribe one user to another (or to themselves): ``` curl -s -H "authorization: Bearer ${TOKEN}" -XPOST \ http://localhost:3000/api/v1/user/activitypub/follow \ --json '{"target": "http://localhost:3000/api/v1/activitypub/user-id/1"}' ``` This makes the first user follow themselves. 3. Create a repo, open an issue, or basically do anything that results in an activity recorded. 4. Visit `http://localhost:3000/{username}?tab=feed` to see the feed in action. If you want to try with multiple instances, then it's very similar: you just change the `actor_id` to the IRI of the user you want to follow the first instance's user with, and then you can look at the feed tab of this user on the second instance, after you performed some activity on the first. ## Trying with Mastodon / GoToSocial To try with Mastodon or GoToSocial, you will likely need to bring your Forgejo instance public, and behind https. Once your Forgejo instance is up, you can search for `@yourusername@forgejo.your.domain.example.com`, and simply follow your Forgejo account. Creating any activity will then happily federate to Mastodon & GoToSocial. You can also copy & paste the Forge user's web profile URL (eg, `https://forgejo.your.domain.example.com/yourusername`) into your fedi client of choice, and it will discover the profile that way too. # Testing * test: https://codeberg.org/meissa/federation/src/branch/federated-user-activity-following/doc/user-activity-following/manual-test.md * Proof of gts->forgejo: https://social.meissa-gmbh.de/@meissa/114499541149466596 * Proof of forgejo->gts: https://social.meissa-gmbh.de/@meissa/114505225265720094 ## Architecture decisions There are a number of ways user activity federation could be implemented. One way - which I explored first - is to wrap each activity, and send those, and let the client render it. The advantage of this would be that we'd be able to have references to other objects (comments, repos, etc). The disadvantage is that doing this requires making all of these things addressable, and that's a lot of work. Another disadvantage is that this requires every client to know how to display it. Another way, chosen here, is to send a rendered HTML `ap.Note` instead, with an `AttributedTo` (`ap.Person`) property, which describes the activity that happened in a HTML note. This is much simpler to implement, and has the huge advantage that it is also easier to display. In fact, once we have http signatures, we should be able to federate user activity to Mastodon, too! (Though this also requires figuring out how Mastodon wants to follow a user...) Since user activity federation is mostly cosmetic, as in, it's there for the user to see, rather than for programs to take actions based upon this activity, I believe that sending an `ap.Note` is preferable over a more machine-oriented approach. ## Limitations & TODO ### FederatedUser We should be caching the Avatar in a similar way. For that, though, we also need to store the last activity of a federated user, so we can expire old avatars from the cache. The avatar refresh part will be covered by #4778. ### Notes While sending out notes, the `AttributedTo` property is set to an `ap.Person`, based on the originating local user. This is currently unused. The idea is that once following is implemented properly (see above), we'll be able to link this to a FederatedUser (and thus to ExternalUser & User), which will allow us to display avatars and such, too. ### Display The template used for displaying the received activities is currently incredibly simplistic. That's probably ok, it doesn't need to be fantastic. ### TODO - [x] Fix the crashes on certain ops: - [x] Issue/PR close & reopen - [x] Figure out a better way to implement follows - [x] Store the `AttributedTo` part of the note, too, the ID of it. - [x] Make sure only those activities are sent out that need to be. Currently, pretty much any activity is sent out, even private ones. We should be a bit smarter about that. - [x] Make the ids used in the AP messages deterministic The IDs used in the AP messages are currently UUIDs, and we do not store them, so all the IRIs are "invalid": the objects they refer to don't exist outside of the AP message itself. We should be able to reconstruct the Note objects and Create activities from their IDs. - [x] Make it possible to follow Forgejo account from Mastodon and GtS - [x] Mastodon without `AUTHORIZED_FETCH` works - [x] GoToSocial can follow - [x] Mastodon with `AUTHORIZED_FETCH` can follow - ~~Create a cron job to refresh federated user avatars~~ - [x] Implement unfollowing - [x] Add a `<link rel="alternate" type="application/activity+json" href="...">` to profile pages This lets Mastodon & most other Fedi frontends discover the AP profile just by pasting a Forgejo user's web profile page into a search box, without having to know the corresponding AP actor URL - [x] Make it easier to make a local user follow a remote AP actor - ~~Rebase on top of #4778 by @realaravinth, once that is ready~~ - [x] Create an API endpoint to list the AP feed - [x] Create a DB migration for the new stuff - [x] Make swagger stuff happy - [x] Clean up the commit history - [x] ~~Tests~~ Opting for manual testing for now. Co-authored-by: Michael Jerger <michael.jerger@meissa-gmbh.de> Co-authored-by: famfo <famfo@famfo.xyz> Co-authored-by: jerger <jerger@noreply.codeberg.org> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4767 Reviewed-by: jerger <jerger@noreply.codeberg.org> Reviewed-by: elle <0xllx0@noreply.codeberg.org> |
||
|---|---|---|
| .devcontainer | ||
| .forgejo | ||
| .semgrep | ||
| assets | ||
| build | ||
| cmd | ||
| contrib | ||
| custom/conf | ||
| docker | ||
| models | ||
| modules | ||
| options | ||
| public | ||
| release-notes | ||
| release-notes-published | ||
| releases/images | ||
| routers | ||
| services | ||
| templates | ||
| tests | ||
| tools | ||
| web_src | ||
| .air.toml | ||
| .deadcode-out | ||
| .dockerignore | ||
| .editorconfig | ||
| .envrc.example | ||
| .gitattributes | ||
| .gitignore | ||
| .gitmodules | ||
| .gitpod.yml | ||
| .golangci.yml | ||
| .ignore | ||
| .mailmap | ||
| .markdownlint.yaml | ||
| .mockery.yml | ||
| .node-version | ||
| .npmrc | ||
| .release-notes-assistant.yaml | ||
| .spectral.yaml | ||
| .yamllint.yaml | ||
| BSDmakefile | ||
| CODEOWNERS | ||
| CONTRIBUTING.md | ||
| DCO | ||
| Dockerfile | ||
| Dockerfile.rootless | ||
| eslint.config.mjs | ||
| flake.lock | ||
| flake.nix | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| Makefile | ||
| manifest.scm | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| README.md | ||
| release-notes-assistant.sh | ||
| RELEASE-NOTES.md | ||
| shell.nix | ||
| stylelint.config.js | ||
| tailwind.config.js | ||
| tsconfig.json | ||
| vitest.config.ts | ||
| webpack.config.js | ||
Welcome to Forgejo
Hi there! Tired of big platforms playing monopoly? Providing Git hosting for your project, friends, company or community? Forgejo (/for'd͡ʒe.jo/ inspired by forĝejo – the Esperanto word for forge) has you covered with its intuitive interface, light and easy hosting and a lot of built-in functionality.
Forgejo was created in 2022 because we think that the project should be owned by an independent community. If you second that, then Forgejo is for you! Our promise: Independent Free/Libre Software forever!
What does Forgejo offer?
If you like any of the following, Forgejo is literally meant for you:
- Lightweight: Forgejo can easily be hosted on nearly every machine. Running on a Raspberry? Small cloud instance? No problem!
- Project management: Besides Git hosting, Forgejo offers issues, pull requests, wikis, kanban boards and much more to coordinate with your team.
- Publishing: Have something to share? Use releases to host your software for download, or use the package registry to publish it for docker, npm and many other package managers.
- Customizable: Want to change your look? Change some settings? There are many config switches to make Forgejo work exactly like you want.
- Powerful: Organizations & team permissions, CI integration, Code Search, LDAP, OAuth and much more. If you have advanced needs, Forgejo has you covered.
- Privacy: From update checker to default settings: Forgejo is built to be privacy first for you and your crew.
- Federation: (WIP) We are actively working to connect software forges with each other through ActivityPub, and create a collaborative network of personal instances.
Learn more
Dive into the documentation, subscribe to releases and blog post on our website, find us on the Fediverse or hop into our Matrix room if you have any questions or want to get involved.
License
Forgejo is distributed under the terms of the GPL version 3.0 or any later version.
The agreement for this license was documented in June 2023 and implemented during the development of Forgejo v9.0. All Forgejo versions before v9.0 are distributed under the MIT license.
Get involved
If you are interested in making Forgejo better, either by reporting a bug or by changing the governance, please take a look at the contribution guide.