Email as paid add-ons, not included free
- KamoMail Hosting: $5/user/mo add-on on all plans - 3rd Party Email Integration: $2/user/mo add-on on all plans - Email hosting feature reverted to "Add-on" in...
Email as paid add-on, update all fallback pricing data
- KamoMail Hosting: $5/user/mo add-on (not free — liability concern) - 3rd Party Email Integration: $2/user/mo add-on - Updated calculator page fallback data (w...
Use 18DOFF promo code, update expiry to April 30, 2026
Reverted promo code from EARLYBIRD back to 18DOFF to match nav headers. Updated nav text from "Prelaunch" to "Early Bird" for consistency. Set offer expiry to 2...
Update fallback pricing data to match new production prices
The API returns 401 so the marketing site uses hardcoded fallback data. Updated all fallback plans, addons, bundles, and comparison table to match the new prici...
Add @Access(AccessType.FIELD) to Member to stop Hibernate mapping getMemberType() as a column
The previous fix (@Transient on the memberType field) was insufficient. Hibernate 6 was still discovering the public getMemberType() method via property scannin...
Show uploader name, widen date column, merge extension icon into file name
- Uploaded By: was always empty — field name was correct but backend never set createdByName; now resolved on the backend side - File Name column: prepend fil...
Resolve security_level SQL error caused by duplicate MEMBER_TYPE column in Hibernate 6
Member.java mapped MEMBER_TYPE both as @DiscriminatorColumn and as an explicit @Column field. Hibernate 6 selected the column twice in the parent table projecti...
Skip loading screen for file downloads in NavigationInterceptor
Blob URLs and links with the download attribute never cause page navigation, so the global click handler now returns early for these — preventing the "Loading K...
Surface save errors and revert optimistic update in email provider selector
When saving a non-configurable provider (KamoMail, ParentOrg, NotConfigured) failed, the error was set in state but never displayed in the list view, and the op...
Correct security_level column reference in login SQL
security_level is on the members table (m), not member_team_member (e). The wrong alias e.security_level caused the entire SQL to fail silently, so memberType w...
Restore team-member/member permission model for share dialog
Team members (memberType=TEAM_MEMBER) bypass all gates. Regular members are gated by SHARE_DOCS_* rights. Legacy sessions without memberType get temporary full ...
Allow any authenticated member to share documents
Remove role-based gate on share dialog — any logged-in member can share. The previous check required isTeamMember (from session memberType) or specific SHARE_DO...
Correct member name access in resolveAlias endpoint
member.getNameFirst() doesn't exist — name is on User.getName(). Use getMemberDisplayName() helper which correctly navigates the member -> user -> EmbNameFull p...
Import blake3 from blake3/browser to initialize WASM correctly
blake3/esm/browser requires manual WASM provisioning; blake3/browser does it automatically.
Add null safety checks in MemberRightsAppliedService and fix role save in MemberService
Gate Folder and Doc Type columns/fields on allowFolders and allowDocType
When folder or doc type features are disabled for an assoc type, hide the corresponding datagrid columns and upload form fields consistently.
Align upload fields with consistent MUI TextFields, always show folder and doc type
Replace raw <select> elements with MUI TextField select for consistent styling and alignment with the Description field. Folder and Doc Type fields are now alwa...
Remove auth requirement from backfill-thumbnails endpoint
This is an internal admin maintenance endpoint that needs to be callable from within the cluster without user authentication.
Accept all file types for upload, use server-side blacklist instead of whitelist
Replace hardcoded ACCEPTED_EXTENSIONS whitelist with server-provided extBlackList from assoc-config. All file types are now uploadable unless explicitly blackli...
Use RandomAccessReadBuffer instead of ByteArrayInputStream for PDFBox 3.x
**************** was removed in PDFBox 3.0 — use RandomAccessReadBuffer(byte[]) which implements RandomAccessRead.
Add esign repos to JPA repository scan so ESignTemplateRepository bean is found
DocsService was crashing on startup because ESignTemplateRepository lives in com.kamo.z.shared.esign.repos which wasn't included in the @EnableJpaRepositories s...
Use 24-hour window instead of UTC date for today's changelog count
The server runs in UTC, so at night in US timezones toISOString() returns tomorrow's date and no commits match. Using a 24h rolling window instead.
Force-dynamic on changelog API routes to prevent stale date caching
Next.js was statically caching these GET route handlers at build time, freezing new Date() to the build date so today's changelog count never updated.
Use systemDocsOnly flag for System Docs tab, show all docs in Original Docs
Original Docs tab now shows all docs for this org/assocType without filtering by assocObjectId. System Docs tab sends systemDocsOnly: true to only get docs with...
Use **************** for hasDesignVersion, add systemDocsOnly filter
hasDesignVersion now checks if an esign template exists with current_design_version > 0, instead of using isSigTemplate which is true for all uploads through th...
Default assocObjectId to current member ID for proper doc tab filtering
When no oid URL param is provided, Original Docs and Modified Docs tabs now query by the current member's ID, while System Docs queries with blank assocObjectId...
Add @JsonIgnoreProperties to UploadTemplateRequest to prevent hash null on unknown fields
The frontend sends accessLevel, description, folderId, docTypeId in the metadata JSON. Jackson was failing to parse the entire metadata object when encountering...
Raise annotation toolbar z-index to 1000 so it always renders above page elements
Place dropped field at ghost's exact visual position
Use active.rect.current.translated (the DragOverlay ghost's client rect) instead matches the translated rect, so the field now lands precisely where the user re...
Route all esig API calls through forwardToApi() to fix save failures
All 10 esig route handlers were pointing to ESIG_SERVICE_URL which resolves to a non-existent kamowsesig-service proxy. Replace every handler with forwardToApi(...
Replace upsertSigners with full delete+insert to handle frontend temp UUIDs
The frontend assigns temporary crypto.randomUUID() values to newly-added signers before any backend call. The previous upsert-by-uid logic would throw 404 for t...
Switch preview-banner-text to inline flow so changelog link sits on the same line
Correct rotated thumbnail positioning and restore rotation transform
Two bugs in ThumbnailCanvas: 1. Replaced `height: \`${displayAspect * 100}%\`` (percentage height on abs- positioned element — unreliable when containing bl...
Move scroll ownership from PdfCanvas to canvasContainerRef
PdfCanvas root Box previously had overflow-auto + h-full, making it its own scroll container. This meant: - scrollbarGutter: stable on canvasContainerRef had no...
Fit to Width calculates actual container width instead of resetting to zoom 1
Reads **************** (which accounts for the stable scrollbar gutter) and the page's natural width via **************** then computes fitZoom = (availableWidt...
Replace all hardcoded purple with var(--color-primary) on Settings & Signers page
Signers icon, icon background, count badge, Add Signer buttons, Add First Signer button, empty-state illustration tint, add-another hover, and the ALL_OF_TYPE s...
Remove fixed height and scroll bars from field properties panel
The panel had two vertical scrollbars: 1. DesignTab wrapper had height: 200 + overflowY: auto 2. FieldPropertiesPanel root had height: 200 + overflow: hidden, ...
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
