Fix: vault now re-locks on every WordPress login/logout (no longer stays unlocked across sessions).
Fix: the Lock Vault button now locks immediately without a page refresh.
1.3.8
New — Memory Cards: keep an inventory of your SD/CF cards so you always know which ones are safe to reuse. Each card has a status — Ready, In Use, Backed Up, or Damaged — that advances automatically as you attach the card to a shoot and tick off backup and formatting. Manage your full card list from the new sidebar entry, or assign cards to a shoot right inside the Work editor. A card that is currently in use cannot be deleted by mistake.
Vault: added a recovery phrase so you can regain access if you forget your vault password (separate from the existing one-time recovery code used for a lost authenticator). After updating, unlock your vault and you will be offered to set one up — this is optional and re-encrypts nothing.
Vault: the unlock and setup screens now save credentials in your browser’s password manager under a dedicated “crm-vault” username, so the vault password is never confused with — or overwritten on top of — your WordPress login.
Vault: authenticator codes are now accepted within a ±60 second window, fixing spurious “invalid code” errors after the server or device clock drifts (e.g. after the machine sleeps).
Vault: the vault now auto-locks after 15 minutes of inactivity and silently re-opens on page refresh while it is unlocked.
Fix: the sidebar title now follows your site language instead of always appearing in English, and the sidebar lock button and version footer are tidier and easier to use.
i18n: Italian (it_IT) translation updated to 100%, including all the new Memory Cards and vault recovery-phrase wording.
Updating from 1.3.x is seamless: your vault, password, authenticator and encrypted data are unchanged. Just update and unlock as usual — there is no data migration and no required action.
1.3.7
i18n: Italian (it_IT) translation completed to 100% — added the vault recovery-code and payment-type strings that were previously untranslated, and corrected leftover pre-rebrand strings.
i18n: added a load_plugin_textdomain() fallback so bundled translations also load on WordPress 6.0–6.6.
1.3.6
WP.org compliance: the full React/Vite source is now bundled in the plugin under src/ (the compiled dist/ bundle is retained for runtime). The same source also remains publicly maintained at the GitHub repository. This satisfies both human-readable-source options in guideline 4.
Docs: expanded the Development section with build-tool instructions (Node.js 22, npm, Vite) and added a build guide at src/README.md.
1.3.5
WP.org compliance: plugin renamed to “Eleva CRM for Photographers”; slug changed to eleva-crm-for-photographers.
WP.org compliance: removed all Pro-gated code blocks (Work Owner, Collaborators, Taxable Price) from the free plugin. No locked features remain.
WP.org compliance: converted inline script/style tags in meta boxes to wp_add_inline_script / wp_add_inline_style.
Source: added Development section to readme.txt linking public GitHub source repository.
Admin menu position changed to auto (null) to avoid conflicting with core items.
1.3.4
Security: vault file download (GET /vault-download/{id}) ownership check now decodes the JSON file-list server-side and compares integers exactly. Previous LIKE-pattern matching covered only IDs in the first or last position of the array and missed mid-array entries; the new check is exact regardless of position.
Security: PBKDF2 iteration count for the vault key derivation raised from 100,000 to 600,000, aligning with OWASP 2023 guidance. Existing vaults remain unlockable; the new iteration count is applied to all derive_key() calls.
Security: customer search SQL filter (posts_search + posts_join) is now scoped to the _ftnc_people meta key only. Previously the JOIN spanned all postmeta rows for matched posts, an unnecessary surface that could grow as new meta keys were added.
WP.org compliance: removed the aggressive remove_all_actions() call on admin_notices hooks on the Fotonic SPA page. Admin notices still fire (so security/update warnings are not suppressed) and are only hidden visually inside the SPA viewport via scoped CSS.
Reliability: activator OpenSSL-missing path now passes the correct plugin slug to deactivate_plugins() so the main plugin is disabled cleanly when the extension is unavailable.
Performance: menu icon SVG is read from disk once per request and cached in a static property instead of being read on every add_menu() call.
i18n: added translators comments to sprintf/_n strings carrying %s/%d placeholders so translators have correct context.
1.3.3
Customer Works recap: the Customer edit page now shows a table of all linked works with title, date, services, total price, and payment status. Footer row shows work count, total price, paid total, and unpaid total.
REST GET /works now accepts a customer_id query parameter to filter works by customer.
i18n: Italian translations added for all new strings.
1.3.2
Calendar view is now included: the monthly calendar showing all scheduled works is available to all users.
Calendar locale fix: month names and event dates now display in the WordPress site language instead of the server/OS locale.
Vault description: Settings page now shows an explanation of the Vault feature — detailed when not yet configured, a short reminder when active.
UI: logo mark used as the WP Admin menu icon.
UI: Settings sidebar nav item right-side clipping fixed.
UI: Payment status filter dropdown in the Works list now sizes to full option text width.
Layout: WP admin footer hidden on the plugin page; SPA viewport height correctly fills the available space.
1.3.1
Security: vault session cookie upgraded from AES-256-CBC (unauthenticated) to AES-256-GCM. The GCM authentication tag means any tampered cookie is rejected outright rather than silently decrypted to garbage. Cookie format: base64(nonce[12] + auth-tag[16] + ciphertext[32]).
Security: deterministic encryption for searchable fields (email, phone) fixed. IV is now derived per-value via HMAC-SHA256(key, value), so different field values produce different IVs. Previously all deterministic ciphertexts shared the same IV, creating a ciphertext relationship leak.
Security: browser-side AES-GCM deterministic encryption (webcrypto.js) IV derivation fixed. IV now hashes key bytes concatenated with value bytes; previously only the key was hashed, producing the same IV for every value in a session.
Security: deterministic ciphertext format changed from bare base64 to v1d:base64(IV||CT), making the format unambiguous and correctly round-trippable through decrypt(). Email and phone fields that were previously stored with the broken format would silently return empty — now they decrypt correctly.
Security: vault REST permission callback now explicitly calls wp_verify_nonce() in addition to current_user_can(), closing a theoretical CSRF window on the REST API.
Security: vault file download endpoint (GET /vault-download/{id}) fixed to use exact JSON-token matching. The previous LIKE %id% pattern allowed attachment ID 1 to match work file arrays containing IDs 10 or 11.
Security: vault unlock, failed unlock, lock, and password-change events now write audit entries to the WordPress error log (user ID, remote IP, event name). Requires WP_DEBUG_LOG to be enabled.
Security: re-encryption of email/phone fields during vault password change now uses deterministic decryption instead of standard decryption, ensuring those fields are correctly re-encrypted after a password change.
Security: price_override and installment amounts are clamped to max(0.0, value), preventing negative price injection via the REST API.
Security: vault password minimum length (12 characters) enforced server-side on both setup and change-password endpoints.
CI: workflow-level permissions: {} deny-all added to deploy.yml; the build job overrides with contents: read only, reducing GITHUB_TOKEN blast radius.
Maintenance: added uninstall.php for complete data cleanup (CPT posts, postmeta, taxonomy terms, options, transients, vault upload directory) on plugin deletion — required for WordPress.org approval.
Distribution: excluded developer-only files (CLAUDE.md, README.md, CHANGELOG.md, SUBMISSION-GUIDE.md) from plugin ZIP via .distignore.
1.3.0
Security: vault setup endpoint now returns 409 if the vault is already configured, preventing a privileged user from accidentally overwriting all encrypted PII.
Security: vault cookie server-secret fallback replaced with a randomly generated 64-character key stored as a WordPress option, eliminating a guessable fallback based on site URL.
Security: meta box save guard upgraded from edit_post to manage_options capability, matching the REST API authorization model.
Compatibility: wp_enqueue_script updated to use array-style args (WordPress 6.3+); removes the deprecation notice from WP_DEBUG logs.
Compatibility: Tested up to WordPress 7.0.
CI: build artifact verification step added to the deploy workflow; the release is aborted if the compiled JS or CSS files are missing.
i18n: translation strings refreshed.
1.2.2
WP admin theme color integration: sidebar nav active state and CTA buttons now read actual computed colors from the WP admin DOM at runtime, adapting to all built-in and custom admin color schemes.
Custom payment types: new CRUD REST API (GET/POST /payment-types, PUT/DELETE /payment-types/:id) lets administrators define installment types beyond the built-in Default/Coupon. UI manager in the Works list.
Installment type selector: dropdown driven by custom payment types instead of a hardcoded toggle.
Payment status badge labels (Paid / Partial / Unpaid) are now translatable via WordPress i18n.
Secondary button border fix: added border-style: solid to prevent WP admin CSS bleed-through from hiding the border after the appearance reset.
Accessibility: removed focus:outline-none from Button component; keyboard users now see a proper focus ring on all interactive elements.
Sidebar nav: all nav items (free and Pro) use the themed active state class; Pro items no longer show hardcoded indigo on active.
1.2.1
Consistent button design system: all buttons use three semantic variants — primary (WP admin theme color), secondary (white + gray border), danger (red). No more shadows, gradients, or mixed inline styles.
WP admin theme color integration: primary buttons pick up –wp-admin-theme-color CSS variable automatically.
Full-width forms: removed max-w-* constraints from WorkForm, CustomerForm, ServiceForm, and SettingsPage.
1.2.0
Added REST endpoint GET /collaborator-options.
Work REST API now saves collaborators[] and full owner type/id fields.
Fixed: sticky layout shell with dynamic viewport height; sidebar and main content scroll independently.
1.1.0
Added Quick Notes WYSIWYG field to Work edit screen, placed above the main notes editor.
Added Calendar Color picker (12-color palette) to Work edit screen.
Added quick_notes and color fields to the Works REST API.
Full i18n/l10n support: all React UI strings wrapped in gettext functions; Italian (it_IT) translation covers 100% of PHP and JavaScript strings.
Regenerated POT template; added JSON translation file for React components (wp_set_script_translations).