Repository navigation
Conversation
computeKuboConfig(kuboConfig, reachabilityConfig, enabled) is the one place that decides the kubo edits. planKuboConfig also returns a record of what changed, which tells our entries from identical operator ones and lets disable restore the touched fields byte for byte.
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 42 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
| export async function readIssuedCertificates(dataPath: string, now: Date = new Date()): Promise<CertificateInfo[]> { | ||
| const certificatesRoot = path.join(caddyDataDir(dataPath), "certificates"); | ||
| let entries: { name: string; parentPath: string; isFile(): boolean }[]; | ||
| try { | ||
| entries = await fs.readdir(certificatesRoot, { recursive: true, withFileTypes: true }); | ||
| } catch (error) { | ||
| if ((error as NodeJS.ErrnoException).code === "ENOENT") return []; | ||
| throw error; | ||
| } | ||
| const certificates: CertificateInfo[] = []; | ||
| for (const entry of entries) { | ||
| if (!entry.isFile() || !entry.name.endsWith(".crt")) continue; | ||
| const filePath = path.join(entry.parentPath, entry.name); | ||
| try { | ||
| const certificate = new X509Certificate(await fs.readFile(filePath)); | ||
| const notAfter = new Date(certificate.validTo); | ||
| certificates.push({ |
There was a problem hiding this comment.
Bug: status lists stale certificates as if they were current.
readIssuedCertificates (
bitsocial-cli/src/reachability/state.ts
Lines 133 to 151 in 189d3c6
.crt under caddy-data/certificates/**. It never compares them with the current config (publicIps, domain, staging), and the human-readable output doesn't print issuer.
Normal-use scenarios once Caddy lands (step 4):
- IP change: the old IP's cert stays in Caddy storage until it expires. The list is sorted by
notAfter, so the dead cert comes first with few or negative hours left, and an operator reads that as "my cert is about to expire". - Staging then production: both certs are listed under the same name, and text mode gives no way to tell them apart.
Suggested fix: keep only certs whose SANs intersect the current publicIps/domain and whose CA directory matches staging. At the least, print the issuer and mark expired entries.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 189d3c6eaa
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // Status must keep working when this file is damaged: it only holds the last check results. | ||
| async function readRuntimeStatus(dataPath: string): Promise<ReachabilityRuntimeStatus | null> { | ||
| try { | ||
| return ((await readJsonIfExists(reachabilityRuntimeStatusPath(dataPath))) as ReachabilityRuntimeStatus | undefined) ?? null; |
There was a problem hiding this comment.
Validate runtime status before exposing it
When runtime-status.json contains valid JSON with a damaged shape, such as a missing or non-array lastIpCheck.publicIps, this cast accepts it and the human status command subsequently throws on publicIps.join(...). The stated resilience currently covers only JSON parse failures; validate the runtime fields and return null for malformed content so bitsocial reachability status continues working.
Useful? React with 👍 / 👎.
| if (status.lastChecks?.lastIpCheck) { | ||
| const { at, publicIps } = status.lastChecks.lastIpCheck; | ||
| this.log(`Last IP check: ${at} (${publicIps.join(", ") || "no public IP found"})`); | ||
| } |
There was a problem hiding this comment.
Print domain and Caddy checks in human status
For domain-only and reverse-proxy configurations, the daemon can populate lastChecks.domains and lastChecks.caddy without setting lastIpCheck, but the normal command prints none of that health information even though its description promises the last checks. Only --json exposes these fields, leaving interactive users unable to see domain failures or whether Caddy is running.
Useful? React with 👍 / 👎.
reachability/config.json holds the operator's choices and refuses to load a newer version rather than drop its fields. The daemon's check results go in a separate file so they cannot overwrite a setup in progress.
…e status Caddy keeps certificates for old addresses and other CAs until they expire, so status now filters to the configured CA and current names. A damaged runtime status file reads as no checks yet, and the text output prints domain and Caddy checks.
189d3c6 to
812bb36
Compare
|
Consolidated into #208. |
Part of #198 (step 3). Based on #202, so its commit shows here until that merges.
Summary
bitsocial reachability status [--json]reports mode, announced addresses, certificate expiry and last checks.The separate runtime file is not in the issue. A periodic check landing during
setupwould otherwise overwrite the operator's config with a stale copy.Evidence
reachabilitytopic.After:
test/reachability/state.test.tsandtest/cli/reachability-status.test.tspass.npm run test:cli: 53 files, 507 passed, 1 skipped.Merge Danger
Door: two-way
The
config.jsonschema becomes a compatibility commitment only oncesetupwrites it (step 5).Blast Radius: none
Adds a read-only command and a help topic.