diff options
| author | JustZvan <justzvan@justzvan.xyz> | 2026-03-30 13:10:26 +0200 |
|---|---|---|
| committer | JustZvan <justzvan@justzvan.xyz> | 2026-03-30 13:10:26 +0200 |
| commit | 4f34bdf4de0d847591faa3e6981eafdf2b80a0b7 (patch) | |
| tree | f2dcb99cec464f0576a2f9815ce81afd866f485c /src/index.ts | |
| parent | 045c533fa3f5ff958829ea412cff647de1ebadcd (diff) | |
feat: add gallery scanning
Diffstat (limited to 'src/index.ts')
| -rw-r--r-- | src/index.ts | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/index.ts b/src/index.ts index 22c9024..2d4c114 100644 --- a/src/index.ts +++ b/src/index.ts @@ -552,6 +552,91 @@ app.ws("/kid/connect", (ws, req) => { return; } + if (data.type === "nsfw_image_detected") { + const deviceId = (ws as unknown as KidWebSocket).deviceId; + if (!deviceId) { + ws.send( + JSON.stringify({ success: false, reason: "Not authenticated" }), + ); + return; + } + + try { + const device = await db + .select() + .from(linkedDevices) + .where(eq(linkedDevices.id, deviceId)) + .limit(1); + + if (device.length === 0) { + logger.error({ deviceId }, "Device not found for nsfw image event"); + ws.send(JSON.stringify({ success: true })); + return; + } + + const parentId = device[0]!.parentId; + const deviceName = device[0]!.nickname; + + const parent = await db + .select({ pushTokens: users.pushTokens }) + .from(users) + .where(eq(users.id, parentId)) + .limit(1); + + if ( + parent.length > 0 && + parent[0]!.pushTokens && + parent[0]!.pushTokens.length > 0 + ) { + await pushNotificationQueue.add("nsfw-image-alert", { + pushTokens: parent[0]!.pushTokens, + notification: { + title: `⚠️ NSFW Image Detected`, + body: `An NSFW image was found on ${deviceName}`, + data: { + type: "nsfw_image_detected", + screen: "DeviceDetail", + deviceId: deviceId.toString(), + deviceName: deviceName, + }, + channelId: "alerts", + }, + }); + + await db.insert(alerts).values({ + deviceId: deviceId, + parentId: parentId, + category: "nsfw_image", + title: `NSFW Image Detected`, + message: `An NSFW image was found on ${deviceName}`, + summary: + "An image containing nudity or sexually explicit content was detected.", + confidence: 100, + packageName: (data.packageName as string) || "unknown", + timestamp: Math.floor(Date.now() / 1000), + read: false, + }); + + logger.info({ parentId, deviceId }, "NSFW image notification sent"); + } + + ws.send(JSON.stringify({ success: true })); + } catch (e) { + logger.error( + { error: e, deviceId }, + "Failed to process nsfw image event", + ); + ws.send( + JSON.stringify({ + success: false, + reason: "Failed to process nsfw image event", + }), + ); + } + + return; + } + logger.debug( { data, deviceId: (ws as unknown as KidWebSocket).deviceId }, "Unknown message type received", |