BREAKING CHANGE(certProvisioner): Refactor: Introduce unified CertProvisioner to centralize certificate provisioning and renewal; remove legacy ACME config from Port80Handler and update SmartProxy to delegate certificate lifecycle management.
This commit is contained in:
@ -1,26 +1,47 @@
|
||||
## Plan: Centralize Certificate Renewal for all certificates
|
||||
## Refactor: Introduce a Unified CertProvisioner for Certificate Lifecycle
|
||||
|
||||
- [ ] Remove renewal logic from Port80Handler
|
||||
- Delete `startRenewalTimer()` and `checkForRenewals()` methods
|
||||
- Remove `renewThresholdDays` and `renewCheckIntervalHours` options from `IPort80HandlerOptions`
|
||||
- [ ] Expose certificate status from Port80Handler
|
||||
- Ensure `getDomainCertificateStatus()` returns `{certObtained, expiryDate}` for each domain
|
||||
- [ ] Add renewal settings to SmartProxy
|
||||
- Extend `port80HandlerConfig` to include `renewThresholdDays` and `renewCheckIntervalHours`
|
||||
- [ ] Implement renewal scheduler in SmartProxy using taskbuffer
|
||||
- Add dependency on `@push.rocks/taskbuffer` and import `{ Task, TaskManager }` in `SmartProxy`
|
||||
- Add `performRenewals()` to iterate domains and trigger renewals where `daysRemaining <= renewThresholdDays`
|
||||
- Instantiate a `TaskManager` and define a `Task` that wraps `performRenewals()`
|
||||
- Use `taskManager.addAndScheduleTask(task, cronExpr)` to schedule renewals, building `cronExpr` from `renewCheckIntervalHours` (e.g. `0 0 */${renewCheckIntervalHours} * * *`)
|
||||
- Call `taskManager.start()` in `SmartProxy.start()`
|
||||
- [ ] Clean shutdown handling
|
||||
- Call `taskManager.stop()` in `SmartProxy.stop()` alongside other cleanup
|
||||
- [ ] Throttling and safety
|
||||
- Skip domains already in `obtainingInProgress`
|
||||
- Optionally batch or stagger renewal calls for large domain sets
|
||||
- [ ] Tests
|
||||
- Unit test `performRenewals()`, mocking `getDomainCertificateStatus()` to simulate expiring certificates
|
||||
- Integration test using an in-memory `Port80Handler` to verify that scheduled renewals invoke `obtainCertificate()` correctly
|
||||
- [ ] Documentation
|
||||
- Update `readme.plan.md` (this section)
|
||||
- Update `README.md` and code comments to document new renewal settings and workflow
|
||||
- [x] Ensure Port80Handler is challenge-only:
|
||||
- Remove any internal scheduling and deprecated ACME flows (`getAcmeClient`, `processAuthorizations`, `handleAcmeChallenge`) from Port80Handler.
|
||||
- Remove legacy ACME options (`renewThresholdDays`, `renewCheckIntervalHours`, `mongoDescriptor`, etc.) from `IPort80HandlerOptions`.
|
||||
- Retain only methods for HTTP-01 challenge and direct renewals (`obtainCertificate`, `renewCertificate`, `getDomainCertificateStatus`).
|
||||
- [x] Clean up deprecated `acme` configuration:
|
||||
- Remove the `acme` property from `IPortProxySettings` and all legacy references in code.
|
||||
|
||||
- [x] Implement `CertProvisioner` component:
|
||||
- [x] Create class `ts/smartproxy/classes.pp.certprovisioner.ts`.
|
||||
- [x] Constructor accepts:
|
||||
* `domainConfigs: IDomainConfig[]`
|
||||
* `port80Handler: Port80Handler`
|
||||
* `networkProxyBridge: NetworkProxyBridge`
|
||||
* optional `certProvider: (domain) => Promise<ICert | 'http01'>`
|
||||
* `renewThresholdDays`, `renewCheckIntervalHours`, `autoRenew` settings.
|
||||
- Responsibilities:
|
||||
* Initial provisioning: static vs HTTP-01.
|
||||
* Subscribe to Port80Handler events (CERTIFICATE_ISSUED/RENEWED) and to static cert updates.
|
||||
* Re-emit unified `'certificate'` events to SmartProxy.
|
||||
* Central scheduling of renewals via `@push.rocks/taskbuffer`.
|
||||
|
||||
- [x] Refactor SmartProxy:
|
||||
- [x] Remove existing scheduling / renewal logic.
|
||||
- [x] Instantiate `CertProvisioner` in `start()`, delegate cert workflows entirely.
|
||||
- [x] Forward CertProvisioner events to SmartProxy’s `'certificate'` listener.
|
||||
|
||||
- [x] CertProvisioner lifecycle methods:
|
||||
- [x] `start()`: provision all domains, start scheduler.
|
||||
- [x] `stop()`: stop scheduler.
|
||||
- [x] `requestCertificate(domain)`: on-demand provisioning.
|
||||
|
||||
- [x] Handle static certificate auto-refresh:
|
||||
- [x] In the renewal scheduler, for domains with static certs, re-call `certProvider(domain)` near expiry.
|
||||
- [x] Apply returned cert via `networkProxyBridge.applyExternalCertificate()`.
|
||||
|
||||
- [ ] Tests:
|
||||
- Unit tests for `CertProvisioner`, mocking Port80Handler and `certProvider`:
|
||||
* Validate initial provisioning and dynamic/static flows.
|
||||
* Validate scheduling triggers correct renewals.
|
||||
- Integration tests:
|
||||
* Use actual in-memory Port80Handler with short intervals to verify renewals and event emission.
|
||||
|
||||
- [ ] Documentation:
|
||||
- Add code-level TS doc for `CertProvisioner` API (options, methods, events).
|
||||
- Update root `README.md` and architecture diagrams to show `CertProvisioner` role.
|
||||
|
Reference in New Issue
Block a user