Skip to content

Public API v1 with OAuth 2.0 and developer documentation at /docs - #408

Open
hugodemenez wants to merge 12 commits into
betafrom
cursor/deltalytix-public-api-docs-b54c
Open

Public API v1 with OAuth 2.0 and developer documentation at /docs#408
hugodemenez wants to merge 12 commits into
betafrom
cursor/deltalytix-public-api-docs-b54c

Conversation

@hugodemenez

@hugodemenez hugodemenez commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

Public OAuth + /api/v1 API, plus single-page API docs at /docs with left-section navigation, OpenAPI reference, examples, and an authenticated try-it playground.

Docs UX (this iteration)

  • One page: /[locale]/docs scrolls through Try it → guides (MDX) → OpenAPI
  • Left sticky nav with scroll-spy; mobile jump select
  • Legacy /docs/[slug] permanently redirects to /docs#slug (hash preserved via Next redirect/meta refresh)
  • Try it: logged-in users can generate a short-lived “Docs playground” PAT (read scopes by default); anonymous users can paste a PAT from Developers
  • OpenAPI: collapsible path/method reference fed from /openapi.json

API (prior commits on this PR)

  • OAuth 2.0 authorize / token / revoke + PATs
  • /api/v1 for me, trades, accounts, connections, imports, metrics
  • Developers dashboard for apps + PATs
  • Machine-readable /openapi.json

Verification

  • bun run typecheck
  • OPENAI_API_KEY=dummy bun run build
  • Browser: generate docs token → GET /api/v1/me200 as local-dashboard-user
  • Curl: Docs playground PAT → /api/v1/me200

Docs left nav
Playground GET /me success
OpenAPI reference

Open in Web Open in Cursor 

@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
deltalytix Ignored Ignored Preview Aug 24, 2026 11:33am

cursoragent and others added 12 commits August 24, 2026 12:32
- OAuth authorization code flow with PKCE, refresh tokens, and revocation
- Personal access tokens and OAuth app management UI at /dashboard/developers
- /api/v1: me, trades (list/create with dedupe), accounts (+metrics),
  connections (IBKR Flex connect + sync), file imports (AI parsing and
  platform parsers), and metrics (summary/equity/accounts)
- Tokens stored as SHA-256 hashes; scope enforcement per endpoint
- First-party OAuth discovery metadata and full OpenAPI 3.1 document

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
- Bilingual (EN/FR) MDX docs: overview, authentication, trades, accounts,
  connections, imports, metrics, and errors
- Landing-style docs index and article pages with TOC and prev/next nav
- Navbar Developers menu, footer, and sitemap now link to the docs
- Proxy: treat /docs as public and only redirect the exact /authentication
  path for signed-in users

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
- /oauth/authorize: exclude /oauth/ from i18n locale routing so the consent
  page resolves (it lives outside the [locale] tree)
- /api/v1/metrics/equity: pre-filter trades by from/to since
  computeEquityChartData only applies its date filter in per-account mode
- globals.css: consume shiki dual-theme variables so MDX code blocks are
  actually syntax highlighted in light and dark mode

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Replace the multi-page docs index and slug primary UX with one
scrollable /docs page, sticky left anchors, legacy slug redirects,
and stubs for the playground/OpenAPI slots.

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Provide DocsOpenApiReference and DocsApiPlayground with server actions
to generate/revoke a Docs playground PAT for logged-in visitors.

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Next.js forbids non-async exports from "use server" modules; keep token
name/scope constants module-private.

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Remove leftover sibling-agent placeholder comments now that the
playground and OpenAPI reference are integrated.

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Without "use cache", Cache Components treated /docs as an uncached
prerender and failed on unstable Date.now() in the landing tree.
Restore CachedDocsPage (same pattern as updates); playground and
OpenAPI stay client-side and still call APIs at runtime.

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Wire scrollable table components into compileMDX so wide docs tables
no longer overflow the page on mobile. Headers stay sticky inside the
table scrollport; tighten OpenAPI detail padding on small screens.

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Generate token already uses a server action; preview crashed (digest
802521699) because public.OAuthAccessToken was missing on the shared DB.
Add the oauth tables migration and return a friendly error instead of
throwing so the docs page no longer full-page fails.

Co-authored-by: Hugo Demenez <hugodemenez@users.noreply.github.com>
Refactor the docs try-it UX into shared playground token helpers,
inline narrative route try blocks, OpenAPI schema utilities, and
code copy controls. Extend /api/v1 connections create/sync beyond
IBKR Flex to Tradovate, DxFeed, and Rithmic Protocol via a shared
connection-services module, and update OpenAPI plus EN/FR docs.
Move token controls into a shared drawer/sheet, put a capability TOC at the top, and add a demo token plus the remaining EN/FR docs and nav wiring.
@hugodemenez
hugodemenez force-pushed the cursor/deltalytix-public-api-docs-b54c branch from 39a3f47 to 4118b0d Compare August 24, 2026 11:33
@hugodemenez
hugodemenez marked this pull request as ready for review August 24, 2026 11:57

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 5 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 4118b0d. Configure here.

codeChallengeMethod: codeChallengeMethod ?? null,
expiresAt: authorizationCodeExpiresAt(),
},
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OAuth approve skips scope allowlist

High Severity

loadAuthorizeContext rejects scopes outside the app’s registered scopes, but approveAuthorizationAction only runs isValidScope on the form scope field and never intersects with app.scopes. Hidden-form tampering can mint an authorization code (and thus tokens) with scopes the app was never allowed to request.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4118b0d. Configure here.

url.searchParams.set("error", "access_denied")
if (state) url.searchParams.set("state", state)
redirect(url.toString())
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deny flow allows open redirect

High Severity

denyAuthorizationAction redirects to the submitted redirect_uri without checking client_id or registered redirectUris. The deny form only posts redirect_uri and state, so any URL can receive the access_denied redirect and be used for phishing.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4118b0d. Configure here.

if (!userId) {
return { error: DxFeedErrorCode.USER_NOT_AUTHENTICATED }
}
const resolvedUserId = userId

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server actions accept arbitrary userId

High Severity

Broker sync server actions now take optional options.userId and, when set, skip session auth and write connections/tokens for that id. These modules are 'use server' exports, so a browser client can pass another user’s id and create or overwrite their broker connections.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4118b0d. Configure here.

codeHash: sha256(code),
appId: app.id,
userId,
scopes,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OAuth tokens use auth id not User.id

High Severity

approveAuthorizationAction and developers PAT/app creation store getUserId() (Supabase auth id) on OAuthAuthorizationCode / OAuthAccessToken / OAuthApp, whose userId FK references User.id. Docs playground correctly resolves the Prisma user via auth_user_id. For legacy users where those ids differ, OAuth/PAT creation fails the FK or API queries miss trades/accounts keyed by User.id.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4118b0d. Configure here.

expiresAt: accessTokenExpiresAt(),
refreshTokenExpiresAt: refreshTokenExpiresAt(),
},
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auth code consume is not atomic

Medium Severity

The authorization-code grant checks consumedAt, then updates it in a separate step before creating tokens. Concurrent exchanges of the same code can both pass the check, or a failure after consume can leave the code burned with no tokens issued.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4118b0d. Configure here.

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.

2 participants