- PHP 75.5%
- TypeScript 21%
- Less 2.7%
- Shell 0.7%
- JavaScript 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .woodpecker | ||
| docs/screenshots | ||
| js | ||
| resources | ||
| scripts | ||
| src | ||
| tests | ||
| .gitattributes | ||
| .gitignore | ||
| .nvmrc | ||
| compose.yaml | ||
| composer.json | ||
| extend.php | ||
| LICENSE.md | ||
| phpstan.neon | ||
| README.md | ||
Forgejo OAuth for Flarum
A Flarum 2 extension that adds "Log in with Forgejo" to FoF OAuth. Any number of Forgejo instances can be configured, each as its own login provider.
Installation
composer require moderndesktop/oauth-forgejo
Setup
- In the admin panel, open Forgejo OAuth and add an instance: a display name, an identifier (e.g.
moderndesktop), and the instance URL (e.g.https://forge.moderndesktop.dev). The page shows the redirect URI for that instance:https://<your forum>/auth/forgejo-<identifier>. Save. - On the Forgejo instance, open Settings → Applications (
/user/settings/applications) and create an OAuth2 application. Use the redirect URI exactly as shown, and leave Confidential client checked. - Open the FoF OAuth settings page. The instance is listed there; enter its client ID and secret and enable it.
The identifier can't be changed after saving, because linked accounts are tied to it.
The Forgejo OAuth settings page, with an instance and its redirect URI and setup steps:
The instance on the FoF OAuth settings page, where its client ID and secret are entered:
Email trust
Forgejo only reports whether an email is verified in the OpenID Connect ID token (email_verified, set from whether the account is active). A login's email is trusted, and can sign in to or link an existing forum account with the same address, only when:
- the instance URL is
https, and - the ID token's
issequals the instance URL, itsaudcontains the client ID, and itssubmatches the user, and email_verifiedistrue.
Otherwise the email only pre-fills the sign-up form. An instance that doesn't require email confirmation marks every account active, so trust is only as strong as that instance's policy.
Known limitation
When "Update email address from provider" is on, the notice email names the provider by its internal name (forgejo-<identifier>) rather than its display name.
Development
Node is pinned in .nvmrc:
fnm use
cd js
yarn install
yarn build # webpack: js/src -> js/dist
yarn dev # rebuild on change
yarn check-typings # tsc; needs vendor/ from composer install
yarn format
PHP tooling runs in thecodingmachine/php:8.5-v5-cli-node26, the same image CI uses, so nothing PHP is installed on the host:
podman compose run --rm php composer install
podman compose run --rm php composer test:setup # once; SQLite by default
podman compose run --rm php composer test
podman compose run --rm php composer analyse:phpstan
CI and releases
Each Woodpecker workflow runs scripts/ci-check.sh (tests, PHPStan, Prettier, type check, JS build) and then does at most one extra thing:
| Workflow | Runs on | After the checks |
|---|---|---|
.woodpecker/check.yaml |
pull requests, manual runs | nothing |
.woodpecker/dist.yaml |
pushes to main |
commits js/dist to main if the build changed it |
.woodpecker/release.yaml |
a tag being pushed | fails if js/dist doesn't match the build |
Flarum loads the committed js/dist, so it has to be in git, but pull requests don't need to include it. dist.yaml is the only workflow that pushes, and the only one given the FORGE_TOKEN secret: a token with write access to the repository, for an account allowed to push to main. Its commit message contains [CI SKIP].
Releases are tagged by hand; nothing in CI creates tags. Wait for CI's js/dist commit to land on main, then tag that commit (e.g. v1.0.0). Packagist creates a version from each tag; the repository's Packagist webhook tells it to update on every push.
License
MIT

