fix(api): relay Mojang logins when no auth source is configured

felis api wired the hasJoined multiplexer only when felis.toml had at
least one [[auth_source]]. With none, the source list stayed nil and
every hasJoined answer was a 204. That was harmless while nothing
pointed at the route, but the installer now starts Velocity with
-Dmojang.sessionserver aimed at felis-api unconditionally, and the
generated felis.toml tells the operator to delete the LittleSkin block
for a Mojang-only server. Doing exactly that turned every login away,
premium accounts included, and felis-api logged nothing about it.

Always build the list through authSourcesFromConfig, which prepends
Mojang in code, so an empty config is a Mojang-only relay. felis nano
already behaves this way with the same file.

The new test pins authSourcesFromConfig itself: Mojang first, the only
Identity source, and still present when nothing is configured. Marking
a configured source Identity makes it fail. The call site in cmdAPI is
now a single unconditional assignment and has no unit test of its own.
This commit is contained in:
flyemoji committed 2026-09-22 12:46:00 +09:00
1 parent 800a9042a1
commit 8fe255e38f
3 files changed
+50 -12

No files matched your search

+8 -9
View File
@@ -286,15 +286,14 @@ func cmdAPI(args []string, stdout, stderr io.Writer) int {
}
fmt.Fprintln(stderr, "felis api: external face fails closed (Access JWKS key function not configured)")
// Felis-nano: wire the multi-source hasJoined multiplexer only when third-party auth
// sources are configured. Mojang leads as the code-owned identity anchor (正版优先);
// config can only append namespace-rewritten third-party sources, never a trusted one,
// so a misconfig cannot reopen the impersonation hole. No sources = a.AuthSources stays
// nil = the endpoint 204s every login (ships off).
if len(cfg.AuthSources) > 0 {
a.AuthSources = authSourcesFromConfig(cfg.AuthSources)
fmt.Fprintf(stderr, "felis api: hasJoined multiplexer active — Mojang + %d third-party source(s)\n", len(cfg.AuthSources))
}
// Felis-nano: the multi-source hasJoined multiplexer. Mojang leads as the code-owned
// identity anchor (正版优先); config can only append namespace-rewritten third-party
// sources, never a trusted one, so a misconfig cannot reopen the impersonation hole.
// Wired unconditionally: the installer points Velocity at this route whether or not any
// [[auth_source]] is configured, so an empty list has to mean a Mojang-only relay, the
// same as under `felis nano`. A nil list would 204 every login, premium ones included.
a.AuthSources = authSourcesFromConfig(cfg.AuthSources)
fmt.Fprintf(stderr, "felis api: hasJoined multiplexer active — Mojang + %d third-party source(s)\n", len(cfg.AuthSources))
// Passkey (WebAuthn) verifier (spec §14, Phase 6). One relying party spans BOTH
// web faces: the RP id is the panel hostname (console.<root>), and because that is