GitHub
08/11/2026, 1:39 PMformatRelative returned 'just now' for future timestamps, so expires ${formatRelative(futureDate)} rendered as "expires just now".
Changes
Frontend — secret field (frontend/src/features/enrollment/EnrollPage.tsx)
• New SecretField component in the Lifecycle tab
• Fetches the enroll secret via GET /api/v1/environments/{env}/enroll/secret
• Displays in a password-masked text field (hidden by default)
• Show/Hide button to toggle visibility
• Copy button to copy to clipboard (shows "Copied ✓")
• Download button that downloads as osctrl-{environment-name}.secret
Frontend — expiration fix (frontend/src/lib/time.ts)
• Added formatTimeUntil(iso) — returns "in 3d", "in 2h", "in 4m" for future dates
• Updated formatRelative to delegate future timestamps to formatTimeUntil instead of returning 'just now'
• LifecycleCard now shows "expires in 3d" for future dates and "expired 2h ago" for past dates
Validation
• npm run check — TypeScript typecheck clean
• npm test — 34 test files / 209 tests pass
• gofmt clean on all modified files
jmpsec/osctrlGitHub
08/11/2026, 1:46 PM