Skip to content

Add Sorare adapter + LOGIN_TOKEN auth profile - #199

Merged
keysersoft merged 1 commit into
mainfrom
keysersoft/sorare-connector-bcrypt
May 18, 2026
Merged

keysersoft merged 1 commit into
mainfrom
keysersoft/sorare-connector-bcrypt

Conversation

@keysersoft

Copy link
Copy Markdown
Contributor

Summary

  • Introduce LOGIN_TOKEN AuthType: declarative spec for APIs that POST credentials → receive long-lived bearer, with optional client-side bcrypt against a per-account salt fetched from the remote service (Sorare pattern). Adapter authors describe the entire flow in JSON; no per-provider code.
  • Ship the Sorare adapter (packages/backend/src/adapters/intl/sorare.json) with 7 GraphQL tools over cards, players, lineups, and the transfer market.
  • Add 12 multilingual MDX guides (en/de/it × {ChatGPT, Claude, OpenClaw, generic MCP}).

Architecture

LoginTokenService handles salt fetch → bcrypt → signIn → token cache (in-memory + encrypted connector_auth_cache DB row) → proactive refresh ≥24 h before expiry → forced re-login on 401, behind a per-key mutex.

REST and GraphQL engines gain a LOGIN_TOKEN case in injectAuth plus a 401-retry path that calls forceRelogin() and re-issues the request once.

Token persistence: new ConnectorAuthCache Prisma model + migration (20260518000000_add_login_token_auth), AES-256-GCM encrypted at rest with the existing ENCRYPTION_KEY.

AdapterMeta gains optional featured?: boolean and priority?: number so the marketing site can rank Sorare on the home page without a code change there.

Live validation

The same LoginTokenService code in this PR was run against the real Sorare API:

  • ✓ salt fetch + bcrypt + signIn returned a JWT with expiredAt exactly 30 days out (732 ms)
  • ✓ second getToken() hit the cache in 0 ms
  • ✓ GraphQL currentUser query with Authorization: Bearer + JWT-AUD returned the authenticated profile
  • ✓ forceRelogin() produced a fresh, different token

Test plan

  • npm test — 704 backend tests pass (15 new login-token specs, 10 new catalog assertions for the Sorare adapter and LOGIN_TOKEN validation)
  • npx tsc --noEmit clean
  • npx eslint clean on changed files
  • Backend + frontend production build compiles
  • After merge → deploy-cloud.yml rebuilds the image; cloud.anythingmcp.com/connectors should list Sorare Fantasy Football in the catalog
  • On cloud: install adapter, fill SORARE_EMAIL / SORARE_PASSWORD / SORARE_AUD, mint MCP key, call sorare_current_user from Claude / ChatGPT / OpenClaw → returns the user slug

Files

  • New: LoginTokenService + spec, Sorare adapter JSON + intl/ folder, login-token auth docs, 12 MDX guides, Prisma migration
  • Modified: schema.prisma (+LOGIN_TOKEN, +ConnectorAuthCache), REST + GraphQL engines, connectors module, catalog.ts (+featured/priority), catalog.spec.ts (+LOGIN_TOKEN validation, +GraphQL method enum), tool-definition.md, two existing live-spec constructors updated for the new LoginTokenService arg

@keysersoft
keysersoft requested a review from D3nisty as a code owner May 18, 2026 13:26
Introduce a declarative LOGIN_TOKEN AuthType for APIs that issue a
long-lived bearer in exchange for a credentials POST, optionally
requiring the password to be bcrypt-hashed with a salt fetched from
the remote service (Sorare pattern).

The new LoginTokenService handles salt fetch + bcrypt + login +
in-memory & DB token caching + per-key mutex + proactive refresh +
forced re-login on 401. REST and GraphQL engines gain a LOGIN_TOKEN
case in injectAuth and an auto-relogin retry on 401. Tokens are
persisted encrypted (AES-256-GCM) in a new connector_auth_cache
table; cache survives restarts.

The Sorare adapter (packages/backend/src/adapters/intl/sorare.json)
ships 7 GraphQL tools over cards, players, lineups, and the transfer
market. The included LOGIN_TOKEN authConfig drives the entire flow
declaratively — no Sorare-specific code anywhere.

Documentation: docs/connectors/login-token-auth.md is the field-by-
field reference; docs/tool-definition.md gains a LOGIN_TOKEN section.
Twelve multilingual MDX guides (en/de/it × {ChatGPT, Claude, OpenClaw,
generic MCP}) cover end-user setup for each AI client.

Validated end-to-end against the live Sorare API: salt fetch + bcrypt
+ signIn returns a 30-day JWT, currentUser query succeeds with the
issued Authorization + JWT-AUD headers, cache hit + forceRelogin both
behave as expected.

All 704 backend tests pass (incl. 15 new login-token specs and
10 new catalog assertions for the Sorare adapter and LOGIN_TOKEN
validation).
@keysersoft
keysersoft force-pushed the keysersoft/sorare-connector-bcrypt branch from 8136cf4 to 18b295c Compare May 18, 2026 13:36
@keysersoft
keysersoft enabled auto-merge (squash) May 18, 2026 13:36
@keysersoft
keysersoft merged commit 92d4c85 into main May 18, 2026
10 checks passed
@keysersoft
keysersoft deleted the keysersoft/sorare-connector-bcrypt branch May 18, 2026 13:38
keysersoft added a commit that referenced this pull request May 18, 2026
McpServerModule registers its own copy of RestEngine and GraphqlEngine
as providers. After the Sorare PR added LoginTokenService as a
constructor dependency of both engines, McpServerModule could no
longer resolve them, causing UnknownDependenciesException at startup
and an unhealthy app container.

Adding LoginTokenService to McpServerModule's providers (alongside
the existing OAuth2TokenService) fixes the startup crash.

This is the root cause of the cloud outage following PR #199.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant