Skip to content

Commit 58ffbc2

Browse files
committed
feat: secure document upload for educator KYC
Adds the upload step for educator verification documents (government ID, teaching/school certificate). The app previously had no document flow, and its only upload primitive posted to an unsigned Cloudinary preset that returns a public secure_url β€” acceptable for a course thumbnail, not for an identity document. Client pre-flight (lib/verification/documents/) - fileSignature.js reads the leading bytes of the File and identifies the real format, naming recognisably hostile payloads (MZ, ELF, ZIP, RAR, gzip, #!) - policy.js gates on declared MIME, size, and magic-byte agreement. A file that fails never reaches the network, so no signed target is requested for it. Upload path (lib/actions/educators/uploadDocument.js) - Requests a short-lived signed upload target from the backend, PUTs the bytes straight to it, then finalises to start server-side malware scanning - The signed PUT uses a bare axios client (withCredentials: false) so the user's bearer token never reaches the storage origin - Only { documentId, status, ... } is stored β€” never a URL UI - DocumentUpload.jsx: drag/drop, click-to-browse, camera capture, per-file progress, preview, replace, remove, and a scan-pending state resolving to accepted or rejected - Reachable at /educator-onboarding/documents; the liveness capture step now routes here on success Docs - docs/secure-document-upload.md - .env.example now states the unsigned Cloudinary preset is course media only Closes #172
1 parent 307b829 commit 58ffbc2

13 files changed

Lines changed: 2658 additions & 6 deletions

File tree

β€Ž.env.exampleβ€Ž

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ NEXT_PUBLIC_DONATION_WALLET=
1818

1919
# ─── Cloudinary ────────────────────────────────────
2020
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name
21-
# Cloudinary cloud name for unsigned uploads (required)
21+
# Cloudinary cloud name for unsigned uploads (required).
22+
# Unsigned uploads return a PUBLIC secure_url, so this path is for course
23+
# media only β€” thumbnails, previews, lesson video.
24+
# Verification documents (government ID, certificates) must NEVER go through
25+
# it. They upload to a private, short-lived signed URL issued by the backend;
26+
# see lib/actions/educators/uploadDocument.js.
2227

2328
# ─── Jitsi ─────────────────────────────────────────
2429
NEXT_PUBLIC_JITSI_DOMAIN=https://meet.jit.si

0 commit comments

Comments
Β (0)