From a74f1b0e7b7cb16ff14c91b9135d77653c380076 Mon Sep 17 00:00:00 2001 From: Hampus Date: Wed, 2 Sep 2026 18:12:48 +0200 Subject: [PATCH] fix(ci): clear knip, refresh openapi, close kv schema race (#2409) --- .../database/PostgresKvUpgradeSafety.test.ts | 15 ++- fluxer_api/src/api/openapi/openapi.json | 100 ++++++++++++++++-- fluxer_app/package.json | 1 - .../src/main/DesktopOutboundHTTP.ts | 18 ++-- .../src/main/PrivilegedRendererDocuments.ts | 2 +- .../src/domains/auth/DesktopHandoffCode.ts | 4 +- pnpm-lock.yaml | 6 -- pnpm-workspace.yaml | 1 - 8 files changed, 116 insertions(+), 31 deletions(-) diff --git a/fluxer_api/src/api/database/PostgresKvUpgradeSafety.test.ts b/fluxer_api/src/api/database/PostgresKvUpgradeSafety.test.ts index 5f08313e8..d247b6e82 100644 --- a/fluxer_api/src/api/database/PostgresKvUpgradeSafety.test.ts +++ b/fluxer_api/src/api/database/PostgresKvUpgradeSafety.test.ts @@ -374,6 +374,10 @@ suite('postgres kv upgrade safety', () => { const gate = new Promise((resolve) => { release = resolve; }); + let created = () => {}; + const tableCreated = new Promise((resolve) => { + created = resolve; + }); const peer = raw.transaction(async (db) => { await db.query(` CREATE TABLE IF NOT EXISTS ${RACE} ( @@ -385,13 +389,22 @@ CREATE TABLE IF NOT EXISTS ${RACE} ( updated_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (table_name, row_key) )`); + created(); await gate; }); + await Promise.race([tableCreated, peer]); const booting = ensurePostgresKvSchema(new TableClient(raw, RACE)).then( () => 'ok', (error: Error) => `failed: ${error.message}`, ); - await sleep(500); + for (let attempt = 0; attempt < 200; attempt += 1) { + const blocked = await raw.query( + `SELECT 1 FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND wait_event_type = 'Lock' AND query LIKE $1`, + [`%${RACE}%`], + ); + if (blocked.rows.length > 0) break; + await sleep(50); + } release(); await peer; expect(await booting).toBe('ok'); diff --git a/fluxer_api/src/api/openapi/openapi.json b/fluxer_api/src/api/openapi/openapi.json index e7343829f..e62cac42f 100644 --- a/fluxer_api/src/api/openapi/openapi.json +++ b/fluxer_api/src/api/openapi/openapi.json @@ -486,7 +486,11 @@ "description": "Cancel an ongoing handoff session. The handoff code will no longer be valid for authentication.", "parameters": [ {"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"} - ] + ], + "requestBody": { + "required": true, + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HandoffCancelRequest"}}} + } } }, "/auth/handoff/{code}/info": { @@ -609,6 +613,69 @@ "parameters": [ {"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"} ] + }, + "post": { + "operationId": "get_handoff_status_with_secret", + "summary": "Get handoff status with secret", + "tags": ["Auth"], + "responses": { + "200": { + "description": "Success", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HandoffStatusResponse"}}} + }, + "400": { + "description": "Bad Request - The request was malformed or contained invalid data", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + }, + "429": { + "description": "Too Many Requests - You are being rate limited", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": {"type": "string", "enum": ["RATE_LIMITED"]}, + "message": {"type": "string"}, + "retry_after": {"type": "number", "description": "Seconds to wait before retrying"}, + "global": {"type": "boolean", "description": "Whether this is a global rate limit"} + }, + "required": ["code", "message", "retry_after"] + } + } + }, + "headers": { + "Retry-After": { + "description": "Number of seconds to wait before retrying (only on 429)", + "schema": {"type": "integer"} + }, + "X-RateLimit-Limit": { + "description": "The number of requests that can be made in the current window", + "schema": {"type": "integer"} + }, + "X-RateLimit-Remaining": { + "description": "The number of remaining requests that can be made", + "schema": {"type": "integer"} + }, + "X-RateLimit-Reset": { + "description": "Unix timestamp when the rate limit resets", + "schema": {"type": "integer"} + } + } + }, + "500": { + "description": "Internal Server Error - An unexpected error occurred", + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}} + } + }, + "x-mint": {"metadata": {"title": "Get handoff status with secret"}}, + "description": "Check the status of a handoff session using the poll secret from initiation. Returns the authentication token once the handoff is complete and the presented secret matches.", + "parameters": [ + {"name": "code", "in": "path", "required": true, "schema": {"type": "string"}, "description": "The code"} + ], + "requestBody": { + "required": true, + "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HandoffStatusRequest"}}} + } } }, "/auth/ip-authorization/poll": { @@ -23871,10 +23938,21 @@ "type": "string", "format": "date-time", "description": "ISO 8601 timestamp when the handoff code expires" + }, + "poll_secret": { + "type": "string", + "description": "Secret the initiating device must present to retrieve the token" } }, "required": ["code", "expires_at"] }, + "HandoffCancelRequest": { + "type": "object", + "properties": { + "poll_secret": {"type": "string", "description": "The poll secret issued when the handoff was initiated"} + }, + "required": ["poll_secret"] + }, "HandoffInfoResponse": { "type": "object", "properties": { @@ -23981,6 +24059,13 @@ }, "required": ["id", "username", "discriminator", "global_name", "avatar", "avatar_color", "flags"] }, + "HandoffStatusRequest": { + "type": "object", + "properties": { + "poll_secret": {"type": "string", "description": "The poll secret issued when the handoff was initiated"} + }, + "required": ["poll_secret"] + }, "IpAuthorizationPollResponse": { "type": "object", "properties": { @@ -31264,9 +31349,9 @@ "page": { "type": "integer", "minimum": 1, - "maximum": 9007199254740991, - "format": "int53", - "description": "Page number for pagination (ignored when cursor is provided)" + "maximum": 400, + "format": "int32", + "description": "Page number for pagination (ignored when cursor is provided). Use cursor to page beyond this." }, "cursor": { "type": "array", @@ -32178,12 +32263,7 @@ "type": "object", "properties": { "type": {"type": "string", "enum": ["bsky", "domain"], "description": "The type of connection to create"}, - "identifier": { - "type": "string", - "minLength": 1, - "maxLength": 253, - "description": "The connection identifier (handle or domain)" - }, + "identifier": {"type": "string", "description": "The connection identifier (handle or domain)"}, "visibility_flags": {"$ref": "#/components/schemas/Int32Type"} }, "required": ["type", "identifier"] diff --git a/fluxer_app/package.json b/fluxer_app/package.json index b50202ecb..6612e2eaf 100644 --- a/fluxer_app/package.json +++ b/fluxer_app/package.json @@ -229,7 +229,6 @@ "mobx-persist-store": "catalog:", "mobx-react-lite": "catalog:", "motion": "catalog:", - "onnxruntime-common": "catalog:", "onnxruntime-web": "catalog:", "qrcode": "catalog:", "react": "catalog:", diff --git a/fluxer_desktop/src/main/DesktopOutboundHTTP.ts b/fluxer_desktop/src/main/DesktopOutboundHTTP.ts index 45d77e375..34c4b0222 100644 --- a/fluxer_desktop/src/main/DesktopOutboundHTTP.ts +++ b/fluxer_desktop/src/main/DesktopOutboundHTTP.ts @@ -48,7 +48,7 @@ interface PinnedAddress { readonly family: 4 | 6; } -export interface DesktopOutboundGETRequest { +interface DesktopOutboundGETRequest { readonly context: string; readonly timeoutMs: number; readonly url: URL; @@ -69,42 +69,42 @@ interface BoundedMessageRead { readonly message: Readable; } -export class DesktopOutboundHTTPBlockedError extends Error { +class DesktopOutboundHTTPBlockedError extends Error { public constructor() { super(DESKTOP_OUTBOUND_HTTP_BLOCKED_MESSAGE); this.name = 'DesktopOutboundHTTPBlockedError'; } } -export class DesktopOutboundHTTPTransportError extends Error { +class DesktopOutboundHTTPTransportError extends Error { public constructor() { super(DESKTOP_OUTBOUND_HTTP_TRANSPORT_MESSAGE); this.name = 'DesktopOutboundHTTPTransportError'; } } -export class DesktopOutboundHTTPTimeoutError extends Error { +class DesktopOutboundHTTPTimeoutError extends Error { public constructor() { super(DESKTOP_OUTBOUND_HTTP_TIMEOUT_MESSAGE); this.name = 'DesktopOutboundHTTPTimeoutError'; } } -export class DesktopOutboundHTTPCapacityError extends Error { +class DesktopOutboundHTTPCapacityError extends Error { public constructor() { super(DESKTOP_OUTBOUND_HTTP_CAPACITY_MESSAGE); this.name = 'DesktopOutboundHTTPCapacityError'; } } -export class BoundedMessageByteLimitError extends RangeError { +class BoundedMessageByteLimitError extends RangeError { public constructor(description: string, maxBytes: number) { super(`${description} exceeds ${maxBytes} bytes`); this.name = 'BoundedMessageByteLimitError'; } } -export class BoundedMessageChunkLimitError extends RangeError { +class BoundedMessageChunkLimitError extends RangeError { public constructor(description: string, maxChunks: number) { super(`${description} exceeds ${maxChunks} response chunks`); this.name = 'BoundedMessageChunkLimitError'; @@ -269,7 +269,7 @@ function isPublicIPv6Address(address: string): boolean { return !(first === 0x2001 && second === 0x0db8); } -export function isPublicPinnedAddress(pinned: PinnedAddress): boolean { +function isPublicPinnedAddress(pinned: PinnedAddress): boolean { return pinned.family === 4 ? isPublicIPv4Address(pinned.address) : isPublicIPv6Address(pinned.address); } @@ -396,7 +396,7 @@ async function lookupAllAddresses(hostname: string): Promise record.address); } -export class DesktopOutboundHTTP { +class DesktopOutboundHTTP { private readonly httpAgent = new http.Agent({keepAlive: true, maxSockets: DESKTOP_OUTBOUND_HTTP_MAX_SOCKETS}); private readonly httpsAgent = new https.Agent({keepAlive: true, maxSockets: DESKTOP_OUTBOUND_HTTP_MAX_SOCKETS}); private addressRequirementOperation: Promise | null = null; diff --git a/fluxer_desktop/src/main/PrivilegedRendererDocuments.ts b/fluxer_desktop/src/main/PrivilegedRendererDocuments.ts index bade5b587..2297c062d 100644 --- a/fluxer_desktop/src/main/PrivilegedRendererDocuments.ts +++ b/fluxer_desktop/src/main/PrivilegedRendererDocuments.ts @@ -3,7 +3,7 @@ import {isTrustedOrigin} from '@electron/main/Window'; import type {IpcMainInvokeEvent} from 'electron'; -export class UntrustedRendererDocumentSenderError extends Error { +class UntrustedRendererDocumentSenderError extends Error { public constructor(channel: string) { super(`${channel} is only reachable from a trusted top-level renderer document`); this.name = 'UntrustedRendererDocumentSenderError'; diff --git a/packages/schema/src/domains/auth/DesktopHandoffCode.ts b/packages/schema/src/domains/auth/DesktopHandoffCode.ts index 464d1d4d7..ce620d1b5 100644 --- a/packages/schema/src/domains/auth/DesktopHandoffCode.ts +++ b/packages/schema/src/domains/auth/DesktopHandoffCode.ts @@ -11,14 +11,14 @@ function normalizeDesktopHandoffCode(value: string): string { return value.replace(DESKTOP_HANDOFF_CODE_SEPARATOR_PATTERN, '').toUpperCase(); } -export function isDesktopHandoffCode(value: string): boolean { +function isDesktopHandoffCode(value: string): boolean { if (value.length !== DESKTOP_HANDOFF_CODE_LENGTH) { return false; } return Array.from(value).every((character) => DESKTOP_HANDOFF_CODE_ALPHABET.includes(character)); } -export function parseDesktopHandoffCodeInput(value: string): string { +function parseDesktopHandoffCodeInput(value: string): string { return normalizeDesktopHandoffCode(value).slice(0, DESKTOP_HANDOFF_CODE_LENGTH); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a6fb9d35..e6e475201 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -267,9 +267,6 @@ catalogs: nodemailer: specifier: 9.0.6 version: 9.0.6 - onnxruntime-common: - specifier: 1.27.0 - version: 1.27.0 onnxruntime-web: specifier: 1.27.0 version: 1.27.0 @@ -1535,9 +1532,6 @@ importers: motion: specifier: 'catalog:' version: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - onnxruntime-common: - specifier: 'catalog:' - version: 1.27.0 onnxruntime-web: specifier: 'catalog:' version: 1.27.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ef7c9b9a6..207c5673b 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -122,7 +122,6 @@ catalog: msw: 2.12.10 nats: 2.29.3 nodemailer: 9.0.6 - onnxruntime-common: 1.27.0 onnxruntime-web: 1.27.0 pg: 8.16.3 pino: 10.3.1