Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
51c64f0
chore(connect): add auth and vitest dependencies
callumflack Feb 16, 2026
59fbb33
refactor(connect): unify legal/docs config and platform helper
callumflack Feb 16, 2026
8056e59
refactor(icons): remove svg re-export indirection
callumflack Feb 16, 2026
3d4ae15
refactor(ui): align field focus states and auth form controls
callumflack Feb 16, 2026
d383014
feat(auth): implement privy auth flow hook and tests
callumflack Feb 16, 2026
0d35b18
feat(auth-ui): add email, oauth, and code verification screens
callumflack Feb 16, 2026
1b344df
feat(connect): split auth and grants into dedicated routes
callumflack Feb 16, 2026
a4f08bc
chore(editor): add workspace organize-imports setting
callumflack Feb 16, 2026
a4dd116
feat(ui): add iris color tokens and component variants
callumflack Feb 16, 2026
2aaa683
feat(connect): add input-otp dependency and primitive component
callumflack Feb 16, 2026
884e79b
feat(auth-ui): upgrade loading and OTP verification experience
callumflack Feb 16, 2026
3ba72ab
feat(auth-ui): redirect successful auth flow to grants
callumflack Feb 16, 2026
3060169
feat(grants-ui): add launch-first grants integration stub
callumflack Feb 16, 2026
a2d0e89
docs(connect): document grants launch override configuration
callumflack Feb 16, 2026
bcfde13
style(connect): increase xlarge typography token size
callumflack Feb 16, 2026
612ef7f
fix(connect): unblock production build
callumflack Feb 16, 2026
c7c2052
chore(connect): sync workspace lockfile
callumflack Feb 16, 2026
6c6e16c
fix(auth-ui): disable auth form debug mode by default
callumflack Feb 16, 2026
db270d3
chore: switch husky to pnpm exec and remove package-lock.json
callumflack Feb 17, 2026
1b1bc8a
feat(auth-ui): support desktop handoff success flow
callumflack Feb 17, 2026
fbbacd0
docs(auth): document auth and grants flow modes
callumflack Feb 17, 2026
f7784f2
chore(dev): add skills sync script and pnpm-only guidance
callumflack Feb 17, 2026
43b3569
fix(auth-ui): hide back button for desktop handoff mode
callumflack Feb 17, 2026
bf3fe3d
fix(auth): harden logging and debug controls
callumflack Feb 17, 2026
d0acff0
fix(auth): clean up wallet listener and typed-data constants
callumflack Feb 17, 2026
9a24bf1
fix(grants-ui): hide back button on grants page
callumflack Feb 17, 2026
c648275
chore(auth-ui): clarify debug mode usage notes
callumflack Feb 17, 2026
e459667
docs(auth): clarify mode behavior and param preservation contract
callumflack Feb 17, 2026
ce63a5d
refactor(auth): replace window.__AUTH_CONFIG__ with NEXT_PUBLIC env vars
Kahtaf Feb 17, 2026
0f1e438
chore(pnpm-lock): update dependencies and improve lockfile structure
Kahtaf Feb 17, 2026
aa84b36
fix(ci): switch from npm to pnpm in CI workflow
Kahtaf Feb 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ jobs:
node-version: [20, 22]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run lint:eslint
- run: npm run format:check
- run: npm test
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm lint:eslint
- run: pnpm format:check
- run: pnpm test
2 changes: 1 addition & 1 deletion .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -1 +1 @@
npx commitlint --edit $1
pnpm exec commitlint --edit $1
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
npx lint-staged
pnpm exec lint-staged
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit"
}
}
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pnpm test:watch # vitest in watch mode
- **Error handling** via `ConnectError` with typed `ConnectErrorCode` constants
- **Test framework**: vitest with `vi.stubGlobal("fetch", mockFetch)` pattern for HTTP mocking
- **Commit messages**: conventional commits (`feat:`, `fix:`, `docs:`, `refactor:`)
- **Package manager**: pnpm only (`pnpm ...`); do not suggest `npm` commands in this repo

