forked from akai/readest
0b18de0581
* feat(send): Send to Readest — multi-channel capture into your library A Send-to-Kindle equivalent: email, web-upload, share, or one-click capture books and articles into the cloud library; they sync to every device. Architecture (client-side processing): out-of-app channels drop a raw payload into a per-user send_inbox; Readest clients drain it through one shared ingestService.ingestFile(). The server never parses or converts. - ingestService.ingestFile() — channel-agnostic import orchestration extracted from library/page.tsx (DI-based, forceUpload support). - send_addresses / send_allowed_senders / send_inbox tables + RLS + 4 SECURITY DEFINER claim/lease RPCs (migration 012_send_to_readest.sql). - Conversion subsystem (DOCX/RTF/HTML/article/TXT -> EPUB) in a Web Worker. - send-email Cloudflare Email Worker; inbox-drainer controller + useInboxDrainer hook; /api/send/* routes. - Send to Readest settings panel: inbound address, approved-sender allowlist, recent activity, per-device drain toggle. - /send web page (file drop + article URL) + SSRF-guarded fetch-url proxy. - OS-shared files routed through ingestFile; Manifest V3 browser extension. Security: inbox state changes only via SECURITY DEFINER RPCs (clients get SELECT-only on send_inbox); approved-sender allowlist gates email; SSRF guard on the one server-side URL fetch; inbox payload signed URLs authorize against send_inbox.user_id. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: run format:check in the pre-push hook Biome format checking is fast (~0.4s), so gate pushes on it too — catches mis-formatted files that bypassed the staged-only pre-commit hook before they reach CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(send): address CodeQL security findings - ReDoS (senders.ts): the email regex had ambiguous quantifiers around the literal dot. Rewrote it linear-time (domain labels exclude '.') and cap the input at 254 chars. - XSS (convertToEpub.ts): run untrusted HTML through DOMPurify (sanitizeForParsing — keeps document structure) before DOMParser, so title extraction and Readability never parse executable markup. - SSRF (fetch-url.ts): harden the host guard — block bare single-label hostnames, IPv4-mapped IPv6, CGNAT/benchmark/multicast ranges, and the unspecified address. DNS rebinding stays a documented residual risk. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
1.2 KiB
YAML
51 lines
1.2 KiB
YAML
packages:
|
|
- apps/*
|
|
- apps/readest-app/workers/send-email
|
|
- packages/foliate-js
|
|
|
|
allowBuilds:
|
|
core-js: true
|
|
edgedriver: true
|
|
esbuild: true
|
|
geckodriver: true
|
|
protobufjs: true
|
|
sharp: true
|
|
workerd: true
|
|
|
|
onlyBuiltDependencies:
|
|
- sharp
|
|
|
|
patchedDependencies:
|
|
'@ai-sdk/provider-utils@3.0.25': patches/@ai-sdk__provider-utils@3.0.25.patch
|
|
'@ai-sdk/provider-utils@4.0.27': patches/@ai-sdk__provider-utils@4.0.27.patch
|
|
mdast-util-gfm-autolink-literal@2.0.1: patches/mdast-util-gfm-autolink-literal@2.0.1.patch
|
|
|
|
overrides:
|
|
glob: '>=11.1.0'
|
|
jws: '>=4.0.1'
|
|
vite: '>=7.3.2 <8'
|
|
srvx: '>=0.11.13'
|
|
rollup: '>=4.59.0'
|
|
undici: '>=7.24.0'
|
|
flatted: '>=3.4.2'
|
|
body-parser: '>=2.2.1'
|
|
dompurify: '>=3.4.0'
|
|
i18next-http-backend: '>=3.0.5'
|
|
picomatch: '>=4.0.4'
|
|
path-to-regexp: '>=8.4.0'
|
|
protobufjs: '>=7.5.5'
|
|
serialize-javascript: 7.0.5
|
|
fast-xml-parser: '>=5.7.0'
|
|
lodash: '>=4.18.0'
|
|
lodash-es: '>=4.18.0'
|
|
postcss: 8.5.14
|
|
basic-ftp: '>=5.3.0'
|
|
qs: '>=6.14.2'
|
|
'@babel/runtime': '>=7.26.10'
|
|
'@babel/helpers': '>=7.26.10'
|
|
mdast-util-gfm-autolink-literal: 2.0.1
|
|
uuid: '>=14.0.0'
|
|
ws: 8.20.1
|
|
'@emnapi/core': 1.8.1
|
|
'@emnapi/runtime': 1.8.1
|