fix: live-run wiring (SDK 1.29, zod 3.25, OAUTH_ISSUER split, alt host ports, web on 3001, log level cast, pino transport)
- Bump @modelcontextprotocol/sdk from 1.0.4 to 1.29.0 in runner-template (1.0.4 has no McpServer or StreamableHTTPServerTransport — file not found at runtime). - Bump zod to 3.25.76 across workspace to satisfy modern SDK peer dep. - Split OAUTH_ISSUER (canonical, host-reachable) from CONTROL_PLANE_URL (container-reachable for JWKS). Runner verifies iss against OAUTH_ISSUER; fetches JWKS from CONTROL_PLANE_URL. Both API and runner now agree on http://localhost:4000/oauth as the issuer in dev. - Move postgres host port 5432 to 5440, redis 6379 to 6390 to avoid collisions with native installs on the dev machine. - Move web from 3000 to 3001 (3000 occupied by Gitea on dev machine). - Drop pino-pretty transport from API to avoid runtime require of an unbundled dep. - Cast build_logs.level (varchar) to BuildEvent's literal union in WS replay path. - Remove unused reqBase helper in oauth.ts.
This commit is contained in:
@@ -46,7 +46,7 @@ async function resolveServerByResource(resource: string) {
|
||||
export async function oauthRoutes(app: FastifyInstance): Promise<void> {
|
||||
// Authorization Server Metadata (RFC 8414) — control-plane wide
|
||||
app.get('/oauth/.well-known/oauth-authorization-server', async (_req, reply) => {
|
||||
const base = `${reqBase(_req)}`;
|
||||
const base = `${config.CONTROL_PLANE_PUBLIC_URL}`;
|
||||
return reply.send({
|
||||
issuer: `${base}/oauth`,
|
||||
authorization_endpoint: `${base}/oauth/authorize`,
|
||||
@@ -215,7 +215,7 @@ export async function oauthRoutes(app: FastifyInstance): Promise<void> {
|
||||
const accessToken = await signAccessToken({
|
||||
subject: row.code.userId ?? row.client.clientId,
|
||||
audience: resource,
|
||||
issuer: `${reqBase(req)}/oauth`,
|
||||
issuer: `${config.CONTROL_PLANE_PUBLIC_URL}/oauth`,
|
||||
scope: row.code.scope ?? '',
|
||||
ttlSeconds: 3600,
|
||||
});
|
||||
@@ -249,7 +249,7 @@ export async function oauthRoutes(app: FastifyInstance): Promise<void> {
|
||||
if (!parsed.success) return reply.code(400).send({ error: 'invalid_request' });
|
||||
const server = await resolveServerByResource(parsed.data.resource);
|
||||
if (!server) return reply.code(404).send({ error: 'not_found' });
|
||||
const base = reqBase(req);
|
||||
const base = config.CONTROL_PLANE_PUBLIC_URL;
|
||||
return reply.send({
|
||||
resource: parsed.data.resource,
|
||||
authorization_servers: [`${base}/oauth`],
|
||||
@@ -259,12 +259,3 @@ export async function oauthRoutes(app: FastifyInstance): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
function reqBase(req: { protocol?: string; headers: Record<string, string | string[] | undefined> }): string {
|
||||
const host =
|
||||
(req.headers['x-forwarded-host'] as string | undefined) ??
|
||||
(req.headers.host as string | undefined) ??
|
||||
`localhost:${config.PORT}`;
|
||||
const proto =
|
||||
(req.headers['x-forwarded-proto'] as string | undefined) ?? req.protocol ?? 'http';
|
||||
return `${proto}://${host}`;
|
||||
}
|
||||
|
||||
@@ -183,10 +183,12 @@ export async function serverRoutes(app: FastifyInstance): Promise<void> {
|
||||
.where(eq(buildLogs.buildId, buildId))
|
||||
.orderBy(buildLogs.timestamp);
|
||||
for (const log of logs) {
|
||||
const level: 'info' | 'warn' | 'error' =
|
||||
log.level === 'warn' || log.level === 'error' ? log.level : 'info';
|
||||
socket.send(
|
||||
JSON.stringify({
|
||||
type: 'log',
|
||||
level: log.level,
|
||||
level,
|
||||
message: log.message,
|
||||
at: log.timestamp.toISOString(),
|
||||
} satisfies BuildEvent),
|
||||
|
||||
Reference in New Issue
Block a user