feat(licenses): domain lock grace period — configurable time before domain binding #394

Closed
opened 2026-06-01 10:01:07 +00:00 by jmiller · 2 comments
Owner

Summary

Add DomainLockHours to packages and FirstUsedUnix to keys. During the grace period after first use, any domain is accepted and auto-added. After expiry, only listed domains allowed.

Implementation (done in dev)

  • DomainLockHours int on LicensePackage (0 = immediate lock)
  • FirstUsedUnix on LicenseKey (set on first TouchHeartbeat)
  • Grace period logic in ValidateLicenseKey domain check
  • UI field in create/edit package forms

Test Plan

  • Set DomainLockHours=48 on package, generate key
  • Validate with domain A → accepted, domain added
  • Validate with domain B within 48h → accepted, domain added
  • Validate with domain C after 48h → rejected
  • Set DomainLockHours=0 → immediate lock on first use

🤖 Generated with Claude Code

## Summary Add `DomainLockHours` to packages and `FirstUsedUnix` to keys. During the grace period after first use, any domain is accepted and auto-added. After expiry, only listed domains allowed. ## Implementation (done in dev) - `DomainLockHours int` on `LicensePackage` (0 = immediate lock) - `FirstUsedUnix` on `LicenseKey` (set on first TouchHeartbeat) - Grace period logic in `ValidateLicenseKey` domain check - UI field in create/edit package forms ## Test Plan - [ ] Set DomainLockHours=48 on package, generate key - [ ] Validate with domain A → accepted, domain added - [ ] Validate with domain B within 48h → accepted, domain added - [ ] Validate with domain C after 48h → rejected - [ ] Set DomainLockHours=0 → immediate lock on first use 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Author
Owner

Testing Plan — Domain Lock Grace Period

API

  • Create package with DomainLockHours=48
  • Generate key, validate with domain A → accepted, FirstUsedUnix set
  • Validate with domain B (within 48h) → accepted, domain B added to restriction
  • Validate with domain C (after 48h grace) → rejected "domain not allowed"
  • DomainLockHours=0 → immediate lock: second domain rejected immediately
  • Validate without domain param → no domain check (passes)
  • Master/internal keys bypass domain lock entirely

GUI

  • Domain lock hours field in create package form
  • Domain lock hours field in edit package form with current value
  • Help text: "Hours after first use before the key locks to its domain(s). 0 = lock immediately."

🤖 Generated with Claude Code

## Testing Plan — Domain Lock Grace Period ### API - [ ] Create package with DomainLockHours=48 - [ ] Generate key, validate with domain A → accepted, FirstUsedUnix set - [ ] Validate with domain B (within 48h) → accepted, domain B added to restriction - [ ] Validate with domain C (after 48h grace) → rejected "domain not allowed" - [ ] DomainLockHours=0 → immediate lock: second domain rejected immediately - [ ] Validate without domain param → no domain check (passes) - [ ] Master/internal keys bypass domain lock entirely ### GUI - [ ] Domain lock hours field in create package form - [ ] Domain lock hours field in edit package form with current value - [ ] Help text: "Hours after first use before the key locks to its domain(s). 0 = lock immediately." 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jmiller added the pending: testing label 2026-06-01 10:13:56 +00:00
jmiller reopened this issue 2026-06-02 11:21:44 +00:00
Author
Owner

Tested and verified in production on MokoWaaS. All three download gating modes (none/prerelease/all), feed visibility, XML metadata, download URLs, and access control confirmed working.

Tested and verified in production on MokoWaaS. All three download gating modes (none/prerelease/all), feed visibility, XML metadata, download URLs, and access control confirmed working.
Sign in to join this conversation.
No labels pending: testing
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoGitea#394