Public: anyone can read this; the crew can change it.
A domain's proof is asked of the authority every time #328
Check · Review · Land · Live done — Landed and live in production.
domains-authority-merge → main 1 commit
2 files
changed +26
−3
src/apps/domains.ts +15 −3
| @@ -112,15 +112,27 @@ export function withAuthority( | ||
| 112 | 112 | primary: DomainResolver, |
| 113 | 113 | authority: Authority, |
| 114 | 114 | ): DomainResolver { |
| 115 | const authoritative = async (name: string): Promise<string[][]> => { | |
| 116 | const servers = await nameserversFor(name, authority); | |
| 117 | return authority.resolveTxtAt(servers, name); | |
| 118 | }; | |
| 115 | 119 | return { |
| 116 | 120 | async resolveTxt(name) { |
| 121 | // A stale answer is as misleading as a stale "none": a record changed | |
| 122 | // a minute ago still reads as its old value for as long as its TTL | |
| 123 | // says. So the authority is asked either way, and both answers count. | |
| 124 | let near: string[][] = []; | |
| 117 | 125 | try { |
| 118 | return await primary.resolveTxt(name); | |
| 126 | near = await primary.resolveTxt(name); | |
| 119 | 127 | } catch (error) { |
| 120 | 128 | if (!isNone(error)) throw error; |
| 121 | const servers = await nameserversFor(name, authority); | |
| 122 | return authority.resolveTxtAt(servers, name); | |
| 123 | 129 | } |
| 130 | const far = await authoritative(name).catch((error: unknown) => { | |
| 131 | if (near.length > 0 && isNone(error)) return [] as string[][]; | |
| 132 | throw error; | |
| 133 | }); | |
| 134 | const seen = new Set(near.map((r) => r.join(""))); | |
| 135 | return [...near, ...far.filter((r) => !seen.has(r.join("")))]; | |
| 124 | 136 | }, |
| 125 | 137 | resolveCname: (name) => primary.resolveCname(name), |
| 126 | 138 | }; |
test/app-domains.test.ts +11
| @@ -159,6 +159,17 @@ describe("checkDomain: every outcome is a sentence", () => { | ||
| 159 | 159 | "a ns1.example.net", |
| 160 | 160 | "[email protected] _forge-verify.app.example.com", |
| 161 | 161 | ]); |
| 162 | // A stale value from the box's resolver does not hide the authority's. | |
| 163 | const stale2 = withAuthority( | |
| 164 | { | |
| 165 | resolveTxt: () => Promise.resolve([["forge-verify=old-token-value"]]), | |
| 166 | resolveCname: stale.resolveCname, | |
| 167 | }, | |
| 168 | authority, | |
| 169 | ); | |
| 170 | const fresh = await checkDomain("app.example.com", token, "notes.apps.test", stale2); | |
| 171 | expect(fresh.verified).toBe(true); | |
| 172 | ||
| 162 | 173 | // And a resolver that says something other than "none" is believed. |
| 163 | 174 | const broken = withAuthority( |
| 164 | 175 | { |
new above
offline