mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
feat(share-links): expose the frozen document set on the share view + OpenAPI
P3-1-T6. loadShareViewData now returns the link's document set as metadata only
(id, title, kind, documentDate, byteSize, servingClass) — scoped to the
membership rows, the owner, and live rows; the blob column is never selected
(the serve route is the only decrypt path). Register documentCount on the share
summary, documentIds on create, and the public /c/{token}/d/{id} serve route in
the OpenAPI contract; regenerate docs/api/openapi.yaml.
This commit is contained in:
1 parent
0885f331b0
commit
de84994a95
4 files changed
+240
-6
No files matched your search
+69
-2
@@ -998,8 +998,11 @@ paths:
|
||||
ONCE in the response. v1.18.7 also mints a passphrase second factor (returned once as `passphrase`, with
|
||||
`shareUrl` and a `qrUrl` carrying the passphrase in the URL fragment); a leaked URL without the passphrase
|
||||
cannot open the record. Every scope column (window, sections, FHIR resource types, API toggle) is frozen
|
||||
write-once. `expiresAt` is required and capped at 90 days. Auth via cookie or Bearer; rate-limited
|
||||
(`share-link:<userId>`, 20/h). Strict: unknown keys 422."
|
||||
write-once. v1.28 accepts an optional `documentIds` array (bounded ≤50): each id is validated as the caller's
|
||||
own live document and frozen onto the link at create (a foreign/deleted id → 422); the summary DTO then reports
|
||||
`documentCount`. A documents-only share (empty report sections + non-empty `documentIds`) is valid. `expiresAt`
|
||||
is required and capped at 90 days. Auth via cookie or Bearer; rate-limited (`share-link:<userId>`, 20/h).
|
||||
Strict: unknown keys 422."
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
@@ -1096,6 +1099,13 @@ paths:
|
||||
- MedicationAdministration
|
||||
allowFhirApi:
|
||||
type: boolean
|
||||
documentIds:
|
||||
maxItems: 50
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 64
|
||||
expiresAt:
|
||||
type: string
|
||||
format: date-time
|
||||
@@ -1204,6 +1214,57 @@ paths:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"422": *a3
|
||||
"429": *a4
|
||||
/c/{token}/d/{id}:
|
||||
get:
|
||||
tags:
|
||||
- Export
|
||||
summary: Serve a shared document blob (v1.28, public)
|
||||
description: "Anonymous, no-session share-scoped document serve route. The raw `hls_` share token in the path is the
|
||||
ONLY credential — never a session; it never elevates a normal authed route. Serves ONLY a document id present in
|
||||
the link's frozen `documentIds` set (a guessed / foreign / soft-deleted id → flat 404). A passphrase-protected
|
||||
link additionally requires the short-lived, token-scoped unlock cookie; revocation and expiry collapse to the
|
||||
same flat 404. The serving-class posture is identical to the owner `/api/documents/inbound/{id}/original` route:
|
||||
Class A (PDF/JPEG/PNG/WebP/GIF) inline with its true type, everything else `application/octet-stream` +
|
||||
`Content-Disposition: attachment` + `X-Content-Type-Options: nosniff`; `Cache-Control: private, no-store`.
|
||||
Images (JPEG/PNG/WebP) are EXIF/XMP/GPS-stripped at egress (the stored original is untouched);
|
||||
PDF/TIFF/HEIC/Office metadata passes through. Per-link rate-limited."
|
||||
parameters:
|
||||
- in: path
|
||||
name: token
|
||||
schema:
|
||||
type: string
|
||||
description: Raw `hls_` share token.
|
||||
required: true
|
||||
description: Raw `hls_` share token.
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
description: A document id on the link's frozen set.
|
||||
required: true
|
||||
description: A document id on the link's frozen set.
|
||||
responses:
|
||||
"200":
|
||||
description: The document bytes. Content-Type is the true stored type for Class A (inline) or `application/octet-stream`
|
||||
for Class B (attachment).
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
"404":
|
||||
description: Flat 404 for every miss class (unknown/revoked/expired token, locked passphrase gate, or an id not on the
|
||||
frozen set).
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"429":
|
||||
description: Per-link serve rate limit exceeded.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
/api/fhir/metadata:
|
||||
get:
|
||||
tags:
|
||||
@@ -12896,6 +12957,8 @@ components:
|
||||
type: boolean
|
||||
protected:
|
||||
type: boolean
|
||||
documentCount:
|
||||
type: number
|
||||
expiresAt:
|
||||
type: string
|
||||
createdAt:
|
||||
@@ -12933,6 +12996,7 @@ components:
|
||||
- resourceTypes
|
||||
- allowFhirApi
|
||||
- protected
|
||||
- documentCount
|
||||
- expiresAt
|
||||
- createdAt
|
||||
- revokedAt
|
||||
@@ -12985,6 +13049,8 @@ components:
|
||||
type: boolean
|
||||
protected:
|
||||
type: boolean
|
||||
documentCount:
|
||||
type: number
|
||||
expiresAt:
|
||||
type: string
|
||||
createdAt:
|
||||
@@ -13009,6 +13075,7 @@ components:
|
||||
- resourceTypes
|
||||
- allowFhirApi
|
||||
- protected
|
||||
- documentCount
|
||||
- expiresAt
|
||||
- createdAt
|
||||
- revokedAt
|
||||
|
||||
Reference in new issue
Block a user