feat(telemedicine): TURN rotation, chat-cache isolation, attachment validation, runtime response parsing - #1020
Merged
llinsss merged 1 commit intoAug 28, 2026
Conversation
… and response parsing - turnCredentialService: ephemeral coturn-style TURN credentials with embedded expiry, HMAC verification, rotation grace window, and a client manager that refreshes before expiry and recovers rejected sessions (closes DogStark#971) - telemedicineChatVault: per-account AES-256-GCM chat/attachment cache; logout and account switch destroy the key before purging so history never leaks to the next account (closes DogStark#972) - attachmentValidationService: magic-byte content sniffing, executable/script blocking, size + allowlist enforcement, quarantine of spoofed types, and safe sandboxed download headers (closes DogStark#973) - runtimeValidation: dependency-free schema parser returning typed validation failures; wired into telemedicine availability so malformed nested JSON no longer crashes screens (closes DogStark#974) - docs/TELEMEDICINE_SECURITY.md covering all four flows Tests: focused unit suites added for each module (node env, synthetic data only).
|
@willy-de7 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Security hardening for the telemedicine relay, chat cache, attachment pipeline
and mobile API response parsing. Four narrowly-scoped, dependency-free modules
(Node
crypto/Bufferonly,nodeJest environment) plus focused unitsuites and contributor docs.
Closes #971
Closes #972
Closes #973
Closes #974
#971 — TURN credential rotation and expiry
src/services/turnCredentialService.tsusername = <expiryUnix>:<principal>,credential = base64(HMAC-SHA1(sharedSecret, username)). No long-lived secretreaches a device; a leaked credential dies at its embedded expiry (default TTL
300s, clamped 30s–24h).
verifyTurnCredentialusestimingSafeEqualand accepts the previoussecret during a rotation grace window so rotating the shared secret never
drops an in-flight call.
TurnCredentialManagercaches one live credential, re-issues within a 60srefresh skew, coalesces concurrent fetches, and exposes
recoverExpiredSession()for the "relay rejected the session" path.#972 — Prevent telemedicine message history leakage on logout
src/services/telemedicineChatVault.tsAES-256-GCM ciphertext keyed by account id (chat bodies + attachment metadata).
logout()/switchAccount()destroy the key first, then purge thecache — an interrupted purge still fails closed because leftover ciphertext is
unreadable.
readHistory()returns[]when no key is present, so a newly signed-inaccount can never read the previous account's cached history.
SecureKeystore/CacheStoreseams;InMemoryStoreprovided fortests.
#973 — Attachment malware and content-type validation for chat
src/services/attachmentValidationService.tssniffContentTypeidentifies files by magic bytes;looksExecutableblocksPE / ELF / Mach-O / Java class / shell scripts /
<script/<?php.validateAttachmentenforcesMAX_ATTACHMENT_BYTES(15 MiB) and an allowlist(
png/jpeg/gif/webp/pdf/plain), rejects empty files, and quarantinesdeclared-vs-detected type mismatches and disguised executables.
safeDownloadHeadersreturnsContent-Disposition: attachment,X-Content-Type-Options: nosniff,Content-Security-Policy: default-src 'none'; sandbox,Cache-Control: private, no-store.[\w.-]only, 128-char cap).#974 — Runtime response validation for mobile API services
src/services/runtimeValidation.tsv.object/array/string/number/boolean/literal/optional)with
.parse()→{ success, data } | { success:false, issues }; rejectsnull, wrong types,NaN/Infinity, and array/object confusion withpath-tagged issues.
parseResponse(schema, data, context)throws a singleResponseValidationErrorcarrying every issue instead of letting malformednested JSON crash a screen.
telemedicineService.getTelemedicineAvailability; the patternextends to the remaining
src/servicescalls incrementally.Tests
New unit suites (synthetic data only, no secrets/tokens/health data in
fixtures or logs):
src/services/__tests__/turnCredentialService.test.ts— issue, TTL clamping,HMAC verify/tamper/expiry, rotation grace window, manager caching + refresh +
expired-session recovery + fetch coalescing.
src/services/__tests__/telemedicineChatVault.test.ts— encrypted round-trip,ciphertext-not-plaintext at rest,
[]after logout, account-switch isolation,key-before-cache teardown on interrupted purge, idempotent logout.
src/services/__tests__/attachmentValidationService.test.ts— magic-bytesniffing, executable/script detection, filename sanitising, type-spoof and
disguised-executable quarantine, size/empty limits, safe headers.
src/services/__tests__/runtimeValidation.test.ts— happy path, malformednested data yields typed issues (no throw), optional handling, type guards,
parseResponseaggregate error.Platform
Pure TypeScript, no native modules — iOS and Android behave identically.
Injectable keystore / cache / clock seams keep every flow testable without a
device. No UI changes.
Docs
docs/TELEMEDICINE_SECURITY.mddocuments all four flows.