@openclaw/crabline 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -12
- package/dist/src/bin/crabline.js +3 -1
- package/dist/src/bin/crabline.js.map +1 -1
- package/dist/src/cli/program.d.ts +5 -1
- package/dist/src/cli/program.js +264 -50
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/config/load.js +39 -3
- package/dist/src/config/load.js.map +1 -1
- package/dist/src/config/schema.d.ts +20 -0
- package/dist/src/config/schema.js +163 -35
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/core/errors.d.ts +1 -0
- package/dist/src/core/errors.js +6 -3
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/http-path.d.ts +1 -0
- package/dist/src/core/http-path.js +14 -0
- package/dist/src/core/http-path.js.map +1 -0
- package/dist/src/core/matcher.d.ts +3 -1
- package/dist/src/core/matcher.js +58 -2
- package/dist/src/core/matcher.js.map +1 -1
- package/dist/src/core/nonces.d.ts +2 -0
- package/dist/src/core/nonces.js +11 -1
- package/dist/src/core/nonces.js.map +1 -1
- package/dist/src/core/reporters.d.ts +5 -0
- package/dist/src/core/reporters.js +26 -2
- package/dist/src/core/reporters.js.map +1 -1
- package/dist/src/core/run.d.ts +3 -1
- package/dist/src/core/run.js +178 -66
- package/dist/src/core/run.js.map +1 -1
- package/dist/src/matrix-ids.d.ts +5 -0
- package/dist/src/matrix-ids.js +83 -0
- package/dist/src/matrix-ids.js.map +1 -0
- package/dist/src/openclaw/artifact-generation.d.ts +7 -2
- package/dist/src/openclaw/artifact-generation.js +399 -27
- package/dist/src/openclaw/artifact-generation.js.map +1 -1
- package/dist/src/openclaw/bridges/matrix.js +21 -4
- package/dist/src/openclaw/bridges/matrix.js.map +1 -1
- package/dist/src/openclaw/bridges/mattermost.js +13 -8
- package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
- package/dist/src/openclaw/bridges/probe-response.d.ts +1 -0
- package/dist/src/openclaw/bridges/probe-response.js +5 -0
- package/dist/src/openclaw/bridges/probe-response.js.map +1 -0
- package/dist/src/openclaw/bridges/signal.js +15 -6
- package/dist/src/openclaw/bridges/signal.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.js +116 -23
- package/dist/src/openclaw/bridges/slack.js.map +1 -1
- package/dist/src/openclaw/bridges/telegram.js +45 -19
- package/dist/src/openclaw/bridges/telegram.js.map +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +32 -16
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/bridges/zalo.js +8 -3
- package/dist/src/openclaw/bridges/zalo.js.map +1 -1
- package/dist/src/openclaw/private-file.d.ts +38 -3
- package/dist/src/openclaw/private-file.js +2008 -87
- package/dist/src/openclaw/private-file.js.map +1 -1
- package/dist/src/openclaw/shared.d.ts +1 -0
- package/dist/src/openclaw/shared.js +48 -13
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw/smoke-lock.d.ts +9 -0
- package/dist/src/openclaw/smoke-lock.js +626 -172
- package/dist/src/openclaw/smoke-lock.js.map +1 -1
- package/dist/src/openclaw.js +225 -42
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/platform/process-owned-lock.d.ts +11 -0
- package/dist/src/platform/process-owned-lock.js +1698 -0
- package/dist/src/platform/process-owned-lock.js.map +1 -0
- package/dist/src/platform/recorder-directory.d.ts +1 -0
- package/dist/src/platform/recorder-directory.js +14 -0
- package/dist/src/platform/recorder-directory.js.map +1 -0
- package/dist/src/platform/windows-acl.d.ts +18 -0
- package/dist/src/platform/windows-acl.js +1367 -0
- package/dist/src/platform/windows-acl.js.map +1 -0
- package/dist/src/platform/windows-lock-root.d.ts +13 -0
- package/dist/src/platform/windows-lock-root.js +98 -0
- package/dist/src/platform/windows-lock-root.js.map +1 -0
- package/dist/src/providers/builtin/discord.d.ts +4 -0
- package/dist/src/providers/builtin/discord.js +52 -9
- package/dist/src/providers/builtin/discord.js.map +1 -1
- package/dist/src/providers/builtin/external-webhook-auth.d.ts +1 -0
- package/dist/src/providers/builtin/external-webhook-auth.js +38 -1
- package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -1
- package/dist/src/providers/builtin/feishu.d.ts +1 -0
- package/dist/src/providers/builtin/feishu.js +96 -26
- package/dist/src/providers/builtin/feishu.js.map +1 -1
- package/dist/src/providers/builtin/googlechat.d.ts +1 -0
- package/dist/src/providers/builtin/googlechat.js +95 -26
- package/dist/src/providers/builtin/googlechat.js.map +1 -1
- package/dist/src/providers/builtin/imessage.js +60 -17
- package/dist/src/providers/builtin/imessage.js.map +1 -1
- package/dist/src/providers/builtin/loopback.js +88 -35
- package/dist/src/providers/builtin/loopback.js.map +1 -1
- package/dist/src/providers/builtin/matrix.d.ts +2 -2
- package/dist/src/providers/builtin/matrix.js +78 -21
- package/dist/src/providers/builtin/matrix.js.map +1 -1
- package/dist/src/providers/builtin/mattermost.d.ts +11 -7
- package/dist/src/providers/builtin/mattermost.js +138 -24
- package/dist/src/providers/builtin/mattermost.js.map +1 -1
- package/dist/src/providers/builtin/msteams.d.ts +1 -0
- package/dist/src/providers/builtin/msteams.js +118 -38
- package/dist/src/providers/builtin/msteams.js.map +1 -1
- package/dist/src/providers/builtin/native-local-mock.js +4 -4
- package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
- package/dist/src/providers/builtin/script.js +1057 -146
- package/dist/src/providers/builtin/script.js.map +1 -1
- package/dist/src/providers/builtin/slack.d.ts +8 -1
- package/dist/src/providers/builtin/slack.js +327 -24
- package/dist/src/providers/builtin/slack.js.map +1 -1
- package/dist/src/providers/builtin/telegram.d.ts +1 -1
- package/dist/src/providers/builtin/telegram.js +55 -14
- package/dist/src/providers/builtin/telegram.js.map +1 -1
- package/dist/src/providers/builtin/whatsapp.d.ts +4 -3
- package/dist/src/providers/builtin/whatsapp.js +157 -29
- package/dist/src/providers/builtin/whatsapp.js.map +1 -1
- package/dist/src/providers/builtin/zalo.d.ts +5 -2
- package/dist/src/providers/builtin/zalo.js +31 -7
- package/dist/src/providers/builtin/zalo.js.map +1 -1
- package/dist/src/providers/catalog.d.ts +1 -1
- package/dist/src/providers/catalog.js +1 -1
- package/dist/src/providers/catalog.js.map +1 -1
- package/dist/src/providers/local-mock.d.ts +4 -0
- package/dist/src/providers/local-mock.js +162 -35
- package/dist/src/providers/local-mock.js.map +1 -1
- package/dist/src/providers/native-ids.d.ts +2 -0
- package/dist/src/providers/native-ids.js +3 -0
- package/dist/src/providers/native-ids.js.map +1 -1
- package/dist/src/providers/recorder.d.ts +14 -3
- package/dist/src/providers/recorder.js +521 -41
- package/dist/src/providers/recorder.js.map +1 -1
- package/dist/src/providers/registry.d.ts +1 -0
- package/dist/src/providers/registry.js +65 -20
- package/dist/src/providers/registry.js.map +1 -1
- package/dist/src/providers/signed-jwt.d.ts +6 -1
- package/dist/src/providers/signed-jwt.js +241 -50
- package/dist/src/providers/signed-jwt.js.map +1 -1
- package/dist/src/providers/slack-ids.d.ts +1 -0
- package/dist/src/providers/slack-ids.js +5 -0
- package/dist/src/providers/slack-ids.js.map +1 -1
- package/dist/src/providers/target-normalizers.d.ts +9 -1
- package/dist/src/providers/target-normalizers.js +177 -58
- package/dist/src/providers/target-normalizers.js.map +1 -1
- package/dist/src/providers/webhook-server.d.ts +3 -0
- package/dist/src/providers/webhook-server.js +268 -47
- package/dist/src/providers/webhook-server.js.map +1 -1
- package/dist/src/servers/http.d.ts +14 -2
- package/dist/src/servers/http.js +229 -58
- package/dist/src/servers/http.js.map +1 -1
- package/dist/src/servers/matrix.d.ts +3 -0
- package/dist/src/servers/matrix.js +268 -110
- package/dist/src/servers/matrix.js.map +1 -1
- package/dist/src/servers/mattermost.d.ts +5 -0
- package/dist/src/servers/mattermost.js +389 -91
- package/dist/src/servers/mattermost.js.map +1 -1
- package/dist/src/servers/recorder.d.ts +11 -0
- package/dist/src/servers/recorder.js +1072 -69
- package/dist/src/servers/recorder.js.map +1 -1
- package/dist/src/servers/signal.d.ts +1 -0
- package/dist/src/servers/signal.js +279 -44
- package/dist/src/servers/signal.js.map +1 -1
- package/dist/src/servers/slack.d.ts +15 -0
- package/dist/src/servers/slack.js +259 -51
- package/dist/src/servers/slack.js.map +1 -1
- package/dist/src/servers/telegram-identity.d.ts +6 -0
- package/dist/src/servers/telegram-identity.js +27 -0
- package/dist/src/servers/telegram-identity.js.map +1 -0
- package/dist/src/servers/telegram.d.ts +17 -6
- package/dist/src/servers/telegram.js +1169 -107
- package/dist/src/servers/telegram.js.map +1 -1
- package/dist/src/servers/webhook-target.d.ts +12 -4
- package/dist/src/servers/webhook-target.js +226 -28
- package/dist/src/servers/webhook-target.js.map +1 -1
- package/dist/src/servers/whatsapp-baileys-websocket.d.ts +60 -1
- package/dist/src/servers/whatsapp-baileys-websocket.js +782 -112
- package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
- package/dist/src/servers/whatsapp-jid.d.ts +1 -0
- package/dist/src/servers/whatsapp-jid.js +9 -5
- package/dist/src/servers/whatsapp-jid.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/binary-node.d.ts +1 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js +37 -13
- package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/crypto.d.ts +3 -0
- package/dist/src/servers/whatsapp-wire/crypto.js +23 -8
- package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/handshake.d.ts +9 -3
- package/dist/src/servers/whatsapp-wire/handshake.js +173 -12
- package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/signal.js +3 -3
- package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
- package/dist/src/servers/whatsapp.d.ts +7 -0
- package/dist/src/servers/whatsapp.js +149 -24
- package/dist/src/servers/whatsapp.js.map +1 -1
- package/dist/src/servers/zalo.d.ts +1 -0
- package/dist/src/servers/zalo.js +193 -82
- package/dist/src/servers/zalo.js.map +1 -1
- package/docs/channel-setup.md +185 -43
- package/fixtures/examples/crabline.example.yaml +3 -2
- package/package.json +18 -10
- package/fixtures/examples/openclaw-bridge.yaml +0 -125
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../src/servers/mattermost.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport path from \"node:path\";\nimport { WebSocket, WebSocketServer, type RawData } from \"ws\";\nimport {\n adminAuthError,\n drainRequestBody,\n hasAdminToken,\n InvalidJsonBodyError,\n isJsonObject,\n isLoopbackHost,\n jsonResponse,\n parseUnknownRequestBody,\n queryRecord,\n readTrimmedString,\n RequestBodyTooLargeError,\n startHttpJsonServer,\n type ServerRequestEvent,\n} from \"./http.js\";\nimport {\n recordCommittedServerEvent,\n recordServerEvent,\n type ServerEventObserver,\n} from \"./recorder.js\";\nimport { resolveMaxPendingInboundEvents } from \"./pending-events.js\";\nimport { closeWebSocketServer } from \"./websocket.js\";\n\nconst DEFAULT_WEBSOCKET_AUTHENTICATION_TIMEOUT_MS = 5_000;\nconst DEFAULT_MAX_WEBSOCKET_BUFFERED_BYTES = 1024 * 1024;\nconst DEFAULT_MAX_WEBSOCKET_MESSAGE_BYTES = 64 * 1024;\nconst DEFAULT_MAX_UNAUTHENTICATED_WEBSOCKET_CLIENTS = 32;\n\nfunction resolvePositiveLimit(value: number | undefined, name: string, fallback: number): number {\n if (value === undefined) {\n return fallback;\n }\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new Error(`${name} must be a positive safe integer.`);\n }\n return value;\n}\n\ntype MattermostPost = {\n channel_id: string;\n create_at: number;\n id: string;\n message: string;\n root_id: string;\n type: string;\n user_id: string;\n};\n\ntype MattermostWebSocketEvent = {\n broadcast: {\n channel_id: string;\n omit_users: null | Record<string, boolean>;\n team_id: string;\n user_id: string;\n };\n data: Record<string, unknown>;\n event: string;\n};\ntype MattermostRecorderEvent = ServerRequestEvent & {\n accepted?: boolean | undefined;\n};\n\ntype MattermostServerState = {\n adminToken: string;\n botToken: string;\n botUserId: string;\n botUsername: string;\n channels: Map<string, { id: string; name: string; display_name: string; type: string }>;\n maxPendingInboundEvents: number;\n maxWebSocketBufferedBytes: number;\n nextPost: number;\n onEvent: ServerEventObserver | undefined;\n pendingEvents: MattermostWebSocketEvent[];\n posts: Map<string, MattermostPost>;\n recorderPath: string;\n users: Map<string, { id: string; username: string; update_at: number }>;\n websocketClients: Map<WebSocket, number>;\n};\n\nexport type MattermostServerManifest = {\n adminToken: string;\n baseUrl: string;\n botToken: string;\n botUserId: string;\n endpoints: {\n adminInboundUrl: string;\n apiRoot: string;\n websocketUrl: string;\n };\n env: {\n MATTERMOST_BOT_TOKEN: string;\n MATTERMOST_URL: string;\n };\n provider: \"mattermost\";\n recorderPath: string;\n version: 1;\n};\n\nexport type StartedMattermostServer = {\n close(): Promise<void>;\n manifest: MattermostServerManifest;\n};\n\nexport type StartMattermostServerParams = {\n adminToken?: string | undefined;\n botToken?: string | undefined;\n botUserId?: string | undefined;\n botUsername?: string | undefined;\n host?: string | undefined;\n onEvent?: ServerEventObserver | undefined;\n port?: number | undefined;\n recorderPath?: string | undefined;\n maxPendingInboundEvents?: number | undefined;\n maxWebSocketBufferedBytes?: number | undefined;\n maxWebSocketMessageBytes?: number | undefined;\n maxUnauthenticatedWebSocketClients?: number | undefined;\n websocketAuthenticationTimeoutMs?: number | undefined;\n};\n\nexport function mattermostId(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 26);\n}\n\nasync function appendEvent(\n state: MattermostServerState,\n event: ServerRequestEvent,\n committed = false,\n): Promise<void> {\n const params = { event, onEvent: state.onEvent, recorderPath: state.recorderPath };\n await (committed ? recordCommittedServerEvent(params) : recordServerEvent(params));\n}\n\nfunction authorized(request: IncomingMessage, token: string): boolean {\n const [scheme, value] = request.headers.authorization?.trim().split(/\\s+/, 2) ?? [];\n return scheme?.toLowerCase() === \"bearer\" && value === token;\n}\n\nfunction mattermostError(message: string, status: number): Response {\n return jsonResponse(\n {\n id: `api.context.${status}`,\n message,\n request_id: \"\",\n status_code: status,\n },\n status,\n );\n}\n\nfunction decodeMattermostPathSegment(value: string): string | Response {\n try {\n return decodeURIComponent(value);\n } catch {\n return mattermostError(\"Invalid path parameter\", 400);\n }\n}\n\nfunction eventBroadcast(params: {\n channelId?: string;\n omitUsers?: Record<string, boolean>;\n userId?: string;\n}): MattermostWebSocketEvent[\"broadcast\"] {\n return {\n channel_id: params.channelId ?? \"\",\n omit_users: params.omitUsers ?? null,\n team_id: \"\",\n user_id: params.userId ?? \"\",\n };\n}\n\nfunction postEvent(\n event: \"post_deleted\" | \"post_edited\" | \"posted\",\n post: MattermostPost,\n senderName: string,\n channelType: string,\n): MattermostWebSocketEvent {\n return {\n event,\n data: {\n channel_display_name: post.channel_id,\n channel_id: post.channel_id,\n channel_name: post.channel_id,\n channel_type: channelType,\n post: JSON.stringify(post),\n sender_name: senderName,\n },\n broadcast: eventBroadcast({ channelId: post.channel_id, userId: post.user_id }),\n };\n}\n\nfunction webSocketEventBytes(event: MattermostWebSocketEvent): number {\n return Buffer.byteLength(JSON.stringify({ ...event, seq: 0 }), \"utf8\");\n}\n\nfunction sendEvent(\n state: MattermostServerState,\n client: WebSocket,\n event: MattermostWebSocketEvent,\n): boolean {\n const seq = state.websocketClients.get(client);\n if (seq === undefined || client.readyState !== WebSocket.OPEN) {\n state.websocketClients.delete(client);\n return false;\n }\n const payload = JSON.stringify({ ...event, seq });\n if (\n client.bufferedAmount + Buffer.byteLength(payload, \"utf8\") >\n state.maxWebSocketBufferedBytes\n ) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n return false;\n }\n try {\n client.send(payload);\n } catch {\n state.websocketClients.delete(client);\n client.terminate();\n return false;\n }\n state.websocketClients.set(client, seq + 1);\n return true;\n}\n\nfunction sendControlMessage(\n state: MattermostServerState,\n client: WebSocket,\n value: Record<string, unknown>,\n): boolean {\n if (client.readyState !== WebSocket.OPEN) {\n state.websocketClients.delete(client);\n return false;\n }\n const payload = JSON.stringify(value);\n if (\n client.bufferedAmount + Buffer.byteLength(payload, \"utf8\") >\n state.maxWebSocketBufferedBytes\n ) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n return false;\n }\n try {\n client.send(payload);\n return true;\n } catch {\n state.websocketClients.delete(client);\n client.terminate();\n return false;\n }\n}\n\nfunction broadcast(\n state: MattermostServerState,\n event: MattermostWebSocketEvent,\n queueIfUndelivered = true,\n): boolean {\n if (event.broadcast.omit_users?.[state.botUserId]) {\n return true;\n }\n if (webSocketEventBytes(event) > state.maxWebSocketBufferedBytes) {\n for (const client of state.websocketClients.keys()) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n }\n return false;\n }\n let delivered = false;\n for (const client of state.websocketClients.keys()) {\n delivered = sendEvent(state, client, event) || delivered;\n }\n if (delivered) {\n return true;\n }\n if (!queueIfUndelivered) {\n return false;\n }\n if (state.pendingEvents.length >= state.maxPendingInboundEvents) {\n return false;\n }\n state.pendingEvents.push(event);\n return true;\n}\n\nfunction pendingQueueFullResponse(state: MattermostServerState): Response {\n return jsonResponse(\n {\n error: `Pending inbound queue is full (${state.maxPendingInboundEvents} events)`,\n ok: false,\n },\n 503,\n );\n}\n\nfunction createPost(params: {\n channelId: string;\n message: string;\n rootId?: string | undefined;\n state: MattermostServerState;\n userId: string;\n}): MattermostPost {\n const id = mattermostId(`post-${params.state.nextPost++}`);\n const post = {\n channel_id: params.channelId,\n create_at: Date.now(),\n id,\n message: params.message,\n root_id: params.rootId ?? \"\",\n type: \"\",\n user_id: params.userId,\n };\n params.state.posts.set(id, post);\n return post;\n}\n\nfunction handleAdminInbound(params: {\n body: Record<string, unknown>;\n state: MattermostServerState;\n}): Response {\n const channelId = readTrimmedString(params.body.channelId ?? params.body.channel_id);\n const senderId = readTrimmedString(params.body.senderId ?? params.body.user_id);\n const text = readTrimmedString(params.body.text ?? params.body.message);\n if (!channelId || !senderId || !text) {\n return jsonResponse({ error: \"channelId, senderId, and text are required\", ok: false }, 400);\n }\n if (\n params.state.websocketClients.size === 0 &&\n params.state.pendingEvents.length >= params.state.maxPendingInboundEvents\n ) {\n return pendingQueueFullResponse(params.state);\n }\n const previousUser = params.state.users.get(senderId);\n const previousChannel = params.state.channels.get(channelId);\n const senderName =\n readTrimmedString(params.body.senderName) ?? previousUser?.username ?? senderId;\n const channelType = readTrimmedString(params.body.channelType) ?? previousChannel?.type ?? \"D\";\n const previousNextPost = params.state.nextPost;\n params.state.users.set(senderId, { id: senderId, update_at: Date.now(), username: senderName });\n params.state.channels.set(channelId, {\n display_name: previousChannel?.display_name ?? channelId,\n id: channelId,\n name: previousChannel?.name ?? channelId,\n type: channelType,\n });\n const post = createPost({\n channelId,\n message: text,\n rootId: readTrimmedString(params.body.rootId ?? params.body.root_id),\n state: params.state,\n userId: senderId,\n });\n const rollback = () => {\n params.state.posts.delete(post.id);\n params.state.nextPost = previousNextPost;\n if (previousUser) {\n params.state.users.set(senderId, previousUser);\n } else {\n params.state.users.delete(senderId);\n }\n if (previousChannel) {\n params.state.channels.set(channelId, previousChannel);\n } else {\n params.state.channels.delete(channelId);\n }\n };\n const event = postEvent(\"posted\", post, senderName, channelType);\n if (webSocketEventBytes(event) > params.state.maxWebSocketBufferedBytes) {\n rollback();\n return jsonResponse({ error: \"Inbound event is too large\", ok: false }, 413);\n }\n if (!broadcast(params.state, event)) {\n rollback();\n return pendingQueueFullResponse(params.state);\n }\n return jsonResponse({ ok: true, post });\n}\n\nasync function handleApi(params: {\n body: unknown;\n method: string;\n path: string;\n state: MattermostServerState;\n}): Promise<Response> {\n const { body, method, path: apiPath, state } = params;\n if (method === \"GET\" && apiPath === \"/users/me\") {\n return jsonResponse(state.users.get(state.botUserId));\n }\n const usernameMatch = /^\\/users\\/username\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && usernameMatch?.[1]) {\n const username = decodeMattermostPathSegment(usernameMatch[1]);\n if (username instanceof Response) {\n return username;\n }\n const user = [...state.users.values()].find((entry) => entry.username === username);\n return user ? jsonResponse(user) : mattermostError(\"User not found\", 404);\n }\n const userMatch = /^\\/users\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && userMatch?.[1]) {\n const user = state.users.get(userMatch[1]);\n return user ? jsonResponse(user) : mattermostError(\"User not found\", 404);\n }\n const channelMatch = /^\\/channels\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && channelMatch?.[1]) {\n const channel = state.channels.get(channelMatch[1]);\n return channel ? jsonResponse(channel) : mattermostError(\"Channel not found\", 404);\n }\n if (method === \"POST\" && apiPath === \"/channels/direct\") {\n const userIds = Array.isArray(body) ? body.map(readTrimmedString) : [];\n if (userIds.length !== 2 || userIds.some((value) => !value)) {\n return mattermostError(\"Two user IDs are required\", 400);\n }\n const [firstUserId, secondUserId] = userIds as [string, string];\n if (firstUserId === secondUserId) {\n return mattermostError(\"Direct channel users must be distinct\", 400);\n }\n if (!state.users.has(firstUserId) || !state.users.has(secondUserId)) {\n return mattermostError(\"User not found\", 404);\n }\n if (firstUserId !== state.botUserId && secondUserId !== state.botUserId) {\n return mattermostError(\"Authenticated user must belong to the direct channel\", 403);\n }\n const channelId = mattermostId(`dm:${userIds.sort().join(\":\")}`);\n const channel = { display_name: \"\", id: channelId, name: channelId, type: \"D\" };\n state.channels.set(channelId, channel);\n return jsonResponse(channel, 201);\n }\n if (!isJsonObject(body)) {\n return mattermostError(\"Request body must be a JSON object\", 400);\n }\n if (method === \"POST\" && apiPath === \"/users/me/typing\") {\n const channelId = readTrimmedString(body.channel_id);\n if (!channelId) {\n return mattermostError(\"channel_id is required\", 400);\n }\n if (!state.channels.has(channelId)) {\n return mattermostError(\"Channel not found\", 404);\n }\n broadcast(\n state,\n {\n broadcast: eventBroadcast({\n channelId,\n omitUsers: { [state.botUserId]: true },\n }),\n data: {\n channel_id: channelId,\n ...(readTrimmedString(body.parent_id)\n ? { parent_id: readTrimmedString(body.parent_id) }\n : {}),\n user_id: state.botUserId,\n },\n event: \"typing\",\n },\n false,\n );\n return jsonResponse({ status: \"OK\" });\n }\n if (method === \"POST\" && apiPath === \"/posts\") {\n const channelId = readTrimmedString(body.channel_id);\n const message = readTrimmedString(body.message);\n if (!channelId || !message) {\n return mattermostError(\"channel_id and message are required\", 400);\n }\n const channel = state.channels.get(channelId);\n if (!channel) {\n return mattermostError(\"Channel not found\", 404);\n }\n const rootId = readTrimmedString(body.root_id);\n if (rootId) {\n const rootPost = state.posts.get(rootId);\n if (!rootPost) {\n return mattermostError(\"Root post not found\", 404);\n }\n if (rootPost.channel_id !== channelId) {\n return mattermostError(\"Root post belongs to another channel\", 400);\n }\n }\n const post = createPost({\n channelId,\n message,\n rootId,\n state,\n userId: state.botUserId,\n });\n broadcast(state, postEvent(\"posted\", post, state.botUsername, channel.type), false);\n return jsonResponse(post, 201);\n }\n const postMatch = /^\\/posts\\/([^/]+)$/u.exec(apiPath);\n if (postMatch?.[1] && method === \"PUT\") {\n const post = state.posts.get(postMatch[1]);\n if (!post) {\n return mattermostError(\"Post not found\", 404);\n }\n if (post.user_id !== state.botUserId) {\n return mattermostError(\"You do not have permission to edit this post\", 403);\n }\n const updated = { ...post, message: readTrimmedString(body.message) ?? post.message };\n state.posts.set(updated.id, updated);\n broadcast(\n state,\n postEvent(\n \"post_edited\",\n updated,\n state.botUsername,\n state.channels.get(updated.channel_id)?.type ?? \"O\",\n ),\n false,\n );\n return jsonResponse(updated);\n }\n if (postMatch?.[1] && method === \"DELETE\") {\n const post = state.posts.get(postMatch[1]);\n if (!post) {\n return mattermostError(\"Post not found\", 404);\n }\n if (post.user_id !== state.botUserId) {\n return mattermostError(\"You do not have permission to delete this post\", 403);\n }\n state.posts.delete(post.id);\n broadcast(\n state,\n postEvent(\n \"post_deleted\",\n post,\n state.botUsername,\n state.channels.get(post.channel_id)?.type ?? \"O\",\n ),\n false,\n );\n return jsonResponse({ status: \"OK\" });\n }\n return mattermostError(\"Not found\", 404);\n}\n\nasync function handleRequest(request: IncomingMessage, state: MattermostServerState) {\n const url = new URL(request.url ?? \"/\", \"http://localhost\");\n const method = request.method ?? \"GET\";\n if (url.pathname === \"/crabline/mattermost/inbound\" && method === \"POST\") {\n if (!hasAdminToken(request, state.adminToken)) {\n drainRequestBody(request);\n return adminAuthError();\n }\n const body = await parseUnknownRequestBody(request);\n if (!isJsonObject(body)) {\n return jsonResponse({ error: \"Request body must be a JSON object\", ok: false }, 400);\n }\n await appendEvent(state, {\n at: new Date().toISOString(),\n body,\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"admin\",\n });\n return handleAdminInbound({ body, state });\n }\n if (!url.pathname.startsWith(\"/api/v4/\")) {\n return new Response(\"not found\", { status: 404 });\n }\n if (!authorized(request, state.botToken)) {\n drainRequestBody(request);\n return mattermostError(\"Invalid or missing token\", 401);\n }\n const body =\n method === \"GET\" || method === \"DELETE\" ? {} : await parseUnknownRequestBody(request);\n const event: MattermostRecorderEvent = {\n at: new Date().toISOString(),\n ...(typeof body === \"object\" && body !== null && Object.keys(body).length > 0 ? { body } : {}),\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"api\",\n };\n const response = await handleApi({\n body,\n method,\n path: url.pathname.slice(\"/api/v4\".length),\n state,\n });\n if (method === \"POST\" && url.pathname === \"/api/v4/posts\") {\n event.accepted = response.status === 201;\n }\n await appendEvent(state, event, response.ok && method !== \"GET\");\n return response;\n}\n\nfunction attachWebSocketServer(params: {\n authenticationTimeoutMs: number;\n maxMessageBytes: number;\n maxUnauthenticatedClients: number;\n state: MattermostServerState;\n server: import(\"node:http\").Server;\n}) {\n const websocketServer = new WebSocketServer({\n maxPayload: params.maxMessageBytes,\n noServer: true,\n });\n const unauthenticatedClients = new Set<WebSocket>();\n const onUpgrade = (\n request: IncomingMessage,\n socket: import(\"node:stream\").Duplex,\n head: Buffer,\n ) => {\n if (new URL(request.url ?? \"/\", \"http://localhost\").pathname !== \"/api/v4/websocket\") {\n socket.destroy();\n return;\n }\n websocketServer.handleUpgrade(request, socket, head, (client) => {\n websocketServer.emit(\"connection\", client, request);\n });\n };\n params.server.on(\"upgrade\", onUpgrade);\n websocketServer.on(\"connection\", (client) => {\n client.on(\"error\", () => {\n unauthenticatedClients.delete(client);\n params.state.websocketClients.delete(client);\n });\n if (unauthenticatedClients.size >= params.maxUnauthenticatedClients) {\n client.terminate();\n return;\n }\n unauthenticatedClients.add(client);\n let authenticationOpen = true;\n const authenticationTimeout = setTimeout(() => {\n authenticationOpen = false;\n client.close(4001, \"authentication timeout\");\n }, params.authenticationTimeoutMs);\n authenticationTimeout.unref();\n client.on(\"message\", (raw: RawData) => {\n let message: {\n action?: string;\n data?: { channel_id?: string; parent_id?: string; token?: string };\n seq?: number;\n };\n try {\n message = JSON.parse(raw.toString()) as typeof message;\n } catch {\n client.close(1003, \"invalid json\");\n return;\n }\n if (!isJsonObject(message)) {\n client.close(1003, \"invalid json\");\n return;\n }\n const seq = message.seq ?? 0;\n if (!params.state.websocketClients.has(client)) {\n if (!authenticationOpen || client.readyState !== WebSocket.OPEN) {\n return;\n }\n if (\n message.action !== \"authentication_challenge\" ||\n message.data?.token !== params.state.botToken\n ) {\n sendControlMessage(params.state, client, {\n error: { id: \"api.context.unauthorized\", message: \"Authentication failed\" },\n seq_reply: seq,\n status: \"FAIL\",\n });\n authenticationOpen = false;\n client.close(4001, \"authentication failed\");\n return;\n }\n clearTimeout(authenticationTimeout);\n authenticationOpen = false;\n unauthenticatedClients.delete(client);\n params.state.websocketClients.set(client, 0);\n sendControlMessage(params.state, client, { seq_reply: seq, status: \"OK\" });\n sendEvent(params.state, client, {\n broadcast: eventBroadcast({ userId: params.state.botUserId }),\n data: {\n connection_id: mattermostId(`connection-${Date.now()}-${Math.random()}`),\n server_version: \"crabline-mattermost.1\",\n },\n event: \"hello\",\n });\n const pending = params.state.pendingEvents.splice(0);\n for (const [index, event] of pending.entries()) {\n if (!sendEvent(params.state, client, event)) {\n params.state.pendingEvents.unshift(...pending.slice(index));\n break;\n }\n }\n return;\n }\n if (message.action === \"user_typing\") {\n const channelId = readTrimmedString(message.data?.channel_id);\n if (!channelId || !params.state.channels.has(channelId)) {\n sendControlMessage(params.state, client, {\n error: {\n id: \"api.channel.get.find.app_error\",\n message: \"Channel not found\",\n },\n seq_reply: seq,\n status: \"FAIL\",\n });\n return;\n }\n broadcast(\n params.state,\n {\n broadcast: eventBroadcast({\n channelId,\n omitUsers: { [params.state.botUserId]: true },\n }),\n data: {\n channel_id: channelId,\n parent_id: readTrimmedString(message.data?.parent_id) ?? \"\",\n user_id: params.state.botUserId,\n },\n event: \"typing\",\n },\n false,\n );\n sendControlMessage(params.state, client, { seq_reply: seq, status: \"OK\" });\n return;\n }\n if (message.action === \"ping\") {\n sendControlMessage(params.state, client, {\n data: { text: \"pong\" },\n seq_reply: seq,\n status: \"OK\",\n });\n return;\n }\n sendControlMessage(params.state, client, {\n error: { id: \"api.websocket.invalid_action\", message: \"Unsupported action\" },\n seq_reply: seq,\n status: \"FAIL\",\n });\n });\n client.once(\"close\", () => {\n authenticationOpen = false;\n clearTimeout(authenticationTimeout);\n unauthenticatedClients.delete(client);\n params.state.websocketClients.delete(client);\n });\n });\n return async () => {\n params.server.off(\"upgrade\", onUpgrade);\n await closeWebSocketServer(websocketServer);\n };\n}\n\nexport async function startMattermostServer(\n params: StartMattermostServerParams = {},\n): Promise<StartedMattermostServer> {\n const host = params.host ?? \"127.0.0.1\";\n const botUserId = params.botUserId ?? mattermostId(\"crabline-mattermost-bot\");\n const botUsername = params.botUsername ?? \"crabline_bot\";\n const maxWebSocketMessageBytes = resolvePositiveLimit(\n params.maxWebSocketMessageBytes,\n \"maxWebSocketMessageBytes\",\n DEFAULT_MAX_WEBSOCKET_MESSAGE_BYTES,\n );\n const maxUnauthenticatedWebSocketClients = resolvePositiveLimit(\n params.maxUnauthenticatedWebSocketClients,\n \"maxUnauthenticatedWebSocketClients\",\n DEFAULT_MAX_UNAUTHENTICATED_WEBSOCKET_CLIENTS,\n );\n const state: MattermostServerState = {\n adminToken: params.adminToken ?? randomBytes(24).toString(\"base64url\"),\n botToken:\n params.botToken ??\n (isLoopbackHost(host) ? \"crabline-mattermost-token\" : randomBytes(13).toString(\"hex\")),\n botUserId,\n botUsername,\n channels: new Map(),\n maxPendingInboundEvents: resolveMaxPendingInboundEvents(params.maxPendingInboundEvents),\n maxWebSocketBufferedBytes: resolvePositiveLimit(\n params.maxWebSocketBufferedBytes,\n \"maxWebSocketBufferedBytes\",\n DEFAULT_MAX_WEBSOCKET_BUFFERED_BYTES,\n ),\n nextPost: 1,\n onEvent: params.onEvent,\n pendingEvents: [],\n posts: new Map(),\n recorderPath: params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"mattermost.jsonl\"),\n users: new Map([[botUserId, { id: botUserId, update_at: Date.now(), username: botUsername }]]),\n websocketClients: new Map(),\n };\n const httpServer = await startHttpJsonServer({\n handle: (request) => handleRequest(request, state),\n handleError: (error) => {\n if (error instanceof InvalidJsonBodyError) {\n return mattermostError(\"Request body is not valid JSON\", 400);\n }\n if (error instanceof RequestBodyTooLargeError) {\n return mattermostError(\"Request body is too large\", 413);\n }\n return undefined;\n },\n host,\n port: params.port ?? 0,\n serverName: \"Mattermost\",\n });\n const closeMattermostWebSocketServer = attachWebSocketServer({\n authenticationTimeoutMs:\n params.websocketAuthenticationTimeoutMs ?? DEFAULT_WEBSOCKET_AUTHENTICATION_TIMEOUT_MS,\n maxMessageBytes: maxWebSocketMessageBytes,\n maxUnauthenticatedClients: maxUnauthenticatedWebSocketClients,\n server: httpServer.server,\n state,\n });\n return {\n async close() {\n await closeMattermostWebSocketServer();\n await httpServer.close();\n },\n manifest: {\n adminToken: state.adminToken,\n baseUrl: httpServer.baseUrl,\n botToken: state.botToken,\n botUserId,\n endpoints: {\n adminInboundUrl: `${httpServer.baseUrl}/crabline/mattermost/inbound`,\n apiRoot: `${httpServer.baseUrl}/api/v4`,\n websocketUrl: `${httpServer.baseUrl.replace(/^http/u, \"ws\")}/api/v4/websocket`,\n },\n env: {\n MATTERMOST_BOT_TOKEN: state.botToken,\n MATTERMOST_URL: httpServer.baseUrl,\n },\n provider: \"mattermost\",\n recorderPath: state.recorderPath,\n version: 1,\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../src/servers/mattermost.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport path from \"node:path\";\nimport { WebSocket, WebSocketServer, type RawData } from \"ws\";\nimport {\n adminAuthError,\n constantTimeTokenEqual,\n drainRequestBody,\n hasAdminToken,\n InvalidJsonBodyError,\n isJsonObject,\n isJsonMediaType,\n isLoopbackHost,\n jsonResponse,\n parseUnknownRequestBody,\n queryRecord,\n RequestBodyTooLargeError,\n startHttpJsonServer,\n type ServerRequestEvent,\n} from \"./http.js\";\nimport {\n recordCommittedServerEvent,\n recordServerEvent,\n type ServerEventObserver,\n} from \"./recorder.js\";\nimport { resolveMaxPendingInboundEvents } from \"./pending-events.js\";\nimport { closeWebSocketServer } from \"./websocket.js\";\n\nconst DEFAULT_WEBSOCKET_AUTHENTICATION_TIMEOUT_MS = 5_000;\nconst DEFAULT_MAX_WEBSOCKET_BUFFERED_BYTES = 1024 * 1024;\nconst DEFAULT_MAX_WEBSOCKET_MESSAGE_BYTES = 64 * 1024;\nconst DEFAULT_MAX_UNAUTHENTICATED_WEBSOCKET_CLIENTS = 32;\nconst DEFAULT_MAX_COMMITTED_CHANNELS = 1_000;\nconst DEFAULT_MAX_COMMITTED_POSTS = 1_000;\nconst DEFAULT_MAX_COMMITTED_STATE_BYTES = 64 * 1024 * 1024;\nconst DEFAULT_MAX_COMMITTED_USERS = 1_000;\nconst DEFAULT_MAX_PENDING_INBOUND_BYTES = 64 * 1024 * 1024;\nconst MATTERMOST_ID_PATTERN = /^[a-z0-9]{26}(?![\\s\\S])/u;\nconst MATTERMOST_USERNAME_PATTERN = /^[a-z0-9._-]{1,64}$/u;\nconst MATTERMOST_CHANNEL_TYPES = new Set([\"D\", \"G\", \"O\", \"P\"]);\nconst MATTERMOST_RESTRICTED_USERNAMES = new Set([\"all\", \"channel\", \"matterbot\", \"system\"]);\n\nfunction resolvePositiveLimit(value: number | undefined, name: string, fallback: number): number {\n if (value === undefined) {\n return fallback;\n }\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new Error(`${name} must be a positive safe integer.`);\n }\n return value;\n}\n\ntype MattermostPost = {\n channel_id: string;\n create_at: number;\n delete_at: number;\n edit_at: number;\n id: string;\n message: string;\n root_id: string;\n type: string;\n update_at: number;\n user_id: string;\n};\n\ntype MattermostChannel = {\n display_name: string;\n id: string;\n name: string;\n type: string;\n};\n\ntype MattermostUser = {\n id: string;\n update_at: number;\n username: string;\n};\n\ntype MattermostWebSocketEvent = {\n broadcast: {\n channel_id: string;\n omit_users: null | Record<string, boolean>;\n team_id: string;\n user_id: string;\n };\n data: Record<string, unknown>;\n event: string;\n};\ntype MattermostRecorderEvent = ServerRequestEvent & {\n accepted?: boolean | undefined;\n};\n\ntype MattermostServerState = {\n adminToken: string;\n botToken: string;\n botUserId: string;\n botUsername: string;\n channels: Map<string, MattermostChannel>;\n committedStateBytes: number;\n maxCommittedChannels: number;\n maxCommittedPosts: number;\n maxCommittedStateBytes: number;\n maxCommittedUsers: number;\n maxPendingInboundBytes: number;\n maxPendingInboundEvents: number;\n maxWebSocketBufferedBytes: number;\n nextPost: number;\n onEvent: ServerEventObserver | undefined;\n pendingEventBytes: number;\n pendingEvents: MattermostWebSocketEvent[];\n posts: Map<string, MattermostPost>;\n recorderPath: string;\n userIdsByUsername: Map<string, string>;\n users: Map<string, MattermostUser>;\n websocketClients: Map<WebSocket, number>;\n};\n\nexport type MattermostServerManifest = {\n adminToken: string;\n baseUrl: string;\n botToken: string;\n botUserId: string;\n endpoints: {\n adminInboundUrl: string;\n apiRoot: string;\n websocketUrl: string;\n };\n env: {\n MATTERMOST_BOT_TOKEN: string;\n MATTERMOST_URL: string;\n };\n provider: \"mattermost\";\n recorderPath: string;\n version: 1;\n};\n\nexport type StartedMattermostServer = {\n close(): Promise<void>;\n manifest: MattermostServerManifest;\n};\n\nexport type StartMattermostServerParams = {\n adminToken?: string | undefined;\n botToken?: string | undefined;\n botUserId?: string | undefined;\n botUsername?: string | undefined;\n host?: string | undefined;\n onEvent?: ServerEventObserver | undefined;\n port?: number | undefined;\n recorderPath?: string | undefined;\n maxCommittedChannels?: number | undefined;\n maxCommittedPosts?: number | undefined;\n maxCommittedStateBytes?: number | undefined;\n maxCommittedUsers?: number | undefined;\n maxPendingInboundBytes?: number | undefined;\n maxPendingInboundEvents?: number | undefined;\n maxWebSocketBufferedBytes?: number | undefined;\n maxWebSocketMessageBytes?: number | undefined;\n maxUnauthenticatedWebSocketClients?: number | undefined;\n websocketAuthenticationTimeoutMs?: number | undefined;\n};\n\nexport function mattermostId(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 26);\n}\n\nasync function appendEvent(\n state: MattermostServerState,\n event: ServerRequestEvent,\n committed = false,\n): Promise<void> {\n const params = { event, onEvent: state.onEvent, recorderPath: state.recorderPath };\n await (committed ? recordCommittedServerEvent(params) : recordServerEvent(params));\n}\n\nfunction authorized(request: IncomingMessage, token: string): boolean {\n const providedToken = /^Bearer ([^\\s]+)$/iu.exec(request.headers.authorization ?? \"\")?.[1];\n return providedToken ? constantTimeTokenEqual(providedToken, token) : false;\n}\n\nfunction mattermostError(\n message: string,\n status: number,\n options: { id?: string; requestId?: string } = {},\n): Response {\n return jsonResponse(\n {\n detailed_error: \"\",\n id: options.id ?? `api.context.${status}.app_error`,\n message,\n request_id:\n options.requestId ??\n mattermostId(`request-${Date.now()}-${Math.random()}-${message}-${status}`),\n status_code: status,\n },\n status,\n );\n}\n\nfunction readMattermostString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction readMattermostMessage(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0 ? value : undefined;\n}\n\nfunction readMattermostId(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction isMattermostId(value: string): boolean {\n return MATTERMOST_ID_PATTERN.test(value);\n}\n\nfunction normalizeMattermostUsername(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value !== value.trim()) {\n return undefined;\n }\n const normalized = value.toLowerCase();\n return MATTERMOST_USERNAME_PATTERN.test(normalized) &&\n !MATTERMOST_RESTRICTED_USERNAMES.has(normalized)\n ? normalized\n : undefined;\n}\n\nfunction requestHasJsonMediaType(request: IncomingMessage): boolean {\n const contentType = request.headers[\"content-type\"];\n return Array.isArray(contentType)\n ? contentType.some(isJsonMediaType)\n : typeof contentType === \"string\" && isJsonMediaType(contentType);\n}\n\nfunction decodeMattermostPathSegment(value: string): string | Response {\n try {\n return decodeURIComponent(value);\n } catch {\n return mattermostError(\"Invalid path parameter\", 400);\n }\n}\n\nfunction eventBroadcast(params: {\n channelId?: string;\n omitUsers?: Record<string, boolean>;\n userId?: string;\n}): MattermostWebSocketEvent[\"broadcast\"] {\n return {\n channel_id: params.channelId ?? \"\",\n omit_users: params.omitUsers ?? null,\n team_id: \"\",\n user_id: params.userId ?? \"\",\n };\n}\n\nfunction postEvent(\n event: \"post_deleted\" | \"post_edited\" | \"posted\",\n post: MattermostPost,\n senderName: string,\n channel: MattermostChannel,\n): MattermostWebSocketEvent {\n return {\n event,\n data:\n event === \"posted\"\n ? {\n channel_display_name: channel.display_name,\n channel_name: channel.name,\n channel_type: channel.type,\n post: JSON.stringify(post),\n sender_name: senderName,\n set_online: true,\n team_id: \"\",\n }\n : { post: JSON.stringify(post) },\n broadcast: eventBroadcast({ channelId: post.channel_id }),\n };\n}\n\nfunction webSocketEventBytes(event: MattermostWebSocketEvent): number {\n return Buffer.byteLength(JSON.stringify({ ...event, seq: Number.MAX_SAFE_INTEGER }), \"utf8\");\n}\n\nfunction retainedValueBytes(value: unknown): number {\n const serialized = JSON.stringify(value);\n return serialized === undefined ? 0 : Buffer.byteLength(serialized, \"utf8\");\n}\n\nfunction retainedValueDelta(previous: unknown, next: unknown): number {\n return retainedValueBytes(next) - retainedValueBytes(previous);\n}\n\nfunction canRetainCommittedValues(\n state: MattermostServerState,\n replacements: ReadonlyArray<readonly [previous: unknown, next: unknown]>,\n): boolean {\n const delta = replacements.reduce(\n (total, [previous, next]) => total + retainedValueDelta(previous, next),\n 0,\n );\n return state.committedStateBytes + delta <= state.maxCommittedStateBytes;\n}\n\nfunction setCommittedValue<Key, Value>(\n state: MattermostServerState,\n values: Map<Key, Value>,\n key: Key,\n value: Value,\n): void {\n state.committedStateBytes += retainedValueDelta(values.get(key), value);\n values.set(key, value);\n}\n\nfunction deleteCommittedValue<Key, Value>(\n state: MattermostServerState,\n values: Map<Key, Value>,\n key: Key,\n): void {\n const previous = values.get(key);\n if (previous === undefined) {\n return;\n }\n state.committedStateBytes -= retainedValueBytes(previous);\n values.delete(key);\n}\n\nfunction sendEvent(\n state: MattermostServerState,\n client: WebSocket,\n event: MattermostWebSocketEvent,\n): boolean {\n const seq = state.websocketClients.get(client);\n if (seq === undefined || client.readyState !== WebSocket.OPEN) {\n state.websocketClients.delete(client);\n return false;\n }\n const payload = JSON.stringify({ ...event, seq });\n const payloadBytes = Buffer.byteLength(payload, \"utf8\");\n if (payloadBytes > state.maxWebSocketBufferedBytes) {\n return false;\n }\n if (client.bufferedAmount + payloadBytes > state.maxWebSocketBufferedBytes) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n return false;\n }\n try {\n client.send(payload);\n } catch {\n state.websocketClients.delete(client);\n client.terminate();\n return false;\n }\n state.websocketClients.set(client, seq + 1);\n return true;\n}\n\nfunction sendControlMessage(\n state: MattermostServerState,\n client: WebSocket,\n value: Record<string, unknown>,\n): boolean {\n if (client.readyState !== WebSocket.OPEN) {\n state.websocketClients.delete(client);\n return false;\n }\n const payload = JSON.stringify(value);\n if (\n client.bufferedAmount + Buffer.byteLength(payload, \"utf8\") >\n state.maxWebSocketBufferedBytes\n ) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n return false;\n }\n try {\n client.send(payload);\n return true;\n } catch {\n state.websocketClients.delete(client);\n client.terminate();\n return false;\n }\n}\n\nfunction broadcast(\n state: MattermostServerState,\n event: MattermostWebSocketEvent,\n queueIfUndelivered = true,\n): boolean {\n if (event.broadcast.omit_users?.[state.botUserId]) {\n return true;\n }\n if (webSocketEventBytes(event) > state.maxWebSocketBufferedBytes) {\n return false;\n }\n let delivered = false;\n for (const client of state.websocketClients.keys()) {\n delivered = sendEvent(state, client, event) || delivered;\n }\n if (delivered) {\n return true;\n }\n if (!queueIfUndelivered) {\n return false;\n }\n if (state.pendingEvents.length >= state.maxPendingInboundEvents) {\n return false;\n }\n const eventBytes = retainedValueBytes(event);\n if (state.pendingEventBytes + eventBytes > state.maxPendingInboundBytes) {\n return false;\n }\n state.pendingEvents.push(event);\n state.pendingEventBytes += eventBytes;\n return true;\n}\n\nfunction pendingQueueFullResponse(state: MattermostServerState): Response {\n return jsonResponse(\n {\n error: `Pending inbound queue is full (${state.maxPendingInboundEvents} events)`,\n ok: false,\n },\n 503,\n );\n}\n\nfunction committedStateFullResponse(resource: \"channels\" | \"posts\" | \"state\" | \"users\"): Response {\n return jsonResponse(\n {\n error: `Committed Mattermost ${resource} limit reached`,\n ok: false,\n },\n 503,\n );\n}\n\nfunction buildPost(params: {\n channelId: string;\n id: string;\n message: string;\n rootId?: string | undefined;\n userId: string;\n}): MattermostPost {\n const now = Date.now();\n return {\n channel_id: params.channelId,\n create_at: now,\n delete_at: 0,\n edit_at: 0,\n id: params.id,\n message: params.message,\n root_id: params.rootId ?? \"\",\n type: \"\",\n update_at: now,\n user_id: params.userId,\n };\n}\n\nfunction buildNextPost(\n state: MattermostServerState,\n params: Omit<Parameters<typeof buildPost>[0], \"id\">,\n reservedId?: string,\n): { nextPost: number; post: MattermostPost } {\n let nextPost = state.nextPost;\n let id: string;\n do {\n id = mattermostId(`post-${nextPost++}`);\n } while (id === reservedId || state.posts.has(id));\n return { nextPost, post: buildPost({ ...params, id }) };\n}\n\nfunction commitNextPost(\n state: MattermostServerState,\n pending: ReturnType<typeof buildNextPost>,\n): void {\n state.nextPost = pending.nextPost;\n setCommittedValue(state, state.posts, pending.post.id, pending.post);\n}\n\nfunction commitNextPostIfCapacity(\n state: MattermostServerState,\n pending: ReturnType<typeof buildNextPost>,\n): boolean {\n if (!canRetainCommittedValues(state, [[undefined, pending.post]])) {\n return false;\n }\n commitNextPost(state, pending);\n return true;\n}\n\nfunction nextDirectChannelId(state: MattermostServerState, seed: string): string {\n let collision = 0;\n let channelId: string;\n do {\n channelId = mattermostId(collision === 0 ? seed : `${seed}:${collision}`);\n collision += 1;\n } while (state.channels.has(channelId));\n return channelId;\n}\n\nfunction webSocketEventTooLargeResponse(): Response {\n return mattermostError(\"WebSocket event is too large\", 413);\n}\n\nfunction handleAdminInbound(params: {\n body: Record<string, unknown>;\n state: MattermostServerState;\n}): Response {\n for (const field of [\"senderName\", \"channelType\", \"rootId\", \"root_id\"] as const) {\n if (params.body[field] !== undefined && typeof params.body[field] !== \"string\") {\n return jsonResponse({ error: `${field} must be a string`, ok: false }, 400);\n }\n }\n const channelId = readMattermostId(params.body.channelId ?? params.body.channel_id);\n const senderId = readMattermostId(params.body.senderId ?? params.body.user_id);\n const text = readMattermostMessage(params.body.text ?? params.body.message);\n if (!channelId || !senderId || !text) {\n return jsonResponse({ error: \"channelId, senderId, and text are required\", ok: false }, 400);\n }\n if (!isMattermostId(channelId)) {\n return jsonResponse(\n { error: \"channelId must be a 26-character Mattermost ID\", ok: false },\n 400,\n );\n }\n if (!isMattermostId(senderId)) {\n return jsonResponse({ error: \"senderId must be a 26-character Mattermost ID\", ok: false }, 400);\n }\n const rootId = readMattermostId(params.body.rootId ?? params.body.root_id);\n if (rootId && !isMattermostId(rootId)) {\n return jsonResponse({ error: \"rootId must be a 26-character Mattermost ID\", ok: false }, 400);\n }\n for (const field of [\n \"channelName\",\n \"channel_name\",\n \"channelDisplayName\",\n \"channel_display_name\",\n ] as const) {\n if (params.body[field] !== undefined && typeof params.body[field] !== \"string\") {\n return jsonResponse({ error: `${field} must be a string`, ok: false }, 400);\n }\n }\n if (\n params.state.websocketClients.size === 0 &&\n params.state.pendingEvents.length >= params.state.maxPendingInboundEvents\n ) {\n return pendingQueueFullResponse(params.state);\n }\n const previousUser = params.state.users.get(senderId);\n const previousChannel = params.state.channels.get(channelId);\n const senderName =\n params.body.senderName === undefined\n ? (previousUser?.username ?? senderId)\n : normalizeMattermostUsername(params.body.senderName);\n if (!senderName) {\n return jsonResponse(\n { error: \"senderName must be a valid Mattermost username\", ok: false },\n 400,\n );\n }\n if (senderId === params.state.botUserId && senderName !== params.state.botUsername) {\n return jsonResponse(\n { error: \"senderName must match the configured bot username\", ok: false },\n 400,\n );\n }\n const usernameOwner = params.state.userIdsByUsername.get(senderName);\n if (usernameOwner && usernameOwner !== senderId) {\n return jsonResponse({ error: \"senderName is already in use\", ok: false }, 400);\n }\n const channelType =\n params.body.channelType === undefined\n ? (previousChannel?.type ?? \"D\")\n : readMattermostString(params.body.channelType);\n if (!channelType || !MATTERMOST_CHANNEL_TYPES.has(channelType)) {\n return jsonResponse({ error: \"channelType is not supported\", ok: false }, 400);\n }\n const channelName =\n readMattermostString(params.body.channelName ?? params.body.channel_name) ??\n previousChannel?.name ??\n channelId;\n const channelDisplayName =\n readMattermostString(params.body.channelDisplayName ?? params.body.channel_display_name) ??\n previousChannel?.display_name ??\n channelName;\n const channel = {\n display_name: channelDisplayName,\n id: channelId,\n name: channelName,\n type: channelType,\n };\n const existingRoot = rootId ? params.state.posts.get(rootId) : undefined;\n if (existingRoot && existingRoot.channel_id !== channelId) {\n return jsonResponse({ error: \"Root post belongs to another channel\", ok: false }, 400);\n }\n if (existingRoot?.root_id) {\n return jsonResponse({ error: \"Root post is itself a reply\", ok: false }, 400);\n }\n if (!previousUser && params.state.users.size >= params.state.maxCommittedUsers) {\n return committedStateFullResponse(\"users\");\n }\n if (!previousChannel && params.state.channels.size >= params.state.maxCommittedChannels) {\n return committedStateFullResponse(\"channels\");\n }\n // buildNextPost always allocates a fresh ID, including against a synthesized root.\n const requiredPostSlots = 1 + (rootId && !existingRoot ? 1 : 0);\n if (params.state.posts.size + requiredPostSlots > params.state.maxCommittedPosts) {\n return committedStateFullResponse(\"posts\");\n }\n const rootPost =\n rootId && !existingRoot\n ? buildPost({\n channelId,\n id: rootId,\n message: \"\",\n userId: senderId,\n })\n : undefined;\n const pendingPost = buildNextPost(\n params.state,\n {\n channelId,\n message: text,\n rootId,\n userId: senderId,\n },\n rootPost?.id,\n );\n const { post } = pendingPost;\n const user = { id: senderId, update_at: Date.now(), username: senderName };\n if (\n !canRetainCommittedValues(params.state, [\n [previousUser, user],\n [previousChannel, channel],\n [undefined, rootPost],\n [undefined, post],\n ])\n ) {\n return committedStateFullResponse(\"state\");\n }\n const event = postEvent(\"posted\", post, senderName, channel);\n if (webSocketEventBytes(event) > params.state.maxWebSocketBufferedBytes) {\n return jsonResponse({ error: \"Inbound event is too large\", ok: false }, 413);\n }\n const previousNextPost = params.state.nextPost;\n if (previousUser?.username !== senderName) {\n params.state.userIdsByUsername.delete(previousUser?.username ?? \"\");\n }\n params.state.userIdsByUsername.set(senderName, senderId);\n setCommittedValue(params.state, params.state.users, senderId, user);\n setCommittedValue(params.state, params.state.channels, channelId, channel);\n if (rootPost) {\n setCommittedValue(params.state, params.state.posts, rootPost.id, rootPost);\n }\n commitNextPost(params.state, pendingPost);\n const rollback = () => {\n deleteCommittedValue(params.state, params.state.posts, post.id);\n if (rootPost) {\n deleteCommittedValue(params.state, params.state.posts, rootPost.id);\n }\n params.state.nextPost = previousNextPost;\n if (previousUser) {\n setCommittedValue(params.state, params.state.users, senderId, previousUser);\n params.state.userIdsByUsername.set(previousUser.username, senderId);\n } else {\n deleteCommittedValue(params.state, params.state.users, senderId);\n }\n if (previousUser?.username !== senderName) {\n params.state.userIdsByUsername.delete(senderName);\n }\n if (previousChannel) {\n setCommittedValue(params.state, params.state.channels, channelId, previousChannel);\n } else {\n deleteCommittedValue(params.state, params.state.channels, channelId);\n }\n };\n if (!broadcast(params.state, event)) {\n rollback();\n return pendingQueueFullResponse(params.state);\n }\n return jsonResponse({ ok: true, post });\n}\n\nasync function handleApi(params: {\n body: unknown;\n method: string;\n path: string;\n state: MattermostServerState;\n}): Promise<Response> {\n const { body, method, path: apiPath, state } = params;\n if (method === \"GET\" && apiPath === \"/users/me\") {\n return jsonResponse(state.users.get(state.botUserId));\n }\n const usernameMatch = /^\\/users\\/username\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && usernameMatch?.[1]) {\n const username = decodeMattermostPathSegment(usernameMatch[1]);\n if (username instanceof Response) {\n return username;\n }\n const userId = state.userIdsByUsername.get(username.toLowerCase());\n const user = userId ? state.users.get(userId) : undefined;\n return user ? jsonResponse(user) : mattermostError(\"User not found\", 404);\n }\n const userMatch = /^\\/users\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && userMatch?.[1]) {\n const user = state.users.get(userMatch[1]);\n return user ? jsonResponse(user) : mattermostError(\"User not found\", 404);\n }\n const channelMatch = /^\\/channels\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && channelMatch?.[1]) {\n const channel = state.channels.get(channelMatch[1]);\n return channel ? jsonResponse(channel) : mattermostError(\"Channel not found\", 404);\n }\n if (method === \"POST\" && apiPath === \"/channels/direct\") {\n const userIds = Array.isArray(body) ? body.map(readMattermostId) : [];\n if (userIds.length !== 2 || userIds.some((value) => !value)) {\n return mattermostError(\"Two user IDs are required\", 400);\n }\n const [firstUserId, secondUserId] = userIds as [string, string];\n if (firstUserId === secondUserId) {\n return mattermostError(\"Direct channel users must be distinct\", 400);\n }\n if (!state.users.has(firstUserId) || !state.users.has(secondUserId)) {\n return mattermostError(\"User not found\", 404);\n }\n if (firstUserId !== state.botUserId && secondUserId !== state.botUserId) {\n return mattermostError(\"Authenticated user must belong to the direct channel\", 403);\n }\n const participantIds = [...userIds].sort();\n const channelName = participantIds.join(\"__\");\n const existingChannel = [...state.channels.values()].find(\n (channel) => channel.type === \"D\" && channel.name === channelName,\n );\n if (existingChannel) {\n return jsonResponse(existingChannel, 201);\n }\n if (state.channels.size >= state.maxCommittedChannels) {\n return mattermostError(\"Too many retained channels\", 503);\n }\n const channelId = nextDirectChannelId(state, `dm:${participantIds.join(\":\")}`);\n const channel = { display_name: \"\", id: channelId, name: channelName, type: \"D\" };\n if (!canRetainCommittedValues(state, [[undefined, channel]])) {\n return mattermostError(\"Too much retained state\", 503);\n }\n setCommittedValue(state, state.channels, channelId, channel);\n return jsonResponse(channel, 201);\n }\n if (!isJsonObject(body)) {\n return mattermostError(\"Request body must be a JSON object\", 400);\n }\n if (method === \"POST\" && apiPath === \"/users/me/typing\") {\n const channelId = readMattermostId(body.channel_id);\n if (!channelId) {\n return mattermostError(\"channel_id is required\", 400);\n }\n if (body.parent_id !== undefined && typeof body.parent_id !== \"string\") {\n return mattermostError(\"parent_id must be a string\", 400);\n }\n if (!state.channels.has(channelId)) {\n return mattermostError(\"Channel not found\", 404);\n }\n const parentId = readMattermostId(body.parent_id);\n broadcast(\n state,\n {\n broadcast: eventBroadcast({\n channelId,\n omitUsers: { [state.botUserId]: true },\n }),\n data: {\n channel_id: channelId,\n ...(parentId ? { parent_id: parentId } : {}),\n user_id: state.botUserId,\n },\n event: \"typing\",\n },\n false,\n );\n return jsonResponse({ status: \"OK\" });\n }\n if (method === \"POST\" && apiPath === \"/posts\") {\n const channelId = readMattermostId(body.channel_id);\n const message = readMattermostMessage(body.message);\n if (!channelId || !message) {\n return mattermostError(\"channel_id and message are required\", 400);\n }\n const rootId = readMattermostId(body.root_id);\n if (body.root_id !== undefined && typeof body.root_id !== \"string\") {\n return mattermostError(\"root_id must be a string\", 400);\n }\n const channel = state.channels.get(channelId);\n if (!channel) {\n return mattermostError(\"Channel not found\", 404);\n }\n if (rootId) {\n const rootPost = state.posts.get(rootId);\n if (!rootPost) {\n return mattermostError(\"Root post not found\", 404);\n }\n if (rootPost.channel_id !== channelId) {\n return mattermostError(\"Root post belongs to another channel\", 400);\n }\n if (rootPost.root_id) {\n return mattermostError(\"Root post is itself a reply\", 400);\n }\n }\n if (state.posts.size >= state.maxCommittedPosts) {\n return mattermostError(\"Too many retained posts\", 503);\n }\n const pendingPost = buildNextPost(state, {\n channelId,\n message,\n rootId,\n userId: state.botUserId,\n });\n const { post } = pendingPost;\n if (!commitNextPostIfCapacity(state, pendingPost)) {\n return mattermostError(\"Too much retained state\", 503);\n }\n const event = postEvent(\"posted\", post, state.botUsername, channel);\n broadcast(state, event, false);\n return jsonResponse(post, 201);\n }\n const postMatch = /^\\/posts\\/([^/]+)$/u.exec(apiPath);\n if (postMatch?.[1] && method === \"PUT\") {\n const post = state.posts.get(postMatch[1]);\n if (!post) {\n return mattermostError(\"Post not found\", 404);\n }\n if (post.user_id !== state.botUserId) {\n return mattermostError(\"You do not have permission to edit this post\", 403);\n }\n const message = body.message === undefined ? post.message : readMattermostMessage(body.message);\n if (!message) {\n return mattermostError(\"message must be a string\", 400);\n }\n const editedAt = Math.max(Date.now(), post.update_at + 1);\n const updated = { ...post, edit_at: editedAt, message, update_at: editedAt };\n if (!canRetainCommittedValues(state, [[post, updated]])) {\n return mattermostError(\"Too much retained state\", 503);\n }\n const event = postEvent(\n \"post_edited\",\n updated,\n state.botUsername,\n state.channels.get(updated.channel_id)!,\n );\n if (webSocketEventBytes(event) > state.maxWebSocketBufferedBytes) {\n return webSocketEventTooLargeResponse();\n }\n setCommittedValue(state, state.posts, updated.id, updated);\n broadcast(state, event, false);\n return jsonResponse(updated);\n }\n if (postMatch?.[1] && method === \"DELETE\") {\n const post = state.posts.get(postMatch[1]);\n if (!post) {\n return mattermostError(\"Post not found\", 404);\n }\n if (post.user_id !== state.botUserId) {\n return mattermostError(\"You do not have permission to delete this post\", 403);\n }\n const deletedAt = Math.max(Date.now(), post.update_at + 1);\n const deletedPost = { ...post, delete_at: deletedAt, update_at: deletedAt };\n const event = postEvent(\n \"post_deleted\",\n deletedPost,\n state.botUsername,\n state.channels.get(deletedPost.channel_id)!,\n );\n if (webSocketEventBytes(event) > state.maxWebSocketBufferedBytes) {\n return webSocketEventTooLargeResponse();\n }\n deleteCommittedValue(state, state.posts, post.id);\n broadcast(state, event, false);\n return jsonResponse({ status: \"OK\" });\n }\n return mattermostError(\"Not found\", 404);\n}\n\nasync function handleRequest(request: IncomingMessage, state: MattermostServerState) {\n const url = new URL(request.url ?? \"/\", \"http://localhost\");\n const method = request.method ?? \"GET\";\n const requestId = mattermostId(`request-${Date.now()}-${Math.random()}`);\n if (url.pathname === \"/crabline/mattermost/inbound\" && method === \"POST\") {\n if (!hasAdminToken(request, state.adminToken)) {\n drainRequestBody(request);\n return adminAuthError();\n }\n const body = await parseUnknownRequestBody(request);\n if (!isJsonObject(body)) {\n return jsonResponse({ error: \"Request body must be a JSON object\", ok: false }, 400);\n }\n await appendEvent(state, {\n at: new Date().toISOString(),\n body,\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"admin\",\n });\n return handleAdminInbound({ body, state });\n }\n if (url.pathname !== \"/api/v4\" && !url.pathname.startsWith(\"/api/v4/\")) {\n drainRequestBody(request);\n return mattermostError(\"Sorry, we could not find the page.\", 404, {\n id: \"api.context.404.app_error\",\n requestId,\n });\n }\n if (!authorized(request, state.botToken)) {\n drainRequestBody(request);\n return mattermostError(\"Invalid or expired session, please login again.\", 401, {\n id: \"api.context.session_expired.app_error\",\n requestId,\n });\n }\n const bodylessMethod = method === \"GET\" || method === \"DELETE\";\n if (bodylessMethod) {\n drainRequestBody(request);\n }\n const requiresJsonPost =\n method === \"POST\" && url.pathname === \"/api/v4/posts\" && !requestHasJsonMediaType(request);\n if (requiresJsonPost) {\n drainRequestBody(request);\n }\n const body = bodylessMethod || requiresJsonPost ? {} : await parseUnknownRequestBody(request);\n const event: MattermostRecorderEvent = {\n at: new Date().toISOString(),\n ...(typeof body === \"object\" && body !== null && Object.keys(body).length > 0 ? { body } : {}),\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"api\",\n };\n const response = requiresJsonPost\n ? mattermostError(\"Content-Type must be application/json.\", 415, {\n id: \"api.context.unsupported_content_type.app_error\",\n requestId,\n })\n : await handleApi({\n body,\n method,\n path: url.pathname.slice(\"/api/v4\".length),\n state,\n });\n if (method === \"POST\" && url.pathname === \"/api/v4/posts\") {\n event.accepted = response.status === 201;\n }\n event.accepted ??= response.ok;\n await appendEvent(state, event, response.ok && method !== \"GET\");\n return response;\n}\n\nfunction attachWebSocketServer(params: {\n authenticationTimeoutMs: number;\n maxMessageBytes: number;\n maxUnauthenticatedClients: number;\n state: MattermostServerState;\n server: import(\"node:http\").Server;\n}) {\n const websocketServer = new WebSocketServer({\n maxPayload: params.maxMessageBytes,\n noServer: true,\n });\n const unauthenticatedClients = new Set<WebSocket>();\n const onUpgrade = (\n request: IncomingMessage,\n socket: import(\"node:stream\").Duplex,\n head: Buffer,\n ) => {\n if (new URL(request.url ?? \"/\", \"http://localhost\").pathname !== \"/api/v4/websocket\") {\n socket.destroy();\n return;\n }\n websocketServer.handleUpgrade(request, socket, head, (client) => {\n websocketServer.emit(\"connection\", client, request);\n });\n };\n params.server.on(\"upgrade\", onUpgrade);\n websocketServer.on(\"connection\", (client) => {\n client.on(\"error\", () => {\n unauthenticatedClients.delete(client);\n params.state.websocketClients.delete(client);\n });\n if (unauthenticatedClients.size >= params.maxUnauthenticatedClients) {\n client.terminate();\n return;\n }\n unauthenticatedClients.add(client);\n let authenticationOpen = true;\n const authenticationTimeout = setTimeout(() => {\n authenticationOpen = false;\n client.close(4001, \"authentication timeout\");\n }, params.authenticationTimeoutMs);\n authenticationTimeout.unref();\n client.on(\"message\", (raw: RawData) => {\n let message: {\n action?: string;\n data?: { channel_id?: string; parent_id?: string; token?: string };\n seq?: number;\n };\n try {\n message = JSON.parse(raw.toString()) as typeof message;\n } catch {\n client.close(1003, \"invalid json\");\n return;\n }\n if (!isJsonObject(message)) {\n client.close(1003, \"invalid json\");\n return;\n }\n const seq = message.seq ?? 0;\n if (!params.state.websocketClients.has(client)) {\n if (!authenticationOpen || client.readyState !== WebSocket.OPEN) {\n return;\n }\n if (\n message.action !== \"authentication_challenge\" ||\n typeof message.data?.token !== \"string\" ||\n !constantTimeTokenEqual(message.data.token, params.state.botToken)\n ) {\n sendControlMessage(params.state, client, {\n error: { id: \"api.context.unauthorized\", message: \"Authentication failed\" },\n seq_reply: seq,\n status: \"FAIL\",\n });\n authenticationOpen = false;\n client.close(4001, \"authentication failed\");\n return;\n }\n clearTimeout(authenticationTimeout);\n authenticationOpen = false;\n unauthenticatedClients.delete(client);\n params.state.websocketClients.set(client, 0);\n sendControlMessage(params.state, client, { seq_reply: seq, status: \"OK\" });\n sendEvent(params.state, client, {\n broadcast: eventBroadcast({ userId: params.state.botUserId }),\n data: {\n connection_id: mattermostId(`connection-${Date.now()}-${Math.random()}`),\n server_version: \"crabline-mattermost.1\",\n },\n event: \"hello\",\n });\n const pending = params.state.pendingEvents.splice(0);\n params.state.pendingEventBytes = 0;\n for (const [index, event] of pending.entries()) {\n if (!sendEvent(params.state, client, event)) {\n const remaining = pending.slice(index);\n params.state.pendingEvents.unshift(...remaining);\n params.state.pendingEventBytes = remaining.reduce(\n (total, queuedEvent) => total + retainedValueBytes(queuedEvent),\n 0,\n );\n break;\n }\n }\n return;\n }\n if (message.action === \"user_typing\") {\n const channelId = readMattermostId(message.data?.channel_id);\n if (!channelId || !params.state.channels.has(channelId)) {\n sendControlMessage(params.state, client, {\n error: {\n id: \"api.channel.get.find.app_error\",\n message: \"Channel not found\",\n },\n seq_reply: seq,\n status: \"FAIL\",\n });\n return;\n }\n broadcast(\n params.state,\n {\n broadcast: eventBroadcast({\n channelId,\n omitUsers: { [params.state.botUserId]: true },\n }),\n data: {\n channel_id: channelId,\n parent_id: readMattermostId(message.data?.parent_id) ?? \"\",\n user_id: params.state.botUserId,\n },\n event: \"typing\",\n },\n false,\n );\n sendControlMessage(params.state, client, { seq_reply: seq, status: \"OK\" });\n return;\n }\n if (message.action === \"ping\") {\n sendControlMessage(params.state, client, {\n data: { text: \"pong\" },\n seq_reply: seq,\n status: \"OK\",\n });\n return;\n }\n sendControlMessage(params.state, client, {\n error: { id: \"api.websocket.invalid_action\", message: \"Unsupported action\" },\n seq_reply: seq,\n status: \"FAIL\",\n });\n });\n client.once(\"close\", () => {\n authenticationOpen = false;\n clearTimeout(authenticationTimeout);\n unauthenticatedClients.delete(client);\n params.state.websocketClients.delete(client);\n });\n });\n return async () => {\n params.server.off(\"upgrade\", onUpgrade);\n await closeWebSocketServer(websocketServer);\n };\n}\n\nexport async function startMattermostServer(\n params: StartMattermostServerParams = {},\n): Promise<StartedMattermostServer> {\n const host = params.host ?? \"127.0.0.1\";\n const botUserId = params.botUserId ?? mattermostId(\"crabline-mattermost-bot\");\n const botUsername = normalizeMattermostUsername(params.botUsername ?? \"crabline_bot\");\n if (!botUsername) {\n throw new Error(\"botUsername must be a valid Mattermost username.\");\n }\n const maxWebSocketMessageBytes = resolvePositiveLimit(\n params.maxWebSocketMessageBytes,\n \"maxWebSocketMessageBytes\",\n DEFAULT_MAX_WEBSOCKET_MESSAGE_BYTES,\n );\n const maxUnauthenticatedWebSocketClients = resolvePositiveLimit(\n params.maxUnauthenticatedWebSocketClients,\n \"maxUnauthenticatedWebSocketClients\",\n DEFAULT_MAX_UNAUTHENTICATED_WEBSOCKET_CLIENTS,\n );\n const maxCommittedStateBytes = resolvePositiveLimit(\n params.maxCommittedStateBytes,\n \"maxCommittedStateBytes\",\n DEFAULT_MAX_COMMITTED_STATE_BYTES,\n );\n const botUser = { id: botUserId, update_at: Date.now(), username: botUsername };\n const initialCommittedStateBytes = retainedValueBytes(botUser);\n if (initialCommittedStateBytes > maxCommittedStateBytes) {\n throw new Error(\"maxCommittedStateBytes cannot retain the configured bot user.\");\n }\n const state: MattermostServerState = {\n adminToken: params.adminToken ?? randomBytes(24).toString(\"base64url\"),\n botToken:\n params.botToken ??\n (isLoopbackHost(host) ? \"crabline-mattermost-token\" : randomBytes(13).toString(\"hex\")),\n botUserId,\n botUsername,\n channels: new Map(),\n committedStateBytes: initialCommittedStateBytes,\n maxCommittedChannels: resolvePositiveLimit(\n params.maxCommittedChannels,\n \"maxCommittedChannels\",\n DEFAULT_MAX_COMMITTED_CHANNELS,\n ),\n maxCommittedPosts: resolvePositiveLimit(\n params.maxCommittedPosts,\n \"maxCommittedPosts\",\n DEFAULT_MAX_COMMITTED_POSTS,\n ),\n maxCommittedStateBytes,\n maxCommittedUsers: resolvePositiveLimit(\n params.maxCommittedUsers,\n \"maxCommittedUsers\",\n DEFAULT_MAX_COMMITTED_USERS,\n ),\n maxPendingInboundBytes: resolvePositiveLimit(\n params.maxPendingInboundBytes,\n \"maxPendingInboundBytes\",\n DEFAULT_MAX_PENDING_INBOUND_BYTES,\n ),\n maxPendingInboundEvents: resolveMaxPendingInboundEvents(params.maxPendingInboundEvents),\n maxWebSocketBufferedBytes: resolvePositiveLimit(\n params.maxWebSocketBufferedBytes,\n \"maxWebSocketBufferedBytes\",\n DEFAULT_MAX_WEBSOCKET_BUFFERED_BYTES,\n ),\n nextPost: 1,\n onEvent: params.onEvent,\n pendingEventBytes: 0,\n pendingEvents: [],\n posts: new Map(),\n recorderPath: params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"mattermost.jsonl\"),\n userIdsByUsername: new Map([[botUsername, botUserId]]),\n users: new Map([[botUserId, botUser]]),\n websocketClients: new Map(),\n };\n const httpServer = await startHttpJsonServer({\n handle: (request) => handleRequest(request, state),\n handleError: (error) => {\n if (error instanceof InvalidJsonBodyError) {\n return mattermostError(\"Request body is not valid JSON\", 400);\n }\n if (error instanceof RequestBodyTooLargeError) {\n return mattermostError(\"Request body is too large\", 413);\n }\n return undefined;\n },\n host,\n port: params.port ?? 0,\n serverName: \"Mattermost\",\n });\n const closeMattermostWebSocketServer = attachWebSocketServer({\n authenticationTimeoutMs:\n params.websocketAuthenticationTimeoutMs ?? DEFAULT_WEBSOCKET_AUTHENTICATION_TIMEOUT_MS,\n maxMessageBytes: maxWebSocketMessageBytes,\n maxUnauthenticatedClients: maxUnauthenticatedWebSocketClients,\n server: httpServer.server,\n state,\n });\n return {\n async close() {\n await closeMattermostWebSocketServer();\n await httpServer.close();\n },\n manifest: {\n adminToken: state.adminToken,\n baseUrl: httpServer.baseUrl,\n botToken: state.botToken,\n botUserId,\n endpoints: {\n adminInboundUrl: `${httpServer.baseUrl}/crabline/mattermost/inbound`,\n apiRoot: `${httpServer.baseUrl}/api/v4`,\n websocketUrl: `${httpServer.baseUrl.replace(/^http/u, \"ws\")}/api/v4/websocket`,\n },\n env: {\n MATTERMOST_BOT_TOKEN: state.botToken,\n MATTERMOST_URL: httpServer.baseUrl,\n },\n provider: \"mattermost\",\n recorderPath: state.recorderPath,\n version: 1,\n },\n };\n}\n"]}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
import { type WindowsDirectorySecuritySnapshot } from "../platform/windows-acl.js";
|
|
1
2
|
import type { ServerRequestEvent } from "./http.js";
|
|
2
3
|
export type ServerEventObserver = (event: ServerRequestEvent) => void | Promise<void>;
|
|
4
|
+
export declare class ServerRecorderCommittedError extends AggregateError {
|
|
5
|
+
readonly committed = true;
|
|
6
|
+
readonly indeterminate: boolean;
|
|
7
|
+
constructor(filePath: string, operationError: unknown, relatedErrors?: unknown[], indeterminate?: boolean);
|
|
8
|
+
}
|
|
9
|
+
export declare function secureServerRecorderWindowsLockRoot(root: string, options?: {
|
|
10
|
+
createWindowsDirectory?: (directoryPath: string) => Promise<void>;
|
|
11
|
+
readWindowsDirectorySecuritySnapshot?: (directoryPath: string) => Promise<WindowsDirectorySecuritySnapshot>;
|
|
12
|
+
}): Promise<string>;
|
|
13
|
+
export declare function serverRecorderWindowsLockPath(root: string, filePath: string): string;
|
|
3
14
|
export declare function recordServerEvent(params: {
|
|
4
15
|
event: ServerRequestEvent;
|
|
5
16
|
onEvent: ServerEventObserver | undefined;
|