Changelog
What changed in each release, newest first.
The same list is in CHANGELOG.md at the root of the package you downloaded.
This page is rendered from that file, so the two cannot say different things.
Version numbers follow Semantic Versioning. In MAJOR.MINOR.PATCH, a new MAJOR
means something an existing installation depends on has changed, a new MINOR adds capability
without breaking anything, and a new PATCH only fixes defects. Each date is the day that
release was issued. The version your copy holds is in the VERSION file beside
this documentation, and on the diagnostics screen.
Before applying a release to an installation that already holds certificates, read upgrading. It covers replacing the application files while keeping your data and settings, what to do when a version is skipped, and how to roll back.
Unreleased
Added
- Buyer support and refund pages state the approved six-month support coverage, optional update renewal prices and fourteen-day conditional refund terms.
- Optional Gumroad update/support entitlement checks from System diagnostics use encrypted write-only licence keys, product binding, cached results and fail-soft HTTPS verification. Refund/dispute/chargeback and subscription deadlines are respected; certificate issuance and public verification stay available.
- Twelve original ready-made certificate designs include editable field layouts, localized print labels and all six certificate fonts. Applying a design creates an independent course template; existing administrator designs are preserved.
- Buyer samples include matching CSV/XLSX import examples, a five-row validation exercise and two original A4 landscape certificate backgrounds with reuse terms.
- Active private demo trials let System Admins change colors, fonts, browser titles and ordinary semantic interface text. Demo image uploads and protected security copy remain blocked; shared previews stay read-only, with bounded settings writes.
- Explicit demo deployments provide isolated 30-minute visitor trials with private sign-in sessions, expiry enforcement and scheduled restoration from owned baselines. Full pools report limited capacity; ordinary installations retain their behavior.
- Explicit demo deployments offer ordinary role sign-in with mandatory 2FA and read-only configuration previews. Server policy protects settings, account security and destructive actions; outbound email/webhooks and maintenance cron are blocked.
- Explicit demo environments can use separately owned storage while ordinary installations retain their existing runtime data and defaults.
- Great Vibes MN is available in certificate designs and exported PDFs, including Mongolian Cyrillic barred O and straight U. Its licence and upstream change log ship with it.
- A read-only Viewer role can inspect active records and the audit log while server-side permissions deny business writes and configuration access.
- Dashboard certificate and email metrics support selectable date ranges and link to matching filtered lists. Existing total and attention counts remain available.
- System Admins can configure email batch size, inter-send delay and a rolling-hour attempt cap. Workers preserve the cap across restarts; delivery logs show cap deferrals.
- Admins and Operators can resend an eligible certificate notification or retry the latest failed notifications in the current filtered list. Pending messages are not duplicated, opt-outs remain respected, and each retry preserves delivery history.
- Course runs has its own menu below Courses. All occurrences can be viewed and filtered together, with course selection when adding a run; existing bookmarks open the corresponding filtered list.
- System Admins can view a paginated email delivery log with status/date filters, recipient, subject, failed attempts and delivery times. Message bodies and raw transport errors remain private.
- A versioned OpenAPI 3.1 integration can issue, read, and revoke client-owned certificates. System Admins manage external course/run mappings and independently scoped, expiring, revocable Bearer tokens whose plaintext is shown once and never stored. Transactional idempotency makes concurrent retries create one record and rejects changed payloads.
- API clients can receive one
certificate_issuance.updatedcurrent-state webhook. Events use a durable at-least-once queue, immutable event ids, raw-body HMAC signatures, bounded retries and SSRF-safe HTTPS delivery. Each client may also reserve its own certificate number prefix; self-paced mappings keep a stable virtual occurrence key. - Admins can send a branded test message from the SMTP settings screen using the values currently entered without saving them. The page reports the SMTP server response, limits repeated attempts, and records the result without credentials.
- Public lookup by certificate number, unique ID or QR now distinguishes a revoked certificate from an unknown identifier. The notice shows no participant details, certificate facts, revocation reason or PDF. Deleted and archived revoked records remain hidden; archiving a verified certificate retains its existing behavior.
Fixed
- The bundled ZIP export dependency now supports the declared PHP 8.1 minimum. Composer resolves dependencies against that minimum when the lock is refreshed.
- Licence checks, webhook transport and CSV export avoid obsolete PHP 8.5 native API calls and constants while retaining compatibility with PHP 8.1.
- Certificate fields support keyboard movement, alignment guides and free dragging; editor text geometry and font weights align with the exported PDF. Eligible older PDFs update once on their next access while preserving approved business values.
- Public PDF previews use the native browser viewer when available, request a clean certificate view and retain the bundled canvas fallback and direct-open controls.
- Email template previews display managed branding logos while keeping scripts, forms and navigation disabled.
- Parallel requests within an existing private demo trial briefly wait for its request lock, keeping gallery fonts and backgrounds usable without changing visitor isolation, expiry or allocation/cleanup locking.
- Runtime translation edits and restores read the current override even when immutable source uses OPcache with timestamp validation disabled. Reused private demo trial paths also read their current baseline instead of a prior cached value.
- Installations without a custom favicon use a bundled, versioned certificate icon across public, admin, system and demo trial pages. Configured favicons retain priority.
- Profile language actions and certificate-template/course/course-run field groups reuse consistent responsive spacing.
- Selecting a certificate design field no longer creates an unsaved-change warning when its position and formatting remain unchanged.
- Dashboard screens remove redundant headings, preserve accessible regions, and keep mobile navigation actions compact. Drawers, dialogs and tables support keyboard use; diagnostics wrap correctly, and sandboxed email previews preserve the page styles.
- Profile feedback returns to its matching tab; authenticated recovery-code navigation returns to the account, and authentication challenge/reset screens offer a sign-in path.
- Certificate-template width controls match the server's bounds before saving.
- Completed Verifier sign-in and authenticated login revisits open the Verifier workspace.
- Guarded forms use native navigation to preserve unsaved-change warnings and feedback. Detached forms no longer block later navigation; ordinary list navigation stays available.
- Shared ISO date validation rejects malformed and NUL-containing strings before parsing.
- Public navigation uses Sign in, keeps its button beside the brand on mobile and hides the duplicate header link on the login page.
1.0.3 2026-09-14
Fixed
- Public certificates render directly on the page using a bundled PDF renderer, without relying on a browser PDF plugin or a new-tab workaround. The existing download remains.
- Browser language negotiation can be disabled with
APP_LOCALE_FROM_BROWSER=false, so an English browser respects a Mongolian site default. Explicit account/session choices still win. New installations disable negotiation; older installations retain it until configured. No schema changes are required.
Changed
- Documented installer language selection, changing an existing site language, the browser option, profile/session precedence and preservation of translation overrides.
1.0.2 2026-09-09
Two more defects reported from a running installation, both on the certificate a learner
actually receives. No database change and no setting change: replacing the application files
is the whole upgrade. 1.0.1 was never deployed, so this release contains it.
Fixed
- The verifying organization and the verification date printed blank. A certificate can go back to a verifier after it was issued, either returned for correction or put back into a queue, and be verified again on another day by another organization. The stored PDF froze every value at its first render, so those two fields stayed as they were before any verifier had seen the certificate: empty. The sheet then disagreed with both the register and the public certificate page, which showed them correctly. The verification on a stored certificate now follows the certificate. Everything that was approved, the participant, the course, the number, the issue and expiry dates, still freezes at issue and is never re-read.
- The certificate preview on the public page was blocked. Scanning a certificate's QR code opened the page with an empty panel reading "This content is blocked. Contact the site owner to fix the issue." The application already allowed its own page to show the certificate and nothing else to, but the web server was configured to forbid framing on every response, which overruled it. The server now sets that rule only on the files it serves itself.
Changed
- The public certificate page no longer says the PDF is kept exactly as it was first generated, which stopped being true in
1.0.1. It says what is now the case: the values are as they were approved, and the design follows the current template. - A regeneration caused by a new verification is recorded in the audit trail as
verification_changed, alongside the existingtemplate_changedandfile_missing.
Added
- The public certificate page offers "Open in a new tab" beside the download, for a phone browser that will not draw a PDF inside a frame.
1.0.1 2026-09-09
Three defects reported from a running installation. No database change is required, and no
setting has to be touched: replacing the application files is the whole upgrade.
Fixed
- A verifier's bulk decision was refused with "access denied". A verifier who selected certificates on the queue page, wrote the decision note and pressed Verify, Return or Reject was shown an HTTP 403 page, which reads as though their permissions were at fault. They were not. A browser assembles the data a form submits after the page's own submit handler has run, and a control disabled in the meantime is dropped from that data together with the value it stood for. The loading state disabled the button that was pressed, so which of the three decisions had been chosen never reached the server. The pressed button now keeps its value, and a request that genuinely arrives without a decision says so instead of reporting a permission problem.
- The same fault in the installer. "Continue without email settings" is a named button on a form with a loading state, so it was dropped in the same way and the step behaved as though nothing had been chosen. Fixed by the same change.
- A corrected certificate template did not reach the certificates already issued. A stored certificate PDF was frozen at issue together with the look it was drawn with, so a template corrected afterwards, for text at the wrong size or a field in the wrong place, changed nothing for the people already holding the broken sheet. The values on a certificate still freeze at issue and are never re-read: the wording, the dates and the numbers stay exactly as approved. The look now follows the template. A certificate is drawn on whatever its template says today, every time it is opened, for as long as it is valid.
- The two-factor code field accepted anything. Its input pattern was not a valid regular expression under current browsers, so the browser skipped it and the field allowed a space or any other character. Server-side validation was never affected, so no code was ever accepted that should not have been.
Changed
- A stored certificate PDF is rendered again when something the template actually draws with moves: the background, the canvas size, or a field's position, size, colour or alignment. Saving a template without changing any of those, renaming it for instance, renders nothing. A certificate whose template has been deleted, or whose background file has gone, is still served from the look recorded on it, so an issued certificate cannot be lost this way.
- Every certificate PDF regeneration now records why in its audit entry: the template changed, or the stored file was missing.
- The verification queue offers 25, 50 or 100 rows a page, matching the certificate register. Sorting and paging keep the choice.
Added
bin/refresh-certificate-documents.phpre-renders the stored PDFs of a chosen set of certificates in one pass, for an operator who would rather not wait for each certificate's next download. It reports what it would do until--confirmis given, requires an actor to record the work against, and renders only the files that are out of date. Select by template, by course, by certificate or by certificate-number pattern.
1.0.0 2026-09-07
Initial public release.
Added
- Certificate registry. Courses, course occurrences and certificate records. Each certificate carries its own certificate number and a unique verification id, and can be issued, edited, submitted for verification, revoked, archived, restored and deleted. Deletion is soft, so a record removed by mistake is recoverable. An occurrence can be deleted while no certificate references it, which is how an occurrence created during a test is cleaned up; once anything has been issued against it the delete is refused and says how many certificates hold it.
- Public verification without an account. A visitor checks a certificate by its unique id, by its direct link or by scanning its QR code, and sees one record: valid or expired, with nothing revealed about any other certificate or participant. A valid certificate can be downloaded as a PDF from the public page.
- External verifier workflow. A verifier organisation signs in to its own screens, sees only the certificates assigned to it, and approves, returns or rejects them one at a time or as a bulk decision.
- Certificate template designer. A field layout placed over a background image, saved per template and rendered to PDF on request, so a template serves an unlimited number of certificates and a rendered file is produced only when someone asks for it.
- Bulk import. CSV and XLSX files with 13 columns, staged for review before anything is written: every row is validated, a rejected row names the column that failed, and the whole batch is confirmed in one step. A row without an email address is rejected, for the same reason the form requires one.
- Certificate export of the filtered list as CSV, with spreadsheet formula injection neutralised in every cell.
- Email delivery. SMTP settings entered in the interface rather than in a file, a queue with retries so a temporary SMTP failure is not a lost notification, an editable template for each message the product sends, and a configurable sender name and address. Every certificate is issued to an email address, so asking for a notification always has somewhere to send it.
- Branding and white label. Logo, favicon, colour palette, fonts and browser title, changed from the interface without editing a stylesheet. Every accent in the interface is mixed from the one primary colour, including the selected navigation item and the ring around a focused field, so a single value rebrands the whole screen.
- Roles and permissions. Admin, Manager and Verifier, defined over 37 named permissions that are seeded on installation and checked on the server for every route.
- Two-factor authentication by time-based one-time code, with single-use recovery codes, required for internal accounts. Secrets are encrypted and recovery codes are stored as hashes.
- Audit log of every state change, readable by an Admin and archived by year so the table does not grow without limit. Rows keep the action name that was current when they were written, and the filter groups an event under the name in use today, so an upgraded installation lists one option per event rather than one per name it has ever had.
- English and Mongolian interfaces, both complete, with a translation editor for changing any wording without touching a file. An installation is expected to work in one language: the language choice in the header is a setting and is off by default, while each account can still pick its own language on its profile screen.
- Translation files. Export a language as one JSON file, translate it outside the browser, and import it back, with a preview that reports what would change before anything is written. Importing a file for a language the package does not ship adds that language, named by its code (
de_DE,de-DEorde), so a buyer can run the product in a language of their own without editing a file on the server or waiting for a release. An untranslated key reads in the reference language rather than as an identifier, and a release that adds strings adds them the same way, so nothing is ever blank. - Five-step web installer at
/install: server requirement checks, database, application settings, email and the first administrator. No shell access is needed to install the product, and the installer closes itself once it has run. - Four scheduled jobs: email delivery, export cleanup, certificate document cleanup and audit archiving.
- Security controls documented on the security and privacy page: prepared statements throughout, a one-time token on every state-changing request, rate limiting on sign-in, two-factor entry, activation, password reset and public verification, server-side sessions that are revoked when an account is disabled, host name validation, uploads checked by content rather than by file name, and generated files stored outside the served folder and streamed through an authorising route.
- Buyer documentation set in HTML, readable from the filesystem with no build step, and a third-party licence notice covering every bundled component.