@bumail/mta-sts 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +121 -2
- package/dist/body.d.ts +4 -0
- package/dist/body.d.ts.map +1 -0
- package/dist/deadline.d.ts +15 -0
- package/dist/deadline.d.ts.map +1 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/fetch-error.d.ts +17 -0
- package/dist/fetch-error.d.ts.map +1 -0
- package/dist/fetch.d.ts +40 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +535 -0
- package/dist/index.js.map +20 -0
- package/dist/policy.d.ts +25 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/report.d.ts +59 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/sts-record.d.ts +21 -0
- package/dist/sts-record.d.ts.map +1 -0
- package/dist/tls-result.d.ts +9 -0
- package/dist/tls-result.d.ts.map +1 -0
- package/dist/tls-rpt-record.d.ts +24 -0
- package/dist/tls-rpt-record.d.ts.map +1 -0
- package/dist/txt.d.ts +9 -0
- package/dist/txt.d.ts.map +1 -0
- package/docs/README.md +10 -0
- package/docs/guide.md +130 -0
- package/docs/roadmap.md +27 -0
- package/docs/troubleshooting.md +199 -0
- package/package.json +54 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Steve Tsala
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,122 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bumail/mta-sts
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MTA-STS (RFC 8461) and SMTP TLS reporting (RFC 8460) as plain functions: read
|
|
4
|
+
and write the `_mta-sts` and `_smtp._tls` TXT records, read and write the
|
|
5
|
+
policy file, fetch a domain's policy over HTTPS with a `fetch` you give, and
|
|
6
|
+
build the TLS report JSON. Nothing here touches the network on its own, and
|
|
7
|
+
a parser answers a result instead of throwing. No dependency.
|
|
8
|
+
|
|
9
|
+
**Bun only**, like every `@bumail/*` package: it runs on Bun 1.4.2 or later.
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
bun add @bumail/mta-sts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## The `_mta-sts` record
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { formatStsRecord, parseStsRecord } from '@bumail/mta-sts';
|
|
19
|
+
|
|
20
|
+
parseStsRecord('v=STSv1; id=20160831085700Z');
|
|
21
|
+
// { ok: true, value: { id: '20160831085700Z' } }
|
|
22
|
+
parseStsRecord(['v=spf1 -all', 'v=STSv1; id=1', 'v=STSv1; id=2']);
|
|
23
|
+
// { ok: false, error: { code: 'MULTIPLE_RECORDS', message: '…' } }
|
|
24
|
+
|
|
25
|
+
formatStsRecord({ id: '20260103' }); // 'v=STSv1; id=20260103'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## The policy file
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { formatPolicy, parsePolicy } from '@bumail/mta-sts';
|
|
32
|
+
|
|
33
|
+
const text = formatPolicy({ mode: 'testing', mx: ['mail.example.com', '*.example.net'], maxAge: 86400 });
|
|
34
|
+
// 'version: STSv1\r\nmode: testing\r\nmx: mail.example.com\r\nmx: *.example.net\r\nmax_age: 86400\r\n'
|
|
35
|
+
|
|
36
|
+
parsePolicy(text);
|
|
37
|
+
// { ok: true, value: { version: 'STSv1', mode: 'testing', mx: [...], maxAge: 86400 } }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Fetching a policy
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { fetchPolicy } from '@bumail/mta-sts';
|
|
44
|
+
|
|
45
|
+
const result = await fetchPolicy('gmail.com', {
|
|
46
|
+
timeoutMs: 10_000, // default 60 000
|
|
47
|
+
maxAgeCap: 86400, // keep a peer's policy a day at most
|
|
48
|
+
signal: AbortSignal.timeout(30_000), // optional: give up early
|
|
49
|
+
});
|
|
50
|
+
if (result.ok) {
|
|
51
|
+
result.policy; // { mode, mx, maxAge (capped), … }
|
|
52
|
+
result.text; // the file as served, for a report
|
|
53
|
+
} else {
|
|
54
|
+
result.error.code; // 'STATUS', 'TIMEOUT', 'CERTIFICATE', …
|
|
55
|
+
result.error.tlsResult; // 'sts-policy-fetch-error' | 'sts-policy-invalid' | 'sts-webpki-invalid'
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
It reads `https://mta-sts.<domain>/.well-known/mta-sts.txt`, follows no
|
|
60
|
+
redirect, accepts only `200` and `text/plain`, reads at most 64 KiB and gives
|
|
61
|
+
up after 60 seconds. Whatever the network does, it answers a result; only
|
|
62
|
+
an option out of range (`timeoutMs` not from 1 to 2147483647, `maxAgeCap` not a whole
|
|
63
|
+
number from 0 to 31 557 600) throws `MtaStsError`, before any fetch.
|
|
64
|
+
|
|
65
|
+
## The `_smtp._tls` record
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { formatTlsRptRecord, parseTlsRptRecord } from '@bumail/mta-sts';
|
|
69
|
+
|
|
70
|
+
parseTlsRptRecord('v=TLSRPTv1; rua=mailto:tls@example.com,https://example.com/r');
|
|
71
|
+
// { ok: true, value: { rua: ['mailto:tls@example.com', 'https://example.com/r'] } }
|
|
72
|
+
// An entry of another scheme is left out; the record fails only when none is left.
|
|
73
|
+
|
|
74
|
+
formatTlsRptRecord({ rua: ['mailto:tls@example.com'] }); // 'v=TLSRPTv1; rua=mailto:tls@example.com'
|
|
75
|
+
// A raw ! or , in a URI throws: write them %21 and %2C (RFC 8460 §3).
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## A TLS report
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { fetchPolicy, serialiseTlsReport, tlsReport } from '@bumail/mta-sts';
|
|
82
|
+
|
|
83
|
+
const fetched = await fetchPolicy('gmail.com');
|
|
84
|
+
|
|
85
|
+
const report = tlsReport({
|
|
86
|
+
organizationName: 'Example Mail',
|
|
87
|
+
contactInfo: 'tls@example.com',
|
|
88
|
+
reportId: crypto.randomUUID(),
|
|
89
|
+
dateRange: { start: new Date('2026-11-02T00:00:00Z'), end: new Date('2026-11-02T23:59:59Z') },
|
|
90
|
+
policies: [
|
|
91
|
+
{
|
|
92
|
+
policy: { type: 'sts', string: fetched.ok ? fetched.text : 'version: STSv1\nmode: none\nmax_age: 0\n', domain: 'gmail.com', mxHost: ['*.google.com'] },
|
|
93
|
+
summary: { success: 120, failure: 2 },
|
|
94
|
+
failureDetails: [{ resultType: 'certificate-expired', failedSessionCount: 2 }],
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
});
|
|
98
|
+
const json = serialiseTlsReport(report); // gzip it and send it to the `rua`: `@bumail/server` does (opt-in)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## API
|
|
102
|
+
|
|
103
|
+
| Export | What it is |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `parseStsRecord(txt)`, `formatStsRecord({ id })`, `StsRecord`, `StsRecordErrorCode`, `TxtAnswer` | the `_mta-sts` TXT record; `txt` is one string, or every TXT string or `@bumail/dns` `TxtRecord` of the name |
|
|
106
|
+
| `parsePolicy(text)`, `formatPolicy(policy)`, `StsPolicy`, `PolicyErrorCode`, `MAX_AGE_LIMIT` | the policy file: `version`, `mode`, `mx`, `max_age` (0 to 31 557 600) |
|
|
107
|
+
| `fetchPolicy(domain, options?)`, `FetchPolicyOptions`, `FetchPolicyResult`, `FetchPolicyError`, `FetchPolicyErrorCode`, `PolicyFetch`, `POLICY_TIMEOUT_MS`, `POLICY_MAX_BYTES` | the policy over HTTPS: `fetch`, `timeoutMs`, `maxAgeCap`, `signal` |
|
|
108
|
+
| `parseTlsRptRecord(txt)`, `formatTlsRptRecord({ rua })`, `TlsRptRecord`, `TlsRptRecordErrorCode` | the `_smtp._tls` TXT record |
|
|
109
|
+
| `tlsReport(input)`, `serialiseTlsReport(report)`, `TlsReportInput`, `TlsReportPolicy`, `TlsFailureDetail`, `TlsReport` | the RFC 8460 §4 report object (hyphenated keys), validated, and its JSON |
|
|
110
|
+
| `TLS_RESULT_TYPES`, `TlsResultType` | the result types of RFC 8460 §4.3, the same union `@bumail/smtp` names |
|
|
111
|
+
| `ParseResult`, `ParseFailure` | what every parser answers |
|
|
112
|
+
| `MtaStsError`, `MtaStsErrorCode` | what a formatter, `tlsReport` or a bad `fetchPolicy` option throws: `INVALID_RECORD`, `INVALID_POLICY`, `INVALID_REPORT`, `INVALID_OPTION` |
|
|
113
|
+
|
|
114
|
+
Matching an MX host against a policy's `mx` patterns is `matchesMxName` in
|
|
115
|
+
`@bumail/smtp/client`, so there is one copy of that rule.
|
|
116
|
+
|
|
117
|
+
## Documentation
|
|
118
|
+
|
|
119
|
+
- [Index](https://github.com/softistx/bumail/blob/develop/packages/mta-sts/docs/README.md): the pages below, and when to read each.
|
|
120
|
+
- [Guide](https://github.com/softistx/bumail/blob/develop/packages/mta-sts/docs/guide.md): publishing a policy, reading a peer's, the fetch rules and the report.
|
|
121
|
+
- [Troubleshooting](https://github.com/softistx/bumail/blob/develop/packages/mta-sts/docs/troubleshooting.md): every error message, and what to do about it.
|
|
122
|
+
- [Roadmap](https://github.com/softistx/bumail/blob/develop/packages/mta-sts/docs/roadmap.md): what is coming, and what is not planned.
|
package/dist/body.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../src/body.ts"],"names":[],"mappings":"AAEA,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAE1C,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ClE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Failure } from './fetch-error';
|
|
2
|
+
export declare function aborted(): Failure;
|
|
3
|
+
/**
|
|
4
|
+
* A deadline over one fetch: `signal` to give the injected `fetch`,
|
|
5
|
+
* `stopped`, which rejects with a `TIMEOUT` failure after `timeoutMs` or with
|
|
6
|
+
* the abort of the caller's `outer` signal, and `dispose`, which clears the
|
|
7
|
+
* timer and removes the listener. Race the work against `stopped`, so a
|
|
8
|
+
* `fetch` that ignores its signal is still cut off.
|
|
9
|
+
*/
|
|
10
|
+
export declare function withDeadline(outer: AbortSignal | undefined, timeoutMs: number): {
|
|
11
|
+
signal: AbortSignal;
|
|
12
|
+
stopped: Promise<never>;
|
|
13
|
+
dispose: () => void;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=deadline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deadline.d.ts","sourceRoot":"","sources":["../src/deadline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAW,MAAM,eAAe,CAAC;AAEtD,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,WAAW,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GACf;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CA2BvE"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a formatter or the report builder refused its input. A parser never
|
|
3
|
+
* throws: it answers a {@link ParseResult}.
|
|
4
|
+
*
|
|
5
|
+
* - `INVALID_OPTION`: an option of `fetchPolicy` out of range;
|
|
6
|
+
* - `INVALID_RECORD`: a record to write that RFC 8461 §3.1 or RFC 8460 §3 cannot hold;
|
|
7
|
+
* - `INVALID_POLICY`: a policy to write that RFC 8461 §3.2 cannot hold;
|
|
8
|
+
* - `INVALID_REPORT`: a TLS report that RFC 8460 §4 cannot hold.
|
|
9
|
+
*/
|
|
10
|
+
export type MtaStsErrorCode = 'INVALID_OPTION' | 'INVALID_RECORD' | 'INVALID_POLICY' | 'INVALID_REPORT';
|
|
11
|
+
export declare class MtaStsError extends Error {
|
|
12
|
+
readonly name = "MtaStsError";
|
|
13
|
+
readonly code: MtaStsErrorCode;
|
|
14
|
+
constructor(code: MtaStsErrorCode, message: string);
|
|
15
|
+
}
|
|
16
|
+
/** A parse that failed: a stable `code` to branch on and a `message` to log. */
|
|
17
|
+
export interface ParseFailure<Code extends string> {
|
|
18
|
+
readonly code: Code;
|
|
19
|
+
readonly message: string;
|
|
20
|
+
}
|
|
21
|
+
/** What a parser answers: the value, or why the text is not one. */
|
|
22
|
+
export type ParseResult<T, Code extends string> = {
|
|
23
|
+
readonly ok: true;
|
|
24
|
+
readonly value: T;
|
|
25
|
+
} | {
|
|
26
|
+
readonly ok: false;
|
|
27
|
+
readonly error: ParseFailure<Code>;
|
|
28
|
+
};
|
|
29
|
+
export declare function fail<Code extends string>(code: Code, message: string): {
|
|
30
|
+
readonly ok: false;
|
|
31
|
+
readonly error: ParseFailure<Code>;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GACxB,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,CAAC;AAEpB,qBAAa,WAAY,SAAQ,KAAK;IACrC,SAAkB,IAAI,iBAAiB;IACvC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;gBAEnB,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM;CAIlD;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY,CAAC,IAAI,SAAS,MAAM;IAChD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,oEAAoE;AACpE,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,IAC3C;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACxC;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAE9D,wBAAgB,IAAI,CAAC,IAAI,SAAS,MAAM,EACvC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,GACb;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,CAAA;CAAE,CAE5D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TlsResultType } from './tls-result';
|
|
2
|
+
/** Why a policy could not be had; each maps to a result type of RFC 8460 §4.3 through {@link FetchPolicyError.tlsResult}. */
|
|
3
|
+
export type FetchPolicyErrorCode = 'INVALID_DOMAIN' | 'NETWORK' | 'TIMEOUT' | 'CERTIFICATE' | 'REDIRECT' | 'STATUS' | 'CONTENT_TYPE' | 'TOO_LARGE' | 'NOT_UTF8' | 'INVALID_POLICY';
|
|
4
|
+
export interface FetchPolicyError {
|
|
5
|
+
readonly code: FetchPolicyErrorCode;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
/** The `result-type` a TLS report names this failure with. */
|
|
8
|
+
readonly tlsResult: Extract<TlsResultType, 'sts-policy-fetch-error' | 'sts-policy-invalid' | 'sts-webpki-invalid'>;
|
|
9
|
+
}
|
|
10
|
+
export declare class Failure extends Error {
|
|
11
|
+
readonly detail: FetchPolicyError;
|
|
12
|
+
constructor(detail: FetchPolicyError);
|
|
13
|
+
}
|
|
14
|
+
export declare function failure(code: FetchPolicyErrorCode, message: string): Failure;
|
|
15
|
+
/** Whether a fetch rejection is a certificate refusal (Bun and Node put the code on the error or its cause). */
|
|
16
|
+
export declare function isCertificateError(error: unknown): boolean;
|
|
17
|
+
//# sourceMappingURL=fetch-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-error.d.ts","sourceRoot":"","sources":["../src/fetch-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,6HAA6H;AAC7H,MAAM,MAAM,oBAAoB,GAC7B,gBAAgB,GAChB,SAAS,GACT,SAAS,GACT,aAAa,GACb,UAAU,GACV,QAAQ,GACR,cAAc,GACd,WAAW,GACX,UAAU,GACV,gBAAgB,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAC1B,aAAa,EACb,wBAAwB,GAAG,oBAAoB,GAAG,oBAAoB,CACtE,CAAC;CACF;AAED,qBAAa,OAAQ,SAAQ,KAAK;IACrB,QAAQ,CAAC,MAAM,EAAE,gBAAgB;gBAAxB,MAAM,EAAE,gBAAgB;CAG7C;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ5E;AAcD,gHAAgH;AAChH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAe1D"}
|
package/dist/fetch.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type FetchPolicyError } from './fetch-error';
|
|
2
|
+
import { type StsPolicy } from './policy';
|
|
3
|
+
export type FetchPolicyResult = {
|
|
4
|
+
readonly ok: true;
|
|
5
|
+
readonly policy: StsPolicy;
|
|
6
|
+
/** The policy file as served, for a report's `policy-string`. */
|
|
7
|
+
readonly text: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly ok: false;
|
|
10
|
+
readonly error: FetchPolicyError;
|
|
11
|
+
};
|
|
12
|
+
/** The smallest `fetch` this package calls, so `globalThis.fetch` and a fake both fit. */
|
|
13
|
+
export type PolicyFetch = (url: string, init: {
|
|
14
|
+
readonly redirect: 'manual';
|
|
15
|
+
readonly signal: AbortSignal;
|
|
16
|
+
readonly headers: Record<string, string>;
|
|
17
|
+
}) => Promise<Response>;
|
|
18
|
+
export interface FetchPolicyOptions {
|
|
19
|
+
/** Defaults to `globalThis.fetch`. */
|
|
20
|
+
readonly fetch?: PolicyFetch;
|
|
21
|
+
/** The whole fetch, body included: a number of milliseconds, above 0 and at most 2147483647. Default {@link POLICY_TIMEOUT_MS}. */
|
|
22
|
+
readonly timeoutMs?: number;
|
|
23
|
+
/** The most `max_age` the returned policy keeps: a whole number of seconds, 0 to {@link MAX_AGE_LIMIT}. Default {@link MAX_AGE_LIMIT}. */
|
|
24
|
+
readonly maxAgeCap?: number;
|
|
25
|
+
/** Gives up when it aborts: the answer is a `NETWORK` failure that says "aborted". */
|
|
26
|
+
readonly signal?: AbortSignal;
|
|
27
|
+
}
|
|
28
|
+
/** RFC 8461 §3.3 asks for a bounded fetch and fixes no figure; a 60-second default. */
|
|
29
|
+
export declare const POLICY_TIMEOUT_MS = 60000;
|
|
30
|
+
/**
|
|
31
|
+
* Fetch and read the policy of `domain` (RFC 8461 §3.3):
|
|
32
|
+
* `GET https://mta-sts.<domain>/.well-known/mta-sts.txt` over HTTPS with a
|
|
33
|
+
* valid certificate, no redirect followed, status 200, `text/plain`, at
|
|
34
|
+
* most 64 KiB, within `timeoutMs`. Whatever the network, the host or the
|
|
35
|
+
* injected `fetch` does, the answer is `{ ok: false, error }`, whose
|
|
36
|
+
* `tlsResult` is the type to report; only an option out of range (a
|
|
37
|
+
* programming error) throws `MtaStsError` `INVALID_OPTION`, before any fetch.
|
|
38
|
+
*/
|
|
39
|
+
export declare function fetchPolicy(domain: string, options?: FetchPolicyOptions): Promise<FetchPolicyResult>;
|
|
40
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAGA,OAAO,EAEN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAC1B;IACA,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACrB,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE5D,0FAA0F;AAC1F,MAAM,MAAM,WAAW,GAAG,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IACL,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,KACG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB,MAAM,WAAW,kBAAkB;IAClC,sCAAsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,mIAAmI;IACnI,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0IAA0I;IAC1I,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,sFAAsF;IACtF,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAyFxC;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAqD5B"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { POLICY_MAX_BYTES } from './body';
|
|
2
|
+
export { MtaStsError, type MtaStsErrorCode, type ParseFailure, type ParseResult, } from './errors';
|
|
3
|
+
export { type FetchPolicyOptions, type FetchPolicyResult, fetchPolicy, POLICY_TIMEOUT_MS, type PolicyFetch, } from './fetch';
|
|
4
|
+
export type { FetchPolicyError, FetchPolicyErrorCode } from './fetch-error';
|
|
5
|
+
export { formatPolicy, MAX_AGE_LIMIT, type PolicyErrorCode, parsePolicy, type StsPolicy, } from './policy';
|
|
6
|
+
export { serialiseTlsReport, type TlsFailureDetail, type TlsReport, type TlsReportInput, type TlsReportPolicy, tlsReport, } from './report';
|
|
7
|
+
export { formatStsRecord, parseStsRecord, type StsRecord, type StsRecordErrorCode, } from './sts-record';
|
|
8
|
+
export { TLS_RESULT_TYPES, type TlsResultType } from './tls-result';
|
|
9
|
+
export { formatTlsRptRecord, parseTlsRptRecord, type TlsRptRecord, type TlsRptRecordErrorCode, } from './tls-rpt-record';
|
|
10
|
+
export type { TxtAnswer } from './txt';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EACN,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,WAAW,EACX,iBAAiB,EACjB,KAAK,WAAW,GAChB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EACN,YAAY,EACZ,aAAa,EACb,KAAK,eAAe,EACpB,WAAW,EACX,KAAK,SAAS,GACd,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,SAAS,GACT,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,eAAe,EACf,cAAc,EACd,KAAK,SAAS,EACd,KAAK,kBAAkB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EACN,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,qBAAqB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC"}
|