Fix auth flows and add daemon heartbeat endpoint
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { Type } from '@sinclair/typebox';
|
||||
import type { FastifyInstance } from 'fastify';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { nodes } from '@source/database';
|
||||
import { AppError } from '../../lib/errors.js';
|
||||
|
||||
const HeartbeatSchema = {
|
||||
body: Type.Object({
|
||||
active_servers: Type.Number({ minimum: 0 }),
|
||||
total_servers: Type.Number({ minimum: 0 }),
|
||||
version: Type.String(),
|
||||
}),
|
||||
};
|
||||
|
||||
function extractBearerToken(authHeader?: string): string | null {
|
||||
if (!authHeader) return null;
|
||||
const [scheme, token] = authHeader.split(' ');
|
||||
if (!scheme || !token || scheme.toLowerCase() !== 'bearer') return null;
|
||||
return token;
|
||||
}
|
||||
|
||||
export default async function daemonNodeRoutes(app: FastifyInstance) {
|
||||
// POST /api/nodes/heartbeat
|
||||
app.post('/heartbeat', { schema: HeartbeatSchema }, async (request) => {
|
||||
const token = extractBearerToken(
|
||||
typeof request.headers.authorization === 'string'
|
||||
? request.headers.authorization
|
||||
: undefined,
|
||||
);
|
||||
|
||||
if (!token) {
|
||||
throw AppError.unauthorized('Missing daemon bearer token', 'DAEMON_AUTH_MISSING');
|
||||
}
|
||||
|
||||
const node = await app.db.query.nodes.findFirst({
|
||||
where: eq(nodes.daemonToken, token),
|
||||
columns: { id: true },
|
||||
});
|
||||
|
||||
if (!node) {
|
||||
throw AppError.unauthorized('Invalid daemon token', 'DAEMON_AUTH_INVALID');
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
await app.db
|
||||
.update(nodes)
|
||||
.set({
|
||||
isOnline: true,
|
||||
lastHeartbeat: now,
|
||||
updatedAt: now,
|
||||
})
|
||||
.where(eq(nodes.id, node.id));
|
||||
|
||||
const body = request.body as {
|
||||
active_servers: number;
|
||||
total_servers: number;
|
||||
version: string;
|
||||
};
|
||||
|
||||
return {
|
||||
success: true,
|
||||
nodeId: node.id,
|
||||
activeServers: body.active_servers,
|
||||
totalServers: body.total_servers,
|
||||
version: body.version,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -26,7 +26,16 @@ export default async function nodeRoutes(app: FastifyInstance) {
|
||||
.where(eq(nodes.organizationId, orgId))
|
||||
.orderBy(nodes.createdAt);
|
||||
|
||||
return { data: nodeList };
|
||||
const total = nodeList.length;
|
||||
return {
|
||||
data: nodeList,
|
||||
meta: {
|
||||
total,
|
||||
page: 1,
|
||||
perPage: total,
|
||||
totalPages: total === 0 ? 0 : 1,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// POST /api/organizations/:orgId/nodes
|
||||
|
||||
Reference in New Issue
Block a user