Constant-time internal-auth secret compare (timing oracle)
Replace String.equals with MessageDigest.isEqual so response latency cannot leak the X-Internal-Auth shared secret byte-by-byte. Fleet-wide sweep of the copy-pa...
Constant-time internal-auth secret compare (timing oracle)
Replace String.equals with MessageDigest.isEqual so response latency cannot leak the X-Internal-Auth shared secret byte-by-byte. Fleet-wide sweep of the copy-pa...
Constant-time internal-auth secret compare (timing oracle)
Replace String.equals with MessageDigest.isEqual so response latency cannot leak the X-Internal-Auth shared secret byte-by-byte. Fleet-wide sweep of the copy-pa...
Recurring generation schedules UI
ScheduleManager: create/list/delete schedules (recipe + daily/weekly/monthly + hour/day + optional auto-post targets + caption); launched from Materials, gated ...
Scheduled generation — sweep runs recipes on a cadence
- CanvaScheduleController: CRUD for org schedules (recipe + cadence + hour/day + optional social targets), computes nextRunAt - CanvaGenerationService: headle...
CanvaSchedule entity + repo (recurring generation)
Org-scoped recurring schedule (recipe + cadence + optional social targets) with an atomic-claim query so a MediaService sweep runs each due schedule once.
Inline expandable Whisper transcript on softphone voicemail + call-history rows
Each recorded row (voicemail and call history) gets a 'Transcript' toggle that fetches the recording's Whisper transcript on demand and shows it inline, so memb...
Save + reuse autofill recipes
TemplateAutofill: "Saved recipes" chips load a template + prefilled mapping; "Save as recipe" persists the current template + field values org-wide. + canvaApi ...
Saved autofill recipes CRUD (org-scoped)
CanvaRecipeController: GET/POST /api/media/canva/recipes + DELETE /{id} — save/list/soft-delete a named brand-template + field mapping, scoped to the caller's o...
CanvaAutofillRecipe entity + repo (saved autofill recipes)
Org-shared named binding of a Canva brand template to field values (literal text or a Materials image), so stewards can re-run a standard data-merge.
/dev/shm 2Gi (headless Chrome needs >=2GB) + 6Gi mem limit
Jibri's 10-config init aborts with '/dev/shm must be at least 2GB' when shm is 512Mi, crash-looping the recorder. Bump the tmpfs to 2Gi and the memory limit to ...
Add Material ID field to create form, details page, and imports
Threads a nullable materialId (max 40) through the Lead type, leadsApi (create + update wire requests), and the shared leadFields system-field list — which driv...
Meet-secrets **************** for jibri recording ingest
Lets jibri finalize.sh authenticate its recording upload to MediaService; matches the cluster *** value MediaService validates against.
Give MediaService internal.auth.secret (mlos-internal-auth) for summary emails
MediaService -> EmailService /api/email/templates/send (meeting-summary) needs INTERNAL_AUTH_SECRET to match EmailService's internal.auth.secret.
Enterprise autofill UI — data-merge brand templates
TemplateAutofill: pick a Canva brand template, fill each field with literal text, an org/compliance token (NMLS #, Equal Housing disclosure, org name/phone/ web...
Enterprise autofill — data-merge brand templates
- CanvaApiClient: list brand templates (dataset=non_empty), get dataset, asset-upload jobs, create/get autofill jobs - CanvaController: GET /brand-templates, ...
Persist mapped Material ID on manual import + API intake
Both setDirectFieldOnCreateRequest switches lack a default case, so an unmapped systemFieldPath is silently dropped. Add a materialId case to the manual-import ...
Add Material ID field end-to-end in shared-lib
Adds a nullable, max-40-char materialId to the Lead entity (MATERIAL_ID VARCHAR(40)), registers it in LeadHistoryFieldRegistry (Profile category) so edits are a...
Social attach + email-a-material + public links
Distribution for marketing materials, built on the new signed public-URL seam. - materialsApi.publicLink(imgId) + /api/materials/link proxy - Materials: "Copy ...
Short-lived signed public URLs for marketing assets
Lets social providers (Meta) and email fetch a specific material for a bounded window without exposing the private imaging-materials bucket. - MaterialUrlSigne...
Include both desktops in every SSO token, deep-link to the chosen one
Each token carried only its own connection, so the browser's reused json session lacked the other one -> opening Windows after Linux gave 'connection does not e...
Route borrower submit through the pipeline so it fires **************** (audit #3)
patchLoanFile's borrower submit (DRAFT->APPLICATION_TAKEN) now calls **************** instead of a raw updateLoanFile status set, so the submit produces the has...
First-class borrower self-submit transition ****************
DRAFT→APPLICATION_TAKEN for a borrower (a loan party, not an operator, so no LOS_TAKE_APPLICATION). Routes through transition() with a scoped predicate that gra...
Delete + preview + import-file-to-Canva
- delete a material (gated on MANAGE_MATERIALS) with confirmation - click a thumbnail to preview it in a lightbox - "Import a file" turns a PDF/PPTX/image into ...
Import a file into Canva as an editable design
- **************** (binary design import) - CanvaController POST /imports (multipart) → create+poll import job → editor deep-link with correlation_state for r...
Shared TranscriptionService + generic endpoint; transcribe VOIP recordings
- Extract a reusable TranscriptionService (ffmpeg normalize -> whisper-asr) and a generic POST /api/conversion/transcribe endpoint, replacing the meet-specifi...
Transcript column on Recording + RecordingMetadata
Adds a TRANSCRIPT TEXT column to the Recording entity and threads a transcript through **************** (with backwards-compat constructors so existing 5- and 9...
Wrap recording upload so MediaService compiles
MinIOStorageService.upload throws a checked Exception that ingest() neither caught nor declared — build break on top of the isGuest fix. Wrap it and rethrow as ...
Verify return-nav JWT signature; tidy token refresh
- CanvaJwtVerifier: verify the correlation_jwt's Ed25519 signature against Canva's JWKS (/connect/keys), plus aud/exp/type; keys cached by kid. Return-nav n...
MeetingParticipant.isGuest() (was getGuest, won't compile); repoint transcribe to generic endpoint
MeetingParticipant exposes isGuest() (primitive boolean getter), not getGuest(). Also point the summary transcribe call at the shared /api/conversion/transcribe...
Make whisper-asr independently scalable (HPA, multi-node)
Remove the single-node pin and switch to a per-pod model cache so pods can schedule on any node, and add an HPA (min 1 / max 4, CPU 75%, deliberate scale-up giv...
Rebrand Guacamole client connection status text to KamoDesktop
Override **************** so the 'Connecting to Guacamole...' screen (and related status) reads KamoDesktop.
Correct Guacamole branding manifest version field
Manifest used guacManifestVersion:1.0; the bundled extensions use guacamoleVersion. The wrong field made Guacamole reject the branding extension ('Unable to rea...
Recording ingest, retention/quota, storage usage, summary pipeline
- MeetRecordingController: internal (X-Internal-Auth) ingest endpoint the jibri finalize.sh posts finished recordings to. - MeetRecordingService: uploads reco...
Sample vars for meeting-summary template preview
Adds a sampleVariables case for the new meeting-summary template so the steward preview UI renders realistic content.
Meeting-summary canonical template
Adds the "meeting-summary" transactional template (subject + branded HTML with {{roomName}} and raw {{summaryHtml}}) and registers it in CANONICAL_KEYS so it se...
Stop double-appending ?target in the SSO proxy route
forwardToApi already forwards the incoming query string, so passing the path with ?target= produced **************** -> target='linux?target=linux' -> 400 'Unkn...
Prosody moderator module, whisper-asr, jibri recording upload
- Meet-prosody: version-control the custom-plugins ConfigMap (captures the existing token_verification no-op override that was created out-of-band) and add ...
Recording transcription endpoint for post-meeting summaries
POST /api/conversion/meet/transcribe (X-Internal-Auth): normalizes an uploaded meeting recording to 16kHz mono WAV via a new additive FfmpegService helper, forw...
Calendar integration for scheduled meetings + real recording storage meter
- calendarIntegrationEnabled: when on, a scheduled clubhouse meeting is also added to the creator's calendar (via the existing calendar system) carrying the ...
MeetingRecording entity + repository for captured recordings
New MEETING_RECORDINGS table (org, meeting ref, room, MinIO bucket/object key, size, duration, captured/expiry timestamps, summary status) — the parent record f...
Alias ALL turbopack content-hashed externals, not just prisma
The prior fix only aliased @prisma/client-<hash>; the build also externalizes pg-<hash> (node-postgres, via @prisma/adapter-pg) under the same content-hashed sc...
Resolve session from X-***-Token header in CallerSessionResolver
The kamo-internal -> APIService BFF path forwards the session as the X-***-Token header, but the resolver only read the X-OTK attribute or the *** cookie — so B...
Marketing app, settings hub, Canva materials
Make Marketing a first-class org-enableable app and ship the Canva-powered Materials experience. App-enablement: - AppType.MARKETING mirror, Organization.isMar...
PatchLoanFile is no longer a status backdoor; unblocking a condition needs the underwrite right; clear cascades
**************** status changes are the pipeline state machine's job (POST /transitions enforces legal arrows + per-arrow role gate + open-blocking-condition ga...
Video poster-frame thumbnails for marketing materials
Canva MP4 exports (and any video upload) skip the Docs PDF path and get a single ffmpeg poster-frame thumbnail (_thumb_p0.png) instead of failing. - **********...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.