Skip to content

Commit ae4cdd0

Browse files
committed
feat(backend): add device information schema for OAuth2 token requests
1 parent 5d89be8 commit ae4cdd0

File tree

5 files changed

+348
-5
lines changed

5 files changed

+348
-5
lines changed

services/backend/api-spec.json

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21919,6 +21919,53 @@
2191921919
"type": "string",
2192021920
"minLength": 1,
2192121921
"description": "PKCE code verifier"
21922+
},
21923+
"device_info": {
21924+
"type": "object",
21925+
"properties": {
21926+
"device_name": {
21927+
"type": "string",
21928+
"minLength": 1,
21929+
"maxLength": 100,
21930+
"description": "User-friendly device name (defaults to hostname)"
21931+
},
21932+
"hostname": {
21933+
"type": "string",
21934+
"description": "System hostname"
21935+
},
21936+
"hardware_id": {
21937+
"type": "string",
21938+
"minLength": 1,
21939+
"description": "Unique hardware fingerprint"
21940+
},
21941+
"os_type": {
21942+
"type": "string",
21943+
"description": "Operating system type (e.g., macOS, Windows, Linux)"
21944+
},
21945+
"os_version": {
21946+
"type": "string",
21947+
"description": "Operating system version"
21948+
},
21949+
"arch": {
21950+
"type": "string",
21951+
"description": "System architecture (e.g., arm64, x64)"
21952+
},
21953+
"node_version": {
21954+
"type": "string",
21955+
"description": "Node.js version for compatibility"
21956+
},
21957+
"user_agent": {
21958+
"type": "string",
21959+
"description": "User agent string from CLI"
21960+
}
21961+
},
21962+
"required": [
21963+
"device_name",
21964+
"hostname",
21965+
"hardware_id"
21966+
],
21967+
"additionalProperties": false,
21968+
"description": "Optional device information for automatic device registration during login"
2192221969
}
2192321970
},
2192421971
"required": [
@@ -21994,6 +22041,55 @@
2199422041
"scope": {
2199522042
"type": "string",
2199622043
"description": "Space-separated list of granted scopes"
22044+
},
22045+
"device": {
22046+
"type": "object",
22047+
"properties": {
22048+
"id": {
22049+
"type": "string",
22050+
"description": "Unique device identifier"
22051+
},
22052+
"device_name": {
22053+
"type": "string",
22054+
"description": "User-friendly device name"
22055+
},
22056+
"hostname": {
22057+
"type": "string",
22058+
"nullable": true,
22059+
"description": "System hostname"
22060+
},
22061+
"hardware_id": {
22062+
"type": "string",
22063+
"nullable": true,
22064+
"description": "Hardware fingerprint"
22065+
},
22066+
"os_type": {
22067+
"type": "string",
22068+
"nullable": true,
22069+
"description": "Operating system type"
22070+
},
22071+
"is_active": {
22072+
"type": "boolean",
22073+
"description": "Whether device is active"
22074+
},
22075+
"is_trusted": {
22076+
"type": "boolean",
22077+
"description": "Whether device is trusted"
22078+
},
22079+
"created_at": {
22080+
"type": "string",
22081+
"format": "date-time",
22082+
"description": "Device creation timestamp"
22083+
}
22084+
},
22085+
"required": [
22086+
"id",
22087+
"device_name",
22088+
"is_active",
22089+
"is_trusted",
22090+
"created_at"
22091+
],
22092+
"description": "Device information if device was registered during login"
2199722093
}
2199822094
},
2199922095
"required": [

services/backend/api-spec.yaml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15124,6 +15124,43 @@ paths:
1512415124
type: string
1512515125
minLength: 1
1512615126
description: PKCE code verifier
15127+
device_info:
15128+
type: object
15129+
properties:
15130+
device_name:
15131+
type: string
15132+
minLength: 1
15133+
maxLength: 100
15134+
description: User-friendly device name (defaults to hostname)
15135+
hostname:
15136+
type: string
15137+
description: System hostname
15138+
hardware_id:
15139+
type: string
15140+
minLength: 1
15141+
description: Unique hardware fingerprint
15142+
os_type:
15143+
type: string
15144+
description: Operating system type (e.g., macOS, Windows, Linux)
15145+
os_version:
15146+
type: string
15147+
description: Operating system version
15148+
arch:
15149+
type: string
15150+
description: System architecture (e.g., arm64, x64)
15151+
node_version:
15152+
type: string
15153+
description: Node.js version for compatibility
15154+
user_agent:
15155+
type: string
15156+
description: User agent string from CLI
15157+
required:
15158+
- device_name
15159+
- hostname
15160+
- hardware_id
15161+
additionalProperties: false
15162+
description: Optional device information for automatic device registration
15163+
during login
1512715164
required:
1512815165
- grant_type
1512915166
- code
@@ -15177,6 +15214,44 @@ paths:
1517715214
scope:
1517815215
type: string
1517915216
description: Space-separated list of granted scopes
15217+
device:
15218+
type: object
15219+
properties:
15220+
id:
15221+
type: string
15222+
description: Unique device identifier
15223+
device_name:
15224+
type: string
15225+
description: User-friendly device name
15226+
hostname:
15227+
type: string
15228+
nullable: true
15229+
description: System hostname
15230+
hardware_id:
15231+
type: string
15232+
nullable: true
15233+
description: Hardware fingerprint
15234+
os_type:
15235+
type: string
15236+
nullable: true
15237+
description: Operating system type
15238+
is_active:
15239+
type: boolean
15240+
description: Whether device is active
15241+
is_trusted:
15242+
type: boolean
15243+
description: Whether device is trusted
15244+
created_at:
15245+
type: string
15246+
format: date-time
15247+
description: Device creation timestamp
15248+
required:
15249+
- id
15250+
- device_name
15251+
- is_active
15252+
- is_trusted
15253+
- created_at
15254+
description: Device information if device was registered during login
1518015255
required:
1518115256
- access_token
1518215257
- token_type

services/backend/src/routes/mcp/servers/create-global.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
12
import { type FastifyInstance } from 'fastify';
23
import { z } from 'zod';
34
import { createSchema } from 'zod-openapi';
@@ -323,6 +324,7 @@ export default async function createGlobalServer(server: FastifyInstance) {
323324
request.log.debug('Detected incomplete installation_methods, falling back to claude_desktop_config extraction');
324325
// Fall back to extracting from claude_desktop_config if available
325326
if (requestData.claude_desktop_config) {
327+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
326328
const { installation_methods, environment_variables, args, transport_type: extractedTransportType } = extractMcpConfigData(requestData.claude_desktop_config);
327329
finalInstallationMethods = installation_methods;
328330
finalTransportType = requestData.transport_type || extractedTransportType;
@@ -460,7 +462,7 @@ export default async function createGlobalServer(server: FastifyInstance) {
460462
logger: request.log,
461463
user: {
462464
id: request.user!.id,
463-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
465+
464466
email: (request.user as any).email,
465467
roleId: 'global_admin'
466468
},
@@ -484,7 +486,7 @@ export default async function createGlobalServer(server: FastifyInstance) {
484486
},
485487
createdBy: {
486488
id: request.user!.id,
487-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
489+
488490
email: (request.user as any).email
489491
},
490492
metadata: {
@@ -606,7 +608,7 @@ export default async function createGlobalServer(server: FastifyInstance) {
606608
const jsonString = JSON.stringify(errorResponse);
607609
return reply.status(500).type('application/json').send(jsonString);
608610
}
609-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
611+
610612
} catch (error: any) {
611613
request.log.error({
612614
operation: 'create_global_mcp_server',

services/backend/src/routes/oauth2/schemas.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,104 @@ export interface OAuth2Client {
345345
name: string;
346346
}
347347

348+
// =============================================================================
349+
// DEVICE INFORMATION SCHEMAS
350+
// =============================================================================
351+
352+
/**
353+
* Device information schema for OAuth2 token requests
354+
* Used by: token.ts for device registration during login
355+
*/
356+
export const DEVICE_INFO_SCHEMA = {
357+
type: 'object',
358+
properties: {
359+
device_name: {
360+
type: 'string',
361+
minLength: 1,
362+
maxLength: 100,
363+
description: 'User-friendly device name (defaults to hostname)'
364+
},
365+
hostname: {
366+
type: 'string',
367+
description: 'System hostname'
368+
},
369+
hardware_id: {
370+
type: 'string',
371+
minLength: 1,
372+
description: 'Unique hardware fingerprint'
373+
},
374+
os_type: {
375+
type: 'string',
376+
description: 'Operating system type (e.g., macOS, Windows, Linux)'
377+
},
378+
os_version: {
379+
type: 'string',
380+
description: 'Operating system version'
381+
},
382+
arch: {
383+
type: 'string',
384+
description: 'System architecture (e.g., arm64, x64)'
385+
},
386+
node_version: {
387+
type: 'string',
388+
description: 'Node.js version for compatibility'
389+
},
390+
user_agent: {
391+
type: 'string',
392+
description: 'User agent string from CLI'
393+
}
394+
},
395+
required: ['device_name', 'hostname', 'hardware_id'],
396+
additionalProperties: false
397+
} as const;
398+
399+
/**
400+
* Device response schema for OAuth2 token responses
401+
* Used by: token.ts for returning device information
402+
*/
403+
export const DEVICE_RESPONSE_SCHEMA = {
404+
type: 'object',
405+
properties: {
406+
id: {
407+
type: 'string',
408+
description: 'Unique device identifier'
409+
},
410+
device_name: {
411+
type: 'string',
412+
description: 'User-friendly device name'
413+
},
414+
hostname: {
415+
type: 'string',
416+
nullable: true,
417+
description: 'System hostname'
418+
},
419+
hardware_id: {
420+
type: 'string',
421+
nullable: true,
422+
description: 'Hardware fingerprint'
423+
},
424+
os_type: {
425+
type: 'string',
426+
nullable: true,
427+
description: 'Operating system type'
428+
},
429+
is_active: {
430+
type: 'boolean',
431+
description: 'Whether device is active'
432+
},
433+
is_trusted: {
434+
type: 'boolean',
435+
description: 'Whether device is trusted'
436+
},
437+
created_at: {
438+
type: 'string',
439+
format: 'date-time',
440+
description: 'Device creation timestamp'
441+
}
442+
},
443+
required: ['id', 'device_name', 'is_active', 'is_trusted', 'created_at']
444+
} as const;
445+
348446
// =============================================================================
349447
// OAUTH2 SCOPE DEFINITIONS
350448
// =============================================================================

0 commit comments

Comments
 (0)