## Environment variables (for examples/nextjs-starter)

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ The [Data Portability Protocol](https://docs.vana.org/docs/data-portability-1) d
## Installation

```bash
npm install @opendatalabs/connect
pnpm add @opendatalabs/connect
```

## Package manager

This repo is pnpm-only for local development and examples. Use `pnpm` commands, not `npm`.

## Prerequisites

Register an app through dataConnect first. You will need to provide the URL where your app will be deployed, and then be given a private key after registration.
Expand Down
8 changes: 8 additions & 0 deletions connect/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ You can start editing the page by modifying `app/page.tsx`. The page auto-update

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Environment

Copy `.env.local.example` to `.env.local` for local overrides.

The grants page supports an optional launch override:

- `NEXT_PUBLIC_GRANTS_TEST_DEEPLINK_URL` - deterministic deep-link used for local launch smoke tests.

## Learn More

To learn more about Next.js, take a look at the following resources:
Expand Down
151 changes: 151 additions & 0 deletions connect/docs/260217-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Connect Web Flow Architecture (Auth + Grants)

This document defines the mental model and technical contract between:

- `/` auth experience (Vana Passport sign-in)
- `/grants` launch/download experience for Data Connect

It exists to answer: _what page should happen next after auth success_, based on **arrival context**.

This doc is architecture: flow semantics, routing contracts, and page responsibilities.

## Mental Model (User-facing)

There are two user journeys entering auth:

1. **Web-first journey**
User starts in web context and needs to continue into data permissions.
- Auth success should continue to `/grants` (or future permissions route).

2. **Desktop-handoff journey**
User arrived at auth from an installed Data Connect app handoff (OS-level app flow).
- Auth success should _not_ continue into grants page UX.
- Success message should instruct return to app.
- Auth should remain on success state (no redirect, no auto-close).

If we do not distinguish these journeys, users get the wrong success state.

## Arrival Context (Core Decision Input)

Arrival context is determined from auth page query params (and/or upstream generated redirect context).
This context decides the auth success action.

### Proposed Context Modes

- `mode=continue_to_grants` (default web behavior)
- `mode=return_to_app` (desktop-handoff behavior)

Equivalent naming is fine (`entry=web|desktop`, `origin=app|web`) as long as one explicit param maps to one explicit post-success policy.

## Routing Contract Between Auth and Grants

Today, auth forwards selected grant context params:

- `app`
- `appId`
- `appName`

Auth computes `grantsUrl` and uses it for:

- fallback success link ("Didn't work? Click here")
- delayed redirect on success

Any arrival-context param used for success branching should be:

- parsed in `/_auth` on first load
- preserved through OAuth round-trips
- explicitly consumed by success transition logic

## Query Param Preservation Contract (Critical)

This is the highest-risk integration gap right now.
Teams may assume auth->grants carries all params, but current behavior is selective.

### Current observed behavior

| Param | Read in auth (`/`) | Preserved through OAuth callback | Forwarded to `/grants` URL |
| ------------------------------- | ------------------------------ | ----------------------------------- | ---------------------------------------------- |
| `mode` | Yes | Yes | No (used only by auth success logic) |
| `app` | Yes | Yes | Yes |
| `appId` | Yes | Yes | Yes |
| `appName` | Yes | Yes | Yes |
| `deepLinkUrl` / `deep_link_url` | Read by `/grants` launch logic | Not guaranteed by auth pass-through | Not currently added by auth grants URL builder |
| `sessionId` | Read by `/grants` launch logic | Not guaranteed by auth pass-through | Not currently added by auth grants URL builder |
| `secret` | Read by `/grants` launch logic | Not guaranteed by auth pass-through | Not currently added by auth grants URL builder |
| `scopes` | Read by `/grants` launch logic | Not guaranteed by auth pass-through | Not currently added by auth grants URL builder |

### Decision needed (within next 24 hours)

Define one explicit contract and align all repos:

1. **Minimal contract (current-ish):** only `app/appId/appName` are guaranteed at `/grants`.
2. **Launch-complete contract:** auth guarantees pass-through for launch-critical params (`deepLinkUrl`, `sessionId`, `secret`, `scopes`) as well.

Without this decision, downstream integrations can silently break after OAuth redirects.

## Success Behavior Matrix

| Arrival context | Auth success copy | Auth success action |
| --------------- | ------------------------------------------------- | ----------------------------------------- |
| Web-first | "Redirecting you to your data permissions..." | Redirect to `/grants` after delay |
| Desktop-handoff | "Return to Data Connect. You may close this tab." | Stay on auth success screen (no redirect) |

## Current vs Target

Current:

- Auth success is context-aware:
- `mode=return_to_app` -> stay on auth success screen (no redirect).
- any other mode / missing mode -> redirect to `grantsUrl` after delay.
- `/grants` renders with no back button.

Target:

- Keep the above success behavior stable.
- Finalize and document full query param preservation contract across auth -> OAuth -> grants.

## Pages and Responsibilities (Supporting Detail)

### `/` (Auth page, backed by `_auth` module)

Purpose:

- Render the auth experience on the root route (`/`) using Privy (email, Google, Apple).
- Bootstrap embedded wallet + signing flow.
- Post auth payload to backend via `/auth-callback`.
- Decide what success means based on arrival context.

Current implementation notes:

- Route: auth page is the root page (`/`).
- Module location: auth UI components live in `src/app/_auth/components/`.
- Flow/control logic lives in `src/app/_auth/auth.ts`.
- Default behavior today: on success, redirect to `/grants` after delay.

### `/grants`

Purpose:

- Explain "you need Data Connect to proceed".
- Let user launch installed app via deep link.
- Offer fallback download link for app install.

Current implementation notes:

- UI is in `src/app/grants/page.tsx`.
- Launch URL precedence and deep-link behavior are documented in `src/app/grants/README.md`.
- This is currently a launch-oriented stub while relay-backed grants flow is evolving.

## Implementation Direction (Next Step)

1. Freeze mode contract (`continue_to_grants` vs `return_to_app`) and keep existing behavior.
2. Decide query param preservation contract (minimal vs launch-complete).
3. Implement pass-through rules consistently in auth redirect and grants URL builder.
4. Add contract tests for param preservation (auth init, OAuth callback, grants fallback link).
5. Share contract with external repo owners before cross-repo implementation.

## Non-goals (for now)

- Full grants consent UI and legal consent copy activation.
- Replacing grants launch stub with complete relay-backed permissions UI.
- Redesigning auth providers or wallet bootstrap internals.
10 changes: 9 additions & 1 deletion connect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "vitest run",
"test:watch": "vitest",
"test:auth": "vitest run src/app/_auth/auth.test.ts",
"lint": "biome check",
"format": "biome format --write"
},
"dependencies": {
"@base-ui/react": "^1.1.0",
"@privy-io/js-sdk-core": "^0.60.0",
"@radix-ui/react-slot": "^1.2.4",
"@tabler/icons-react": "^3.36.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"input-otp": "^1.4.2",
"lucide-react": "^0.562.0",
"motion": "^12.29.2",
"next": "16.1.6",
Expand All @@ -29,10 +34,13 @@
"devDependencies": {
"@biomejs/biome": "2.2.0",
"@tailwindcss/postcss": "^4",
"@testing-library/react": "^16.3.2",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"jsdom": "^28.1.0",
"tailwindcss": "^4",
"typescript": "^5"
"typescript": "^5",
"vitest": "^4.0.18"
}
}
Loading