Skip to content

Commit 542dcb3

Browse files
feat(device-agent): implement device registration and authentication flow (#2281)
- Added DeviceAgentAuthService to handle device authentication, including generating and exchanging authorization codes. - Implemented device registration logic with and without serial numbers, ensuring proper organization validation. - Created new DTOs for device registration, check-in, and authorization code exchange. - Updated DeviceAgentController to include endpoints for generating auth codes, registering devices, and checking in. - Introduced proxy functionality in the portal to forward device-agent requests to the NestJS API, enhancing security and session management. - Enhanced error handling and validation across new features, ensuring robust API interactions. Tests included for all new functionalities to ensure reliability and maintainability. Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
1 parent 8b74e54 commit 542dcb3

File tree

31 files changed

+1489
-716
lines changed

31 files changed

+1489
-716
lines changed

.github/workflows/device-agent-release.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
tag_name: ${{ steps.version.outputs.tag_name }}
1919
is_prerelease: ${{ steps.version.outputs.is_prerelease }}
2020
portal_url: ${{ steps.version.outputs.portal_url }}
21+
api_url: ${{ steps.version.outputs.api_url }}
2122
release_name: ${{ steps.version.outputs.release_name }}
2223
auto_update_url: ${{ steps.version.outputs.auto_update_url }}
2324
s3_env: ${{ steps.version.outputs.s3_env }}
@@ -50,12 +51,14 @@ jobs:
5051
TAG_NAME="device-agent-v${NEXT_VERSION}"
5152
IS_PRERELEASE="false"
5253
PORTAL_URL="https://portal.trycomp.ai"
54+
API_URL="https://api.trycomp.ai"
5355
RELEASE_NAME="Device Agent v${NEXT_VERSION}"
5456
S3_ENV="production"
5557
else
5658
TAG_NAME="device-agent-v${NEXT_VERSION}-staging.${GITHUB_RUN_NUMBER}"
5759
IS_PRERELEASE="true"
5860
PORTAL_URL="https://portal.staging.trycomp.ai"
61+
API_URL="https://api.staging.trycomp.ai"
5962
RELEASE_NAME="Device Agent v${NEXT_VERSION} (Staging #${GITHUB_RUN_NUMBER})"
6063
S3_ENV="staging"
6164
fi
@@ -67,6 +70,7 @@ jobs:
6770
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
6871
echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
6972
echo "portal_url=$PORTAL_URL" >> $GITHUB_OUTPUT
73+
echo "api_url=$API_URL" >> $GITHUB_OUTPUT
7074
echo "release_name=$RELEASE_NAME" >> $GITHUB_OUTPUT
7175
echo "auto_update_url=$AUTO_UPDATE_URL" >> $GITHUB_OUTPUT
7276
echo "s3_env=$S3_ENV" >> $GITHUB_OUTPUT
@@ -77,6 +81,7 @@ jobs:
7781
echo "Tag name: $TAG_NAME"
7882
echo "Pre-release: $IS_PRERELEASE"
7983
echo "Portal URL: $PORTAL_URL"
84+
echo "API URL: $API_URL"
8085
echo "Auto-update URL: $AUTO_UPDATE_URL"
8186
echo "S3 env: $S3_ENV"
8287
@@ -112,6 +117,7 @@ jobs:
112117
- name: Build
113118
env:
114119
PORTAL_URL: ${{ needs.detect-version.outputs.portal_url }}
120+
API_URL: ${{ needs.detect-version.outputs.api_url }}
115121
AGENT_VERSION: ${{ needs.detect-version.outputs.version }}
116122
run: bun run build
117123

@@ -170,6 +176,7 @@ jobs:
170176
- name: Build
171177
env:
172178
PORTAL_URL: ${{ needs.detect-version.outputs.portal_url }}
179+
API_URL: ${{ needs.detect-version.outputs.api_url }}
173180
AGENT_VERSION: ${{ needs.detect-version.outputs.version }}
174181
run: bun run build
175182

@@ -319,6 +326,7 @@ jobs:
319326
- name: Build
320327
env:
321328
PORTAL_URL: ${{ needs.detect-version.outputs.portal_url }}
329+
API_URL: ${{ needs.detect-version.outputs.api_url }}
322330
AGENT_VERSION: ${{ needs.detect-version.outputs.version }}
323331
run: bun run build
324332

CLAUDE.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@ packages/
3434

3535
## Authentication & Session
3636

37-
- **Session-based auth only.** No JWT tokens. All requests use `credentials: 'include'` to send httpOnly session cookies.
37+
- **Auth lives in `apps/api` (NestJS).** The API is the single source of truth for authentication via better-auth. All apps and packages that need to authenticate (app, portal, device-agent, etc.) MUST go through the API — never run a local better-auth instance or handle auth directly in a frontend app.
38+
- **Session-based auth only.** No JWT tokens. Cross-subdomain cookies (`.trycomp.ai`) allow sessions to work across all apps.
3839
- **HybridAuthGuard** supports 3 methods in order: API Key (`x-api-key`), Service Token (`x-service-token`), Session (cookies). `@Public()` skips auth.
39-
- **Client-side**: `apiClient` from `@/lib/api-client` (always sends cookies).
40-
- **Server-side**: `serverApi` from `@/lib/api-server.ts`.
40+
- **Client-side auth**: `authClient` (better-auth client) with `baseURL` pointing to the API, NOT the current app.
41+
- **Client-side data**: `apiClient` from `@/lib/api-client` (always sends cookies).
42+
- **Server-side data**: `serverApi` from `@/lib/api-server.ts`.
43+
- **Server-side session checks**: Proxy to the API's `/api/auth/get-session` endpoint — do NOT instantiate better-auth locally.
4144
- **Raw `fetch()` to API**: MUST include `credentials: 'include'`, otherwise 401.
4245

4346
## API Architecture

apps/api/src/auth/auth.server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { db } from '@trycompai/db';
55
import { betterAuth } from 'better-auth';
66
import { prismaAdapter } from 'better-auth/adapters/prisma';
77
import {
8+
bearer,
89
emailOTP,
910
magicLink,
1011
multiSession,
@@ -302,6 +303,7 @@ export const auth = betterAuth({
302303
},
303304
}),
304305
multiSession(),
306+
bearer(),
305307
],
306308
socialProviders,
307309
user: {

0 commit comments

Comments
 (0)