Files
member-console/internal/embeds/static/grant-valid-until-tz.js
T
cgalo5758 8ad678836b fix: grant "Valid Until" parsed as UTC, expiring trials immediately
The operator grant forms use <input type="datetime-local">, which submits a
naive wall-clock string with no timezone. The handlers parsed it with time.Parse,
whose default for a zone-less value is UTC — so for an operator behind UTC, a
near-future pick resolved to a past instant, GrantExpirationWorkflow saw a
past valid_until and fired immediately, and the plan reverted to the default at
once instead of lasting the chosen window.

- Route IssueGrant and ExtendGrant through one parseGrantValidUntil helper.
- Interpret the value in the server's local zone (time.ParseInLocation), and when
  the browser supplies valid_until_offset (grant-valid-until-tz.js, attached on
  htmx:configRequest) resolve the exact instant regardless of server timezone.
- Reject a Valid Until in the past.
2026-06-23 17:11:03 -05:00

20 lines
1.0 KiB
JavaScript

// grant-valid-until-tz.js
//
// The operator grant forms use <input type="datetime-local" name="valid_until">,
// which submits a naive wall-clock string with no timezone. Without help, the
// server can only assume its own local zone — wrong when the operator's browser
// is in a different timezone than the deployment. This attaches the browser's
// UTC offset (in minutes, for the *picked* date so DST is handled) as
// valid_until_offset on every HTMX request that carries a valid_until, letting
// the server resolve the exact instant. Pure progressive enhancement: if this
// script doesn't run, the server falls back to its local zone.
(function () {
document.body.addEventListener("htmx:configRequest", function (evt) {
var params = evt.detail && evt.detail.parameters;
if (!params || !params.valid_until) return;
var picked = new Date(params.valid_until); // datetime-local → local time for that date
if (isNaN(picked.getTime())) return;
params.valid_until_offset = String(picked.getTimezoneOffset());
});
})();