@utilix-tech/sdk 0.38.0 → 0.40.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/CHANGELOG.md +8 -0
- package/README.md +25 -5
- package/dist/{chunk-47RI5V3B.js → chunk-2MTHD2LG.js} +62 -1
- package/dist/{chunk-GEFVMGZR.js → chunk-PET2CGTH.js} +46 -1
- package/dist/{chunk-DBNTO3YO.js → chunk-Y4BVU76A.js} +80 -1
- package/dist/hashing-CJjlvqS_.d.cts +127 -0
- package/dist/hashing-CJjlvqS_.d.ts +127 -0
- package/dist/index.cjs +185 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/{network-CnKUQT4g.d.cts → network-CKPoesdD.d.cts} +52 -2
- package/dist/{network-CnKUQT4g.d.ts → network-CKPoesdD.d.ts} +52 -2
- package/dist/tools/hashing.cjs +45 -0
- package/dist/tools/hashing.d.cts +1 -1
- package/dist/tools/hashing.d.ts +1 -1
- package/dist/tools/hashing.js +1 -1
- package/dist/tools/network.cjs +79 -0
- package/dist/tools/network.d.cts +1 -1
- package/dist/tools/network.d.ts +1 -1
- package/dist/tools/network.js +1 -1
- package/dist/tools/units.cjs +61 -0
- package/dist/tools/units.d.cts +1 -1
- package/dist/tools/units.d.ts +1 -1
- package/dist/tools/units.js +1 -1
- package/dist/{units-HQrMCiNM.d.cts → units-CzPwRC03.d.cts} +50 -2
- package/dist/{units-HQrMCiNM.d.ts → units-CzPwRC03.d.ts} +50 -2
- package/package.json +1 -1
- package/dist/hashing-CnetQFD_.d.cts +0 -76
- package/dist/hashing-CnetQFD_.d.ts +0 -76
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Full release notes for all Utilix surfaces (browser tools, REST API, SDKs, MCP server) live at [utilix.tech/changelog](https://utilix.tech/changelog). This file tracks just this package.
|
|
4
4
|
|
|
5
|
+
## 0.40.0
|
|
6
|
+
- Add `calculateCashBreakdown`, `calculateChange` (cash-till-calculator): break a cash amount down into the minimum count of bills/coins from a set of denominations (largest first), or compute change owed for a payment/tender pair and its breakdown.
|
|
7
|
+
- Add `generateEtag` (etag-generator): compute a content-hash ETag (MD5/SHA-1/SHA-256) for a response header, with an optional weak-validator (W/) prefix.
|
|
8
|
+
|
|
9
|
+
## 0.39.0
|
|
10
|
+
- Add `generateSri`, `generateSriAll` (sri-hash-generator): compute SHA-256/384/512 Subresource Integrity hashes for a script or stylesheet's content, formatted as the `<algorithm>-<base64>` string an HTML `integrity` attribute expects.
|
|
11
|
+
- Add `analyzeEmailHeaders` (email-header-analyzer): parse a raw email header block into structured From/To/Subject fields, the Received hop chain in order, and SPF/DKIM/DMARC results from an Authentication-Results header.
|
|
12
|
+
|
|
5
13
|
## 0.38.0
|
|
6
14
|
- Add `compareUnitPrices` (unit-price-comparator): compare two or more package options by price and quantity to find the true cost per unit, flag the cheapest, and report how much more expensive each other option is by percentage.
|
|
7
15
|
- Add `csvToSqlInsert` (csv-to-sql-insert-generator): convert CSV data with a header row into parameterless SQL INSERT statements, with basic type inference (numbers/booleans unquoted, empty cells NULL) and ANSI/MySQL identifier quoting.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @utilix-tech/sdk
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**610 developer utility functions for Node.js: runs locally, no API key required.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
6
6
|
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
@@ -119,7 +119,7 @@ base62Encode("hello world"); // "AAwf93rvy4aWQVw"
|
|
|
119
119
|
### `/hashing`: Hash & Password
|
|
120
120
|
|
|
121
121
|
```ts
|
|
122
|
-
import { hashAll, hashOne, hashPassword, verifyPassword, generateHtpasswdFile } from "@utilix-tech/sdk/hashing";
|
|
122
|
+
import { hashAll, hashOne, hashPassword, verifyPassword, generateHtpasswdFile, generateSriAll } from "@utilix-tech/sdk/hashing";
|
|
123
123
|
|
|
124
124
|
// Hash with MD5, SHA-1, SHA-256, SHA-512 in one call
|
|
125
125
|
const hashes = await hashAll("my-string");
|
|
@@ -131,6 +131,14 @@ const valid = await verifyPassword("my-password", hash);
|
|
|
131
131
|
|
|
132
132
|
// Generate .htpasswd file
|
|
133
133
|
generateHtpasswdFile([{ username: "alice", password: "secret" }]);
|
|
134
|
+
|
|
135
|
+
// Subresource Integrity hashes for a script/stylesheet's content (SHA-256/384/512)
|
|
136
|
+
generateSriAll("console.log(1)");
|
|
137
|
+
// [{ algorithm: "SHA-256", base64: "...", integrity: "sha256-..." }, ...]
|
|
138
|
+
|
|
139
|
+
// Content-hash ETag header value (MD5/SHA-1/SHA-256), with an optional weak (W/) prefix
|
|
140
|
+
generateEtag("console.log(1)");
|
|
141
|
+
// { algorithm: "SHA-1", weak: false, hash: "...", etag: "\"...\"", snippet: "ETag: \"...\"" }
|
|
134
142
|
```
|
|
135
143
|
|
|
136
144
|
---
|
|
@@ -402,6 +410,14 @@ calculateRoi({ initialValue: 1000, finalValue: 1610.51, years: 5 });
|
|
|
402
410
|
// Unit price comparator: true cost per unit across package options, flags the cheapest
|
|
403
411
|
compareUnitPrices([{ label: "12-pack", price: 6, quantity: 12 }, { label: "24-pack", price: 10, quantity: 24 }]);
|
|
404
412
|
// { items: [...], bestLabel: "24-pack" }
|
|
413
|
+
|
|
414
|
+
// Cash till breakdown: minimum count of bills/coins from a set of denominations
|
|
415
|
+
calculateCashBreakdown(53.75, USD_DENOMINATIONS);
|
|
416
|
+
// { breakdown: [{ denomination: 50, count: 1, subtotal: 50 }, ...], totalCount: 7, remainder: 0 }
|
|
417
|
+
|
|
418
|
+
// Change owed for a payment/tender pair, broken down the same way
|
|
419
|
+
calculateChange(4.65, 5.0, USD_DENOMINATIONS);
|
|
420
|
+
// { changeDue: 0.35, breakdown: [{ denomination: 0.25, count: 1, subtotal: 0.25 }, ...], totalCount: 2 }
|
|
405
421
|
```
|
|
406
422
|
|
|
407
423
|
---
|
|
@@ -412,7 +428,7 @@ compareUnitPrices([{ label: "12-pack", price: 6, quantity: 12 }, { label: "24-pa
|
|
|
412
428
|
import { getStatusCode, isValidIp, isValidIpv4, isValidIpv6,
|
|
413
429
|
searchStatusCodes, buildGeoUrl, countryCodeToFlag,
|
|
414
430
|
parseHar, validateSitemap, validateRobotsTxt,
|
|
415
|
-
parseUserAgent, buildCacheControl, buildReferrerPolicy, parseIpv6Address, buildLinkHeader, checkSetCookieHeader } from "@utilix-tech/sdk/network";
|
|
431
|
+
parseUserAgent, buildCacheControl, buildReferrerPolicy, parseIpv6Address, buildLinkHeader, checkSetCookieHeader, analyzeEmailHeaders } from "@utilix-tech/sdk/network";
|
|
416
432
|
|
|
417
433
|
getStatusCode(404);
|
|
418
434
|
// { code: 404, text: "Not Found", description: "...", category: "Client Error" }
|
|
@@ -463,6 +479,10 @@ buildLinkHeader([{ url: "/fonts/inter.woff2", rel: "preload", as: "font", type:
|
|
|
463
479
|
// Parse and validate a Set-Cookie header's attribute combination
|
|
464
480
|
checkSetCookieHeader("session=abc123; SameSite=None");
|
|
465
481
|
// { cookie: {...}, issues: ["SameSite=None requires the Secure attribute..."], warnings: [...], valid: false }
|
|
482
|
+
|
|
483
|
+
// Parse a raw email header block: fields, Received hop chain, SPF/DKIM/DMARC results
|
|
484
|
+
analyzeEmailHeaders(rawHeaderText);
|
|
485
|
+
// { from: "...", to: "...", receivedHops: [...], hopCount: 2, spf: "pass", dkim: "pass", dmarc: "pass", warnings: [] }
|
|
466
486
|
```
|
|
467
487
|
|
|
468
488
|
---
|
|
@@ -695,12 +715,12 @@ readVideoInfo(new Uint8Array(videoBytes));
|
|
|
695
715
|
|---|---|
|
|
696
716
|
| `@utilix-tech/sdk/json` | Format, minify, diff, validate, JSONPath, CSV↔JSON, YAML↔JSON, TS types from data or from a JSON Schema |
|
|
697
717
|
| `@utilix-tech/sdk/encoding` | Base64, URL, HTML entities, Base32/Base58/Base62 encode/decode |
|
|
698
|
-
| `@utilix-tech/sdk/hashing` | MD5, SHA-1/256/512, bcrypt, HMAC, .htpasswd |
|
|
718
|
+
| `@utilix-tech/sdk/hashing` | MD5, SHA-1/256/512, bcrypt, HMAC, .htpasswd, SRI hashes, content-hash ETag generation |
|
|
699
719
|
| `@utilix-tech/sdk/text` | Case convert, slugify, word count, lorem ipsum, line ops, HTML→Markdown, Levenshtein/Damerau string distance, readability scoring, sentence length distribution, emoji lookup |
|
|
700
720
|
| `@utilix-tech/sdk/data` | CSV, YAML, TOML, XML, INI, NDJSON parse and convert, SRT/WebVTT subtitles, Markdown front matter parser |
|
|
701
721
|
| `@utilix-tech/sdk/generators` | UUID v4/v7, ULID, passwords, strength check, entropy estimator, fake data |
|
|
702
722
|
| `@utilix-tech/sdk/time` | Date diff, timezone convert, cron parse, relative time |
|
|
703
|
-
| `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format, credit card/IBAN/barcode/ISBN validation, loan calculator, EMI calculator, compound/simple interest calculators, VAT/sales tax calculator, tip/bill split calculator, break-even point calculator, Rule of 72 calculator, savings goal calculator, ROI calculator |
|
|
723
|
+
| `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format, credit card/IBAN/barcode/ISBN validation, loan calculator, EMI calculator, compound/simple interest calculators, VAT/sales tax calculator, tip/bill split calculator, break-even point calculator, Rule of 72 calculator, savings goal calculator, ROI calculator, cash denomination/till calculator |
|
|
704
724
|
| `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing, User-Agent parsing, IPv6 address compress/expand |
|
|
705
725
|
| `@utilix-tech/sdk/api` | cURL build/parse, JWT decode/sign, JWKS parse, CORS headers, CSP header |
|
|
706
726
|
| `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format, MIME type lookup, GitHub URL parsing, regex ReDoS detector, Conventional Commits linter |
|
|
@@ -14,12 +14,15 @@ __export(units_exports, {
|
|
|
14
14
|
COMMON_TAX_RATES: () => COMMON_TAX_RATES,
|
|
15
15
|
COMMON_TIP_PERCENTAGES: () => COMMON_TIP_PERCENTAGES,
|
|
16
16
|
COMMON_VIEWPORTS: () => COMMON_VIEWPORTS,
|
|
17
|
+
USD_DENOMINATIONS: () => USD_DENOMINATIONS,
|
|
17
18
|
applySuccessiveDiscounts: () => applySuccessiveDiscounts,
|
|
18
19
|
autoFormat: () => autoFormat,
|
|
19
20
|
bumpVersion: () => bumpVersion,
|
|
20
21
|
calcAspectRatio: () => calcAspectRatio,
|
|
21
22
|
calcSubnet: () => calcSubnet,
|
|
22
23
|
calculateBreakEven: () => calculateBreakEven,
|
|
24
|
+
calculateCashBreakdown: () => calculateCashBreakdown,
|
|
25
|
+
calculateChange: () => calculateChange,
|
|
23
26
|
calculateCompoundInterest: () => calculateCompoundInterest,
|
|
24
27
|
calculateDiscount: () => calculateDiscount,
|
|
25
28
|
calculateEmi: () => calculateEmi,
|
|
@@ -1867,5 +1870,63 @@ function compareUnitPrices(items) {
|
|
|
1867
1870
|
const bestLabel = results.find((r) => r.isBest).label;
|
|
1868
1871
|
return { items: results, bestLabel };
|
|
1869
1872
|
}
|
|
1873
|
+
var USD_DENOMINATIONS = [100, 50, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01];
|
|
1874
|
+
function _cashToCents(n) {
|
|
1875
|
+
return Math.round(n * 100);
|
|
1876
|
+
}
|
|
1877
|
+
function calculateCashBreakdown(amount, denominations) {
|
|
1878
|
+
if (!Number.isFinite(amount) || amount < 0) return { error: "Amount must be zero or a positive number" };
|
|
1879
|
+
if (!Array.isArray(denominations) || denominations.length === 0) {
|
|
1880
|
+
return { error: "At least one denomination is required" };
|
|
1881
|
+
}
|
|
1882
|
+
for (const d of denominations) {
|
|
1883
|
+
if (typeof d !== "number" || !Number.isFinite(d) || d <= 0) {
|
|
1884
|
+
return { error: "Each denomination must be a positive number" };
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
const round22 = (n) => Math.round(n * 100) / 100;
|
|
1888
|
+
const sorted = Array.from(new Set(denominations)).sort((a, b) => b - a);
|
|
1889
|
+
let remainingCents = _cashToCents(amount);
|
|
1890
|
+
const breakdown = [];
|
|
1891
|
+
let totalCount = 0;
|
|
1892
|
+
for (const d of sorted) {
|
|
1893
|
+
const dCents = _cashToCents(d);
|
|
1894
|
+
const count = Math.floor(remainingCents / dCents);
|
|
1895
|
+
if (count > 0) {
|
|
1896
|
+
breakdown.push({ denomination: d, count, subtotal: round22(count * d) });
|
|
1897
|
+
remainingCents -= count * dCents;
|
|
1898
|
+
totalCount += count;
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
return {
|
|
1902
|
+
amount: round22(amount),
|
|
1903
|
+
denominations: sorted,
|
|
1904
|
+
breakdown,
|
|
1905
|
+
totalCount,
|
|
1906
|
+
remainder: round22(remainingCents / 100)
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
function calculateChange(amountDue, amountTendered, denominations) {
|
|
1910
|
+
if (!Number.isFinite(amountDue) || amountDue < 0) return { error: "Amount due must be zero or a positive number" };
|
|
1911
|
+
if (!Number.isFinite(amountTendered) || amountTendered < 0) {
|
|
1912
|
+
return { error: "Amount tendered must be zero or a positive number" };
|
|
1913
|
+
}
|
|
1914
|
+
if (_cashToCents(amountTendered) < _cashToCents(amountDue)) {
|
|
1915
|
+
return { error: "Amount tendered must be greater than or equal to the amount due" };
|
|
1916
|
+
}
|
|
1917
|
+
const round22 = (n) => Math.round(n * 100) / 100;
|
|
1918
|
+
const changeDue = round22(amountTendered - amountDue);
|
|
1919
|
+
const breakdown = calculateCashBreakdown(changeDue, denominations);
|
|
1920
|
+
if ("error" in breakdown) return breakdown;
|
|
1921
|
+
return {
|
|
1922
|
+
amountDue: round22(amountDue),
|
|
1923
|
+
amountTendered: round22(amountTendered),
|
|
1924
|
+
changeDue,
|
|
1925
|
+
denominations: breakdown.denominations,
|
|
1926
|
+
breakdown: breakdown.breakdown,
|
|
1927
|
+
totalCount: breakdown.totalCount,
|
|
1928
|
+
remainder: breakdown.remainder
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1870
1931
|
|
|
1871
|
-
export { BASE_LABELS, BASE_PREFIXES, BYTE_UNITS, COMMON_CURRENCIES, COMMON_LOCALES, COMMON_PERMISSIONS, COMMON_RATIOS, COMMON_SIZES, COMMON_TAX_RATES, COMMON_TIP_PERCENTAGES, COMMON_VIEWPORTS, applySuccessiveDiscounts, autoFormat, bumpVersion, calcAspectRatio, calcSubnet, calculateBreakEven, calculateCompoundInterest, calculateDiscount, calculateEmi, calculateLoan, calculateMarginMarkup, calculatePercentageChange, calculateRoi, calculateRuleOf72, calculateSavingsGoal, calculateSimpleInterest, calculateTax, calculateTimeValue, calculateTipSplit, calculateVideoBitrate, compareSemver, compareUnitPrices, convert, convertAprApy, convertBytes, convertIp, coverBox, decimalToIp, decimalToIpCidr, describePermissions, fitIntoBox, formatNumber, formatValue, formatVwValue, formatWithSeparator, gcd, ipFromBinary, ipFromDecimal, ipFromHex, ipToBinary, ipToDecimal, ipToDecimalCidr, ipToHex, ipToOctal, isValid, isValidCidr, isValidIp, isValidIpv4, marginToMarkup, markupToMargin, octalToPermissions, parseFileSize, parseInput, parseNumberString, parseSemver, permissionsToChmod, permissionsToOctal, permissionsToSymbolic, ptToPx, pxToAll, pxToViewport, remToPx, satisfiesRange, scaleByHeight, scaleByWidth, sortVersions, splitSubnet, symbolicToPermissions, units_exports, validateBarcode, validateCardNumber, validateIban, validateIsbn, viewportToPx };
|
|
1932
|
+
export { BASE_LABELS, BASE_PREFIXES, BYTE_UNITS, COMMON_CURRENCIES, COMMON_LOCALES, COMMON_PERMISSIONS, COMMON_RATIOS, COMMON_SIZES, COMMON_TAX_RATES, COMMON_TIP_PERCENTAGES, COMMON_VIEWPORTS, USD_DENOMINATIONS, applySuccessiveDiscounts, autoFormat, bumpVersion, calcAspectRatio, calcSubnet, calculateBreakEven, calculateCashBreakdown, calculateChange, calculateCompoundInterest, calculateDiscount, calculateEmi, calculateLoan, calculateMarginMarkup, calculatePercentageChange, calculateRoi, calculateRuleOf72, calculateSavingsGoal, calculateSimpleInterest, calculateTax, calculateTimeValue, calculateTipSplit, calculateVideoBitrate, compareSemver, compareUnitPrices, convert, convertAprApy, convertBytes, convertIp, coverBox, decimalToIp, decimalToIpCidr, describePermissions, fitIntoBox, formatNumber, formatValue, formatVwValue, formatWithSeparator, gcd, ipFromBinary, ipFromDecimal, ipFromHex, ipToBinary, ipToDecimal, ipToDecimalCidr, ipToHex, ipToOctal, isValid, isValidCidr, isValidIp, isValidIpv4, marginToMarkup, markupToMargin, octalToPermissions, parseFileSize, parseInput, parseNumberString, parseSemver, permissionsToChmod, permissionsToOctal, permissionsToSymbolic, ptToPx, pxToAll, pxToViewport, remToPx, satisfiesRange, scaleByHeight, scaleByWidth, sortVersions, splitSubnet, symbolicToPermissions, units_exports, validateBarcode, validateCardNumber, validateIban, validateIsbn, viewportToPx };
|
|
@@ -6,15 +6,20 @@ import bcrypt from 'bcryptjs';
|
|
|
6
6
|
// src/tools/hashing.ts
|
|
7
7
|
var hashing_exports = {};
|
|
8
8
|
__export(hashing_exports, {
|
|
9
|
+
ETAG_ALGORITHMS: () => ETAG_ALGORITHMS,
|
|
9
10
|
HASH_ALGORITHMS: () => HASH_ALGORITHMS,
|
|
10
11
|
HASH_BITS: () => HASH_BITS,
|
|
11
12
|
ROUND_OPTIONS: () => ROUND_OPTIONS,
|
|
13
|
+
SRI_ALGORITHMS: () => SRI_ALGORITHMS,
|
|
12
14
|
createEntry: () => createEntry,
|
|
13
15
|
generateBcryptHash: () => generateBcryptHash,
|
|
16
|
+
generateEtag: () => generateEtag,
|
|
14
17
|
generateHtpasswdFile: () => generateHtpasswdFile,
|
|
15
18
|
generateMd5Hash: () => generateMd5Hash,
|
|
16
19
|
generatePlain: () => generatePlain,
|
|
17
20
|
generateSha1Hash: () => generateSha1Hash,
|
|
21
|
+
generateSri: () => generateSri,
|
|
22
|
+
generateSriAll: () => generateSriAll,
|
|
18
23
|
hashAll: () => hashAll,
|
|
19
24
|
hashOne: () => hashOne,
|
|
20
25
|
hashPassword: () => hashPassword,
|
|
@@ -247,5 +252,45 @@ function generateHtpasswdFile(entries) {
|
|
|
247
252
|
function validateUsername(username) {
|
|
248
253
|
return /^[^\s:]{1,255}$/.test(username);
|
|
249
254
|
}
|
|
255
|
+
var SRI_ALGORITHMS = ["SHA-256", "SHA-384", "SHA-512"];
|
|
256
|
+
var SRI_NODE_ALG_MAP = {
|
|
257
|
+
"SHA-256": "sha256",
|
|
258
|
+
"SHA-384": "sha384",
|
|
259
|
+
"SHA-512": "sha512"
|
|
260
|
+
};
|
|
261
|
+
function generateSri(content, algorithm = "SHA-384") {
|
|
262
|
+
if (typeof content !== "string" || content.length === 0) {
|
|
263
|
+
return { error: "Content is required" };
|
|
264
|
+
}
|
|
265
|
+
if (!SRI_ALGORITHMS.includes(algorithm)) {
|
|
266
|
+
return { error: `Unknown algorithm: ${algorithm}. Must be one of ${SRI_ALGORITHMS.join(", ")}` };
|
|
267
|
+
}
|
|
268
|
+
const base64 = createHash(SRI_NODE_ALG_MAP[algorithm]).update(content, "utf8").digest("base64");
|
|
269
|
+
return { algorithm, base64, integrity: `${SRI_NODE_ALG_MAP[algorithm]}-${base64}` };
|
|
270
|
+
}
|
|
271
|
+
function generateSriAll(content) {
|
|
272
|
+
if (typeof content !== "string" || content.length === 0) {
|
|
273
|
+
return { error: "Content is required" };
|
|
274
|
+
}
|
|
275
|
+
return SRI_ALGORITHMS.map((alg) => generateSri(content, alg));
|
|
276
|
+
}
|
|
277
|
+
var ETAG_ALGORITHMS = ["MD5", "SHA-1", "SHA-256"];
|
|
278
|
+
var ETAG_NODE_ALG_MAP = {
|
|
279
|
+
"MD5": "md5",
|
|
280
|
+
"SHA-1": "sha1",
|
|
281
|
+
"SHA-256": "sha256"
|
|
282
|
+
};
|
|
283
|
+
function generateEtag(content, algorithm = "SHA-1", weak = false) {
|
|
284
|
+
if (typeof content !== "string" || content.length === 0) {
|
|
285
|
+
return { error: "Content is required" };
|
|
286
|
+
}
|
|
287
|
+
if (!ETAG_ALGORITHMS.includes(algorithm)) {
|
|
288
|
+
return { error: `Unknown algorithm: ${algorithm}. Must be one of ${ETAG_ALGORITHMS.join(", ")}` };
|
|
289
|
+
}
|
|
290
|
+
const hash = createHash(ETAG_NODE_ALG_MAP[algorithm]).update(content, "utf8").digest("hex");
|
|
291
|
+
const quoted = `"${hash}"`;
|
|
292
|
+
const etag = weak ? `W/${quoted}` : quoted;
|
|
293
|
+
return { algorithm, weak, hash, etag, headerName: "ETag", snippet: `ETag: ${etag}` };
|
|
294
|
+
}
|
|
250
295
|
|
|
251
|
-
export { HASH_ALGORITHMS, HASH_BITS, ROUND_OPTIONS, createEntry, generateBcryptHash, generateHtpasswdFile, generateMd5Hash, generatePlain, generateSha1Hash, hashAll, hashOne, hashPassword, hashWithTiming, hashing_exports, parseHtpasswdFile, validateRounds, validateUsername, verifyPassword };
|
|
296
|
+
export { ETAG_ALGORITHMS, HASH_ALGORITHMS, HASH_BITS, ROUND_OPTIONS, SRI_ALGORITHMS, createEntry, generateBcryptHash, generateEtag, generateHtpasswdFile, generateMd5Hash, generatePlain, generateSha1Hash, generateSri, generateSriAll, hashAll, hashOne, hashPassword, hashWithTiming, hashing_exports, parseHtpasswdFile, validateRounds, validateUsername, verifyPassword };
|
|
@@ -8,6 +8,7 @@ __export(network_exports, {
|
|
|
8
8
|
LINK_REL_VALUES: () => LINK_REL_VALUES,
|
|
9
9
|
REFERRER_POLICY_VALUES: () => REFERRER_POLICY_VALUES,
|
|
10
10
|
STATUS_CODES: () => STATUS_CODES,
|
|
11
|
+
analyzeEmailHeaders: () => analyzeEmailHeaders,
|
|
11
12
|
buildCacheControl: () => buildCacheControl,
|
|
12
13
|
buildDnsQueryUrl: () => buildDnsQueryUrl,
|
|
13
14
|
buildGeoUrl: () => buildGeoUrl,
|
|
@@ -2130,5 +2131,83 @@ function checkSetCookieHeader(header) {
|
|
|
2130
2131
|
}
|
|
2131
2132
|
return { cookie, issues, warnings, valid: issues.length === 0 };
|
|
2132
2133
|
}
|
|
2134
|
+
function analyzeEmailHeaders(raw) {
|
|
2135
|
+
if (typeof raw !== "string" || !raw.trim()) {
|
|
2136
|
+
return { error: "Raw email header text is required" };
|
|
2137
|
+
}
|
|
2138
|
+
const normalized = raw.replace(/\r\n/g, "\n");
|
|
2139
|
+
const blockEnd = normalized.indexOf("\n\n");
|
|
2140
|
+
const headerBlock = blockEnd === -1 ? normalized : normalized.slice(0, blockEnd);
|
|
2141
|
+
const rawLines = headerBlock.split("\n");
|
|
2142
|
+
const unfolded = [];
|
|
2143
|
+
for (const line of rawLines) {
|
|
2144
|
+
if (/^[ \t]/.test(line) && unfolded.length > 0) {
|
|
2145
|
+
unfolded[unfolded.length - 1] += " " + line.trim();
|
|
2146
|
+
} else if (line.trim() !== "") {
|
|
2147
|
+
unfolded.push(line);
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
const headers = [];
|
|
2151
|
+
for (const line of unfolded) {
|
|
2152
|
+
const colonIdx = line.indexOf(":");
|
|
2153
|
+
if (colonIdx === -1) continue;
|
|
2154
|
+
const name = line.slice(0, colonIdx).trim();
|
|
2155
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
2156
|
+
if (!name) continue;
|
|
2157
|
+
headers.push({ name, value });
|
|
2158
|
+
}
|
|
2159
|
+
if (headers.length === 0) {
|
|
2160
|
+
return { error: 'No parseable headers found \u2014 expected lines like "From: ..." or "Received: ..."' };
|
|
2161
|
+
}
|
|
2162
|
+
const findFirst = (name) => headers.find((h) => h.name.toLowerCase() === name.toLowerCase())?.value ?? null;
|
|
2163
|
+
const findAll = (name) => headers.filter((h) => h.name.toLowerCase() === name.toLowerCase());
|
|
2164
|
+
const receivedHops = findAll("received").map((h, i) => {
|
|
2165
|
+
const fromMatch = h.value.match(/from\s+([^\s;]+(?:\s*\([^)]*\))?)/i);
|
|
2166
|
+
const byMatch = h.value.match(/\bby\s+([^\s;]+)/i);
|
|
2167
|
+
const segments = h.value.split(";");
|
|
2168
|
+
const date = segments.length > 1 ? segments[segments.length - 1].trim() : null;
|
|
2169
|
+
return {
|
|
2170
|
+
index: i + 1,
|
|
2171
|
+
raw: h.value,
|
|
2172
|
+
from: fromMatch ? fromMatch[1].trim() : null,
|
|
2173
|
+
by: byMatch ? byMatch[1].trim() : null,
|
|
2174
|
+
date: date || null
|
|
2175
|
+
};
|
|
2176
|
+
});
|
|
2177
|
+
const authResultsHeader = findFirst("authentication-results");
|
|
2178
|
+
const authResults = [];
|
|
2179
|
+
if (authResultsHeader) {
|
|
2180
|
+
const re = /\b(spf|dkim|dmarc)=(\w+)/gi;
|
|
2181
|
+
let m;
|
|
2182
|
+
while ((m = re.exec(authResultsHeader)) !== null) {
|
|
2183
|
+
authResults.push({ mechanism: m[1].toLowerCase(), result: m[2].toLowerCase() });
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
const findAuth = (mechanism) => authResults.find((a) => a.mechanism === mechanism)?.result ?? null;
|
|
2187
|
+
const warnings = [];
|
|
2188
|
+
if (receivedHops.length === 0) {
|
|
2189
|
+
warnings.push("No Received headers found \u2014 this may be a partial header block rather than a full raw source.");
|
|
2190
|
+
}
|
|
2191
|
+
if (!authResultsHeader) {
|
|
2192
|
+
warnings.push("No Authentication-Results header found \u2014 SPF/DKIM/DMARC cannot be determined from this header block alone.");
|
|
2193
|
+
}
|
|
2194
|
+
return {
|
|
2195
|
+
headers,
|
|
2196
|
+
from: findFirst("from"),
|
|
2197
|
+
to: findFirst("to"),
|
|
2198
|
+
subject: findFirst("subject"),
|
|
2199
|
+
date: findFirst("date"),
|
|
2200
|
+
messageId: findFirst("message-id"),
|
|
2201
|
+
returnPath: findFirst("return-path"),
|
|
2202
|
+
replyTo: findFirst("reply-to"),
|
|
2203
|
+
receivedHops,
|
|
2204
|
+
hopCount: receivedHops.length,
|
|
2205
|
+
authResults,
|
|
2206
|
+
spf: findAuth("spf"),
|
|
2207
|
+
dkim: findAuth("dkim"),
|
|
2208
|
+
dmarc: findAuth("dmarc"),
|
|
2209
|
+
warnings
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2133
2212
|
|
|
2134
|
-
export { DNS_RECORD_TYPES, HTTP_HEADERS, LINK_REL_VALUES, REFERRER_POLICY_VALUES, STATUS_CODES, buildCacheControl, buildDnsQueryUrl, buildGeoUrl, buildLinkHeader, buildMapUrl, buildReferrerPolicy, checkSetCookieHeader, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseDnsResponse, parseGeoResponse, parseHar, parseIpv6Address, parseUserAgent, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateRobotsTxt, validateSitemap };
|
|
2213
|
+
export { DNS_RECORD_TYPES, HTTP_HEADERS, LINK_REL_VALUES, REFERRER_POLICY_VALUES, STATUS_CODES, analyzeEmailHeaders, buildCacheControl, buildDnsQueryUrl, buildGeoUrl, buildLinkHeader, buildMapUrl, buildReferrerPolicy, checkSetCookieHeader, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseDnsResponse, parseGeoResponse, parseHar, parseIpv6Address, parseUserAgent, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateRobotsTxt, validateSitemap };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @utilix/sdk — hashing module
|
|
3
|
+
*
|
|
4
|
+
* Tools covered:
|
|
5
|
+
* - hash-generator : hashAll, hashOne (MD5, SHA-1, SHA-256, SHA-384, SHA-512)
|
|
6
|
+
* - bcrypt-tool : hashPassword, verifyPassword, hashWithTiming, validateRounds
|
|
7
|
+
* - htpasswd : generateSha1Hash, generateMd5Hash, generateBcryptHash,
|
|
8
|
+
* generatePlain, createEntry, parseHtpasswdFile,
|
|
9
|
+
* generateHtpasswdFile, validateUsername
|
|
10
|
+
* - sri-hash-generator: generateSri, generateSriAll (SHA-256/384/512 Subresource Integrity hashes)
|
|
11
|
+
* - etag-generator : generateEtag (MD5/SHA-1/SHA-256 content-hash ETag header values)
|
|
12
|
+
*/
|
|
13
|
+
type HashAlgorithm = 'MD5' | 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512';
|
|
14
|
+
declare const HASH_ALGORITHMS: HashAlgorithm[];
|
|
15
|
+
declare const HASH_BITS: Record<HashAlgorithm, number>;
|
|
16
|
+
interface HashResult {
|
|
17
|
+
algorithm: HashAlgorithm;
|
|
18
|
+
hex: string;
|
|
19
|
+
bits: number;
|
|
20
|
+
}
|
|
21
|
+
declare function hashAll(input: string): Promise<HashResult[]>;
|
|
22
|
+
declare function hashOne(algorithm: HashAlgorithm, input: string): Promise<string>;
|
|
23
|
+
declare const ROUND_OPTIONS: readonly [8, 10, 12, 14];
|
|
24
|
+
declare function hashPassword(password: string, rounds?: number): Promise<string>;
|
|
25
|
+
declare function verifyPassword(password: string, hash: string): Promise<boolean>;
|
|
26
|
+
interface BcryptResult {
|
|
27
|
+
hash: string;
|
|
28
|
+
rounds: number;
|
|
29
|
+
timingMs: number;
|
|
30
|
+
}
|
|
31
|
+
declare function hashWithTiming(password: string, rounds: number): Promise<BcryptResult>;
|
|
32
|
+
declare function validateRounds(rounds: number): {
|
|
33
|
+
valid: boolean;
|
|
34
|
+
warning?: string;
|
|
35
|
+
};
|
|
36
|
+
type HtpasswdAlgorithm = 'bcrypt' | 'sha1' | 'md5' | 'plain';
|
|
37
|
+
interface HtpasswdEntry {
|
|
38
|
+
username: string;
|
|
39
|
+
hashedPassword: string;
|
|
40
|
+
algorithm: HtpasswdAlgorithm;
|
|
41
|
+
line: string;
|
|
42
|
+
}
|
|
43
|
+
declare function generateSha1Hash(password: string): string;
|
|
44
|
+
declare function generateMd5Hash(password: string): string;
|
|
45
|
+
declare function generateBcryptHash(password: string, rounds?: number): string;
|
|
46
|
+
declare function generatePlain(password: string): string;
|
|
47
|
+
declare function createEntry(username: string, password: string, algorithm?: HtpasswdAlgorithm): HtpasswdEntry;
|
|
48
|
+
declare function parseHtpasswdFile(content: string): HtpasswdEntry[];
|
|
49
|
+
declare function generateHtpasswdFile(entries: HtpasswdEntry[]): string;
|
|
50
|
+
declare function validateUsername(username: string): boolean;
|
|
51
|
+
type SriAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512';
|
|
52
|
+
declare const SRI_ALGORITHMS: SriAlgorithm[];
|
|
53
|
+
interface SriResult {
|
|
54
|
+
algorithm: SriAlgorithm;
|
|
55
|
+
base64: string;
|
|
56
|
+
integrity: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Compute a Subresource Integrity hash for the given file/script content:
|
|
60
|
+
* digest it with the chosen algorithm and base64-encode it into the
|
|
61
|
+
* `<algorithm>-<base64>` form used by an HTML `integrity` attribute.
|
|
62
|
+
*/
|
|
63
|
+
declare function generateSri(content: string, algorithm?: SriAlgorithm): SriResult | {
|
|
64
|
+
error: string;
|
|
65
|
+
};
|
|
66
|
+
/** Compute SRI hashes for all three algorithms SRI supports (SHA-256/384/512). */
|
|
67
|
+
declare function generateSriAll(content: string): SriResult[] | {
|
|
68
|
+
error: string;
|
|
69
|
+
};
|
|
70
|
+
type EtagAlgorithm = 'MD5' | 'SHA-1' | 'SHA-256';
|
|
71
|
+
declare const ETAG_ALGORITHMS: EtagAlgorithm[];
|
|
72
|
+
interface EtagResult {
|
|
73
|
+
algorithm: EtagAlgorithm;
|
|
74
|
+
weak: boolean;
|
|
75
|
+
hash: string;
|
|
76
|
+
etag: string;
|
|
77
|
+
headerName: 'ETag';
|
|
78
|
+
snippet: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Compute a content-hash ETag for the given content: digest it with the
|
|
82
|
+
* chosen algorithm, hex-encode it, and quote it into the exact string an
|
|
83
|
+
* ETag response header expects, with an optional weak-validator (W/)
|
|
84
|
+
* prefix. This hashes whatever content you give it; it does not replicate
|
|
85
|
+
* any specific web server's own ETag algorithm, which is often based on
|
|
86
|
+
* file size and modification time instead of content.
|
|
87
|
+
*/
|
|
88
|
+
declare function generateEtag(content: string, algorithm?: EtagAlgorithm, weak?: boolean): EtagResult | {
|
|
89
|
+
error: string;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
type hashing_BcryptResult = BcryptResult;
|
|
93
|
+
declare const hashing_ETAG_ALGORITHMS: typeof ETAG_ALGORITHMS;
|
|
94
|
+
type hashing_EtagAlgorithm = EtagAlgorithm;
|
|
95
|
+
type hashing_EtagResult = EtagResult;
|
|
96
|
+
declare const hashing_HASH_ALGORITHMS: typeof HASH_ALGORITHMS;
|
|
97
|
+
declare const hashing_HASH_BITS: typeof HASH_BITS;
|
|
98
|
+
type hashing_HashAlgorithm = HashAlgorithm;
|
|
99
|
+
type hashing_HashResult = HashResult;
|
|
100
|
+
type hashing_HtpasswdAlgorithm = HtpasswdAlgorithm;
|
|
101
|
+
type hashing_HtpasswdEntry = HtpasswdEntry;
|
|
102
|
+
declare const hashing_ROUND_OPTIONS: typeof ROUND_OPTIONS;
|
|
103
|
+
declare const hashing_SRI_ALGORITHMS: typeof SRI_ALGORITHMS;
|
|
104
|
+
type hashing_SriAlgorithm = SriAlgorithm;
|
|
105
|
+
type hashing_SriResult = SriResult;
|
|
106
|
+
declare const hashing_createEntry: typeof createEntry;
|
|
107
|
+
declare const hashing_generateBcryptHash: typeof generateBcryptHash;
|
|
108
|
+
declare const hashing_generateEtag: typeof generateEtag;
|
|
109
|
+
declare const hashing_generateHtpasswdFile: typeof generateHtpasswdFile;
|
|
110
|
+
declare const hashing_generateMd5Hash: typeof generateMd5Hash;
|
|
111
|
+
declare const hashing_generatePlain: typeof generatePlain;
|
|
112
|
+
declare const hashing_generateSha1Hash: typeof generateSha1Hash;
|
|
113
|
+
declare const hashing_generateSri: typeof generateSri;
|
|
114
|
+
declare const hashing_generateSriAll: typeof generateSriAll;
|
|
115
|
+
declare const hashing_hashAll: typeof hashAll;
|
|
116
|
+
declare const hashing_hashOne: typeof hashOne;
|
|
117
|
+
declare const hashing_hashPassword: typeof hashPassword;
|
|
118
|
+
declare const hashing_hashWithTiming: typeof hashWithTiming;
|
|
119
|
+
declare const hashing_parseHtpasswdFile: typeof parseHtpasswdFile;
|
|
120
|
+
declare const hashing_validateRounds: typeof validateRounds;
|
|
121
|
+
declare const hashing_validateUsername: typeof validateUsername;
|
|
122
|
+
declare const hashing_verifyPassword: typeof verifyPassword;
|
|
123
|
+
declare namespace hashing {
|
|
124
|
+
export { type hashing_BcryptResult as BcryptResult, hashing_ETAG_ALGORITHMS as ETAG_ALGORITHMS, type hashing_EtagAlgorithm as EtagAlgorithm, type hashing_EtagResult as EtagResult, hashing_HASH_ALGORITHMS as HASH_ALGORITHMS, hashing_HASH_BITS as HASH_BITS, type hashing_HashAlgorithm as HashAlgorithm, type hashing_HashResult as HashResult, type hashing_HtpasswdAlgorithm as HtpasswdAlgorithm, type hashing_HtpasswdEntry as HtpasswdEntry, hashing_ROUND_OPTIONS as ROUND_OPTIONS, hashing_SRI_ALGORITHMS as SRI_ALGORITHMS, type hashing_SriAlgorithm as SriAlgorithm, type hashing_SriResult as SriResult, hashing_createEntry as createEntry, hashing_generateBcryptHash as generateBcryptHash, hashing_generateEtag as generateEtag, hashing_generateHtpasswdFile as generateHtpasswdFile, hashing_generateMd5Hash as generateMd5Hash, hashing_generatePlain as generatePlain, hashing_generateSha1Hash as generateSha1Hash, hashing_generateSri as generateSri, hashing_generateSriAll as generateSriAll, hashing_hashAll as hashAll, hashing_hashOne as hashOne, hashing_hashPassword as hashPassword, hashing_hashWithTiming as hashWithTiming, hashing_parseHtpasswdFile as parseHtpasswdFile, hashing_validateRounds as validateRounds, hashing_validateUsername as validateUsername, hashing_verifyPassword as verifyPassword };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { verifyPassword as A, type BcryptResult as B, ETAG_ALGORITHMS as E, HASH_ALGORITHMS as H, ROUND_OPTIONS as R, SRI_ALGORITHMS as S, type EtagAlgorithm as a, type EtagResult as b, HASH_BITS as c, type HashAlgorithm as d, type HashResult as e, type HtpasswdAlgorithm as f, type HtpasswdEntry as g, hashing as h, type SriAlgorithm as i, type SriResult as j, createEntry as k, generateBcryptHash as l, generateEtag as m, generateHtpasswdFile as n, generateMd5Hash as o, generatePlain as p, generateSha1Hash as q, generateSri as r, generateSriAll as s, hashAll as t, hashOne as u, hashPassword as v, hashWithTiming as w, parseHtpasswdFile as x, validateRounds as y, validateUsername as z };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @utilix/sdk — hashing module
|
|
3
|
+
*
|
|
4
|
+
* Tools covered:
|
|
5
|
+
* - hash-generator : hashAll, hashOne (MD5, SHA-1, SHA-256, SHA-384, SHA-512)
|
|
6
|
+
* - bcrypt-tool : hashPassword, verifyPassword, hashWithTiming, validateRounds
|
|
7
|
+
* - htpasswd : generateSha1Hash, generateMd5Hash, generateBcryptHash,
|
|
8
|
+
* generatePlain, createEntry, parseHtpasswdFile,
|
|
9
|
+
* generateHtpasswdFile, validateUsername
|
|
10
|
+
* - sri-hash-generator: generateSri, generateSriAll (SHA-256/384/512 Subresource Integrity hashes)
|
|
11
|
+
* - etag-generator : generateEtag (MD5/SHA-1/SHA-256 content-hash ETag header values)
|
|
12
|
+
*/
|
|
13
|
+
type HashAlgorithm = 'MD5' | 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512';
|
|
14
|
+
declare const HASH_ALGORITHMS: HashAlgorithm[];
|
|
15
|
+
declare const HASH_BITS: Record<HashAlgorithm, number>;
|
|
16
|
+
interface HashResult {
|
|
17
|
+
algorithm: HashAlgorithm;
|
|
18
|
+
hex: string;
|
|
19
|
+
bits: number;
|
|
20
|
+
}
|
|
21
|
+
declare function hashAll(input: string): Promise<HashResult[]>;
|
|
22
|
+
declare function hashOne(algorithm: HashAlgorithm, input: string): Promise<string>;
|
|
23
|
+
declare const ROUND_OPTIONS: readonly [8, 10, 12, 14];
|
|
24
|
+
declare function hashPassword(password: string, rounds?: number): Promise<string>;
|
|
25
|
+
declare function verifyPassword(password: string, hash: string): Promise<boolean>;
|
|
26
|
+
interface BcryptResult {
|
|
27
|
+
hash: string;
|
|
28
|
+
rounds: number;
|
|
29
|
+
timingMs: number;
|
|
30
|
+
}
|
|
31
|
+
declare function hashWithTiming(password: string, rounds: number): Promise<BcryptResult>;
|
|
32
|
+
declare function validateRounds(rounds: number): {
|
|
33
|
+
valid: boolean;
|
|
34
|
+
warning?: string;
|
|
35
|
+
};
|
|
36
|
+
type HtpasswdAlgorithm = 'bcrypt' | 'sha1' | 'md5' | 'plain';
|
|
37
|
+
interface HtpasswdEntry {
|
|
38
|
+
username: string;
|
|
39
|
+
hashedPassword: string;
|
|
40
|
+
algorithm: HtpasswdAlgorithm;
|
|
41
|
+
line: string;
|
|
42
|
+
}
|
|
43
|
+
declare function generateSha1Hash(password: string): string;
|
|
44
|
+
declare function generateMd5Hash(password: string): string;
|
|
45
|
+
declare function generateBcryptHash(password: string, rounds?: number): string;
|
|
46
|
+
declare function generatePlain(password: string): string;
|
|
47
|
+
declare function createEntry(username: string, password: string, algorithm?: HtpasswdAlgorithm): HtpasswdEntry;
|
|
48
|
+
declare function parseHtpasswdFile(content: string): HtpasswdEntry[];
|
|
49
|
+
declare function generateHtpasswdFile(entries: HtpasswdEntry[]): string;
|
|
50
|
+
declare function validateUsername(username: string): boolean;
|
|
51
|
+
type SriAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512';
|
|
52
|
+
declare const SRI_ALGORITHMS: SriAlgorithm[];
|
|
53
|
+
interface SriResult {
|
|
54
|
+
algorithm: SriAlgorithm;
|
|
55
|
+
base64: string;
|
|
56
|
+
integrity: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Compute a Subresource Integrity hash for the given file/script content:
|
|
60
|
+
* digest it with the chosen algorithm and base64-encode it into the
|
|
61
|
+
* `<algorithm>-<base64>` form used by an HTML `integrity` attribute.
|
|
62
|
+
*/
|
|
63
|
+
declare function generateSri(content: string, algorithm?: SriAlgorithm): SriResult | {
|
|
64
|
+
error: string;
|
|
65
|
+
};
|
|
66
|
+
/** Compute SRI hashes for all three algorithms SRI supports (SHA-256/384/512). */
|
|
67
|
+
declare function generateSriAll(content: string): SriResult[] | {
|
|
68
|
+
error: string;
|
|
69
|
+
};
|
|
70
|
+
type EtagAlgorithm = 'MD5' | 'SHA-1' | 'SHA-256';
|
|
71
|
+
declare const ETAG_ALGORITHMS: EtagAlgorithm[];
|
|
72
|
+
interface EtagResult {
|
|
73
|
+
algorithm: EtagAlgorithm;
|
|
74
|
+
weak: boolean;
|
|
75
|
+
hash: string;
|
|
76
|
+
etag: string;
|
|
77
|
+
headerName: 'ETag';
|
|
78
|
+
snippet: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Compute a content-hash ETag for the given content: digest it with the
|
|
82
|
+
* chosen algorithm, hex-encode it, and quote it into the exact string an
|
|
83
|
+
* ETag response header expects, with an optional weak-validator (W/)
|
|
84
|
+
* prefix. This hashes whatever content you give it; it does not replicate
|
|
85
|
+
* any specific web server's own ETag algorithm, which is often based on
|
|
86
|
+
* file size and modification time instead of content.
|
|
87
|
+
*/
|
|
88
|
+
declare function generateEtag(content: string, algorithm?: EtagAlgorithm, weak?: boolean): EtagResult | {
|
|
89
|
+
error: string;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
type hashing_BcryptResult = BcryptResult;
|
|
93
|
+
declare const hashing_ETAG_ALGORITHMS: typeof ETAG_ALGORITHMS;
|
|
94
|
+
type hashing_EtagAlgorithm = EtagAlgorithm;
|
|
95
|
+
type hashing_EtagResult = EtagResult;
|
|
96
|
+
declare const hashing_HASH_ALGORITHMS: typeof HASH_ALGORITHMS;
|
|
97
|
+
declare const hashing_HASH_BITS: typeof HASH_BITS;
|
|
98
|
+
type hashing_HashAlgorithm = HashAlgorithm;
|
|
99
|
+
type hashing_HashResult = HashResult;
|
|
100
|
+
type hashing_HtpasswdAlgorithm = HtpasswdAlgorithm;
|
|
101
|
+
type hashing_HtpasswdEntry = HtpasswdEntry;
|
|
102
|
+
declare const hashing_ROUND_OPTIONS: typeof ROUND_OPTIONS;
|
|
103
|
+
declare const hashing_SRI_ALGORITHMS: typeof SRI_ALGORITHMS;
|
|
104
|
+
type hashing_SriAlgorithm = SriAlgorithm;
|
|
105
|
+
type hashing_SriResult = SriResult;
|
|
106
|
+
declare const hashing_createEntry: typeof createEntry;
|
|
107
|
+
declare const hashing_generateBcryptHash: typeof generateBcryptHash;
|
|
108
|
+
declare const hashing_generateEtag: typeof generateEtag;
|
|
109
|
+
declare const hashing_generateHtpasswdFile: typeof generateHtpasswdFile;
|
|
110
|
+
declare const hashing_generateMd5Hash: typeof generateMd5Hash;
|
|
111
|
+
declare const hashing_generatePlain: typeof generatePlain;
|
|
112
|
+
declare const hashing_generateSha1Hash: typeof generateSha1Hash;
|
|
113
|
+
declare const hashing_generateSri: typeof generateSri;
|
|
114
|
+
declare const hashing_generateSriAll: typeof generateSriAll;
|
|
115
|
+
declare const hashing_hashAll: typeof hashAll;
|
|
116
|
+
declare const hashing_hashOne: typeof hashOne;
|
|
117
|
+
declare const hashing_hashPassword: typeof hashPassword;
|
|
118
|
+
declare const hashing_hashWithTiming: typeof hashWithTiming;
|
|
119
|
+
declare const hashing_parseHtpasswdFile: typeof parseHtpasswdFile;
|
|
120
|
+
declare const hashing_validateRounds: typeof validateRounds;
|
|
121
|
+
declare const hashing_validateUsername: typeof validateUsername;
|
|
122
|
+
declare const hashing_verifyPassword: typeof verifyPassword;
|
|
123
|
+
declare namespace hashing {
|
|
124
|
+
export { type hashing_BcryptResult as BcryptResult, hashing_ETAG_ALGORITHMS as ETAG_ALGORITHMS, type hashing_EtagAlgorithm as EtagAlgorithm, type hashing_EtagResult as EtagResult, hashing_HASH_ALGORITHMS as HASH_ALGORITHMS, hashing_HASH_BITS as HASH_BITS, type hashing_HashAlgorithm as HashAlgorithm, type hashing_HashResult as HashResult, type hashing_HtpasswdAlgorithm as HtpasswdAlgorithm, type hashing_HtpasswdEntry as HtpasswdEntry, hashing_ROUND_OPTIONS as ROUND_OPTIONS, hashing_SRI_ALGORITHMS as SRI_ALGORITHMS, type hashing_SriAlgorithm as SriAlgorithm, type hashing_SriResult as SriResult, hashing_createEntry as createEntry, hashing_generateBcryptHash as generateBcryptHash, hashing_generateEtag as generateEtag, hashing_generateHtpasswdFile as generateHtpasswdFile, hashing_generateMd5Hash as generateMd5Hash, hashing_generatePlain as generatePlain, hashing_generateSha1Hash as generateSha1Hash, hashing_generateSri as generateSri, hashing_generateSriAll as generateSriAll, hashing_hashAll as hashAll, hashing_hashOne as hashOne, hashing_hashPassword as hashPassword, hashing_hashWithTiming as hashWithTiming, hashing_parseHtpasswdFile as parseHtpasswdFile, hashing_validateRounds as validateRounds, hashing_validateUsername as validateUsername, hashing_verifyPassword as verifyPassword };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { verifyPassword as A, type BcryptResult as B, ETAG_ALGORITHMS as E, HASH_ALGORITHMS as H, ROUND_OPTIONS as R, SRI_ALGORITHMS as S, type EtagAlgorithm as a, type EtagResult as b, HASH_BITS as c, type HashAlgorithm as d, type HashResult as e, type HtpasswdAlgorithm as f, type HtpasswdEntry as g, hashing as h, type SriAlgorithm as i, type SriResult as j, createEntry as k, generateBcryptHash as l, generateEtag as m, generateHtpasswdFile as n, generateMd5Hash as o, generatePlain as p, generateSha1Hash as q, generateSri as r, generateSriAll as s, hashAll as t, hashOne as u, hashPassword as v, hashWithTiming as w, parseHtpasswdFile as x, validateRounds as y, validateUsername as z };
|