feat: plugins v1.7
This commit is contained in:
241
electron/api/openapi.ts
Normal file
241
electron/api/openapi.ts
Normal file
@@ -0,0 +1,241 @@
|
||||
export interface OpenApiBuildOptions {
|
||||
baseUrl: string;
|
||||
appVersion: string;
|
||||
}
|
||||
|
||||
export function buildOpenApiDocument(options: OpenApiBuildOptions): unknown {
|
||||
const { baseUrl, appVersion } = options;
|
||||
|
||||
return {
|
||||
openapi: '3.1.0',
|
||||
info: {
|
||||
title: 'MetoYou Local Desktop API',
|
||||
version: appVersion,
|
||||
description:
|
||||
'Authenticated local HTTP API exposed by the MetoYou desktop app. '
|
||||
+ 'Authentication is performed against a configured signaling server. '
|
||||
+ 'Bearer tokens issued here are scoped to this device only.'
|
||||
},
|
||||
servers: [{ url: baseUrl }],
|
||||
components: {
|
||||
securitySchemes: {
|
||||
bearerAuth: {
|
||||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
bearerFormat: 'opaque'
|
||||
}
|
||||
},
|
||||
schemas: {
|
||||
Error: {
|
||||
type: 'object',
|
||||
required: ['error'],
|
||||
properties: {
|
||||
error: { type: 'string' },
|
||||
errorCode: { type: 'string' }
|
||||
}
|
||||
},
|
||||
LoginRequest: {
|
||||
type: 'object',
|
||||
required: ['username', 'password', 'serverUrl'],
|
||||
properties: {
|
||||
username: { type: 'string' },
|
||||
password: { type: 'string' },
|
||||
serverUrl: {
|
||||
type: 'string',
|
||||
format: 'uri',
|
||||
description: 'Base URL of the signaling server to authenticate against. Must be in the allowed list configured in the desktop app.'
|
||||
}
|
||||
}
|
||||
},
|
||||
LoginResponse: {
|
||||
type: 'object',
|
||||
required: ['token', 'expiresAt', 'user'],
|
||||
properties: {
|
||||
token: { type: 'string' },
|
||||
expiresAt: { type: 'integer', format: 'int64' },
|
||||
user: { $ref: '#/components/schemas/AuthUser' }
|
||||
}
|
||||
},
|
||||
AuthUser: {
|
||||
type: 'object',
|
||||
required: ['id', 'username', 'displayName'],
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
username: { type: 'string' },
|
||||
displayName: { type: 'string' }
|
||||
}
|
||||
},
|
||||
Profile: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
username: { type: 'string' },
|
||||
displayName: { type: 'string' },
|
||||
description: { type: 'string' },
|
||||
avatarUrl: { type: 'string' },
|
||||
status: { type: 'string' }
|
||||
}
|
||||
},
|
||||
Room: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
name: { type: 'string' }
|
||||
},
|
||||
additionalProperties: true
|
||||
},
|
||||
Message: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
roomId: { type: 'string' },
|
||||
channelId: { type: 'string' },
|
||||
senderId: { type: 'string' },
|
||||
senderName: { type: 'string' },
|
||||
content: { type: 'string' },
|
||||
timestamp: { type: 'integer', format: 'int64' },
|
||||
editedAt: { type: 'integer', format: 'int64' },
|
||||
isDeleted: { type: 'boolean' }
|
||||
},
|
||||
additionalProperties: true
|
||||
}
|
||||
}
|
||||
},
|
||||
security: [{ bearerAuth: [] }],
|
||||
paths: {
|
||||
'/api/health': {
|
||||
get: {
|
||||
security: [],
|
||||
summary: 'Liveness probe',
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Service is alive',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
status: { type: 'string' },
|
||||
version: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/api/openapi.json': {
|
||||
get: {
|
||||
security: [],
|
||||
summary: 'OpenAPI specification',
|
||||
responses: { '200': { description: 'This document' } }
|
||||
}
|
||||
},
|
||||
'/api/auth/login': {
|
||||
post: {
|
||||
security: [],
|
||||
summary: 'Exchange username/password (validated by a signaling server) for a bearer token',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/LoginRequest' }
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Token issued',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/LoginResponse' }
|
||||
}
|
||||
}
|
||||
},
|
||||
'401': {
|
||||
description: 'Invalid credentials',
|
||||
content: {
|
||||
'application/json': { schema: { $ref: '#/components/schemas/Error' } }
|
||||
}
|
||||
},
|
||||
'403': {
|
||||
description: 'Signaling server URL not allowed',
|
||||
content: {
|
||||
'application/json': { schema: { $ref: '#/components/schemas/Error' } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/api/auth/logout': {
|
||||
post: {
|
||||
summary: 'Revoke the current bearer token',
|
||||
responses: { '204': { description: 'Token revoked' } }
|
||||
}
|
||||
},
|
||||
'/api/profile': {
|
||||
get: {
|
||||
summary: 'Get the current user profile',
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Current user profile',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/Profile' }
|
||||
}
|
||||
}
|
||||
},
|
||||
'404': {
|
||||
description: 'No current user is set on this device',
|
||||
content: {
|
||||
'application/json': { schema: { $ref: '#/components/schemas/Error' } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/api/rooms': {
|
||||
get: {
|
||||
summary: 'List rooms (servers) known to this device',
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Rooms array',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: { $ref: '#/components/schemas/Room' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/api/rooms/{roomId}/messages': {
|
||||
get: {
|
||||
summary: 'List messages for a room',
|
||||
parameters: [
|
||||
{ name: 'roomId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
{ name: 'limit', in: 'query', required: false, schema: { type: 'integer', minimum: 1, maximum: 500 } },
|
||||
{ name: 'offset', in: 'query', required: false, schema: { type: 'integer', minimum: 0 } }
|
||||
],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Messages array',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: { $ref: '#/components/schemas/Message' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user