@interop/http-digest-header 2.3.2 → 3.0.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/README.md +49 -18
- package/dist/digest-reactnative.d.ts +2 -0
- package/dist/digest-reactnative.d.ts.map +1 -0
- package/{lib → dist}/digest-reactnative.js +2 -3
- package/dist/digest-reactnative.js.map +1 -0
- package/dist/digest.d.ts +2 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +8 -0
- package/dist/digest.js.map +1 -0
- package/dist/httpDigest.d.ts +36 -0
- package/dist/httpDigest.d.ts.map +1 -0
- package/dist/httpDigest.js +120 -0
- package/dist/httpDigest.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/util-browser.d.ts +6 -0
- package/dist/util-browser.d.ts.map +1 -0
- package/dist/util-browser.js +21 -0
- package/dist/util-browser.js.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +10 -0
- package/dist/util.js.map +1 -0
- package/package.json +50 -44
- package/lib/digest.js +0 -8
- package/lib/httpDigest.js +0 -127
- package/lib/index.js +0 -4
- package/lib/util-browser.js +0 -19
- package/lib/util.js +0 -12
- package/types/httpDigest.d.ts +0 -36
- package/types/index.d.ts +0 -1
- package/types/lib/httpDigest.d.ts +0 -36
- package/types/lib/index.d.ts +0 -1
- package/types/lib/util.d.ts +0 -5
- package/types/util.d.ts +0 -5
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# HTTP Digest Header Library _(@interop/http-digest-header)_
|
|
2
2
|
|
|
3
|
-
[](https://github.com/interop-alliance/http-digest-header/actions?query=workflow%3A%22CI%22)
|
|
4
|
+
[](https://github.com/interop-alliance/http-digest-header/actions/workflows/ci.yml)
|
|
4
5
|
|
|
5
|
-
> JavaScript library (Node.js, browser and React Native) for creating and
|
|
6
|
+
> JavaScript library (Node.js, browser and React Native) for creating and
|
|
7
|
+
> verifying Digest headers for HTTP Signatures
|
|
6
8
|
|
|
7
9
|
## Table of Contents
|
|
8
10
|
|
|
@@ -16,12 +18,14 @@
|
|
|
16
18
|
## Background
|
|
17
19
|
|
|
18
20
|
**FORKED FROM**: https://github.com/digitalbazaar/http-digest-header to provide
|
|
19
|
-
support for React Native
|
|
21
|
+
support for React Native and add TypeScript types.
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
- For React Native use: the `expo-crypto` peer dependency is required (see
|
|
24
|
+
[Usage in React Native](#usage-in-react-native)).
|
|
22
25
|
|
|
23
26
|
Originally, this library was implemented based on the `Digest` header as
|
|
24
|
-
mentioned in
|
|
27
|
+
mentioned in
|
|
28
|
+
**[HTTP Signatures IETF draft](https://tools.ietf.org/html/draft-cavage-http-signatures)**.
|
|
25
29
|
|
|
26
30
|
Since then, the `Digest` header got its own standards-track spec, at
|
|
27
31
|
https://tools.ietf.org/html/draft-ietf-httpbis-digest-headers.
|
|
@@ -34,7 +38,7 @@ with Node.js).
|
|
|
34
38
|
|
|
35
39
|
## Install
|
|
36
40
|
|
|
37
|
-
- Browsers and Node.js
|
|
41
|
+
- Browsers and Node.js 24+ supported.
|
|
38
42
|
- [Web Crypto API][] required. Older browsers and Node.js 14 must use a
|
|
39
43
|
polyfill.
|
|
40
44
|
|
|
@@ -49,29 +53,55 @@ To install locally (for development):
|
|
|
49
53
|
```
|
|
50
54
|
git clone https://github.com/interop-alliance/http-digest-header.git
|
|
51
55
|
cd http-digest-header
|
|
52
|
-
|
|
56
|
+
pnpm install
|
|
53
57
|
```
|
|
54
58
|
|
|
55
59
|
## Usage
|
|
56
60
|
|
|
57
61
|
```js
|
|
58
|
-
import * as httpDigest from '@interop/http-digest-header'
|
|
62
|
+
import * as httpDigest from '@interop/http-digest-header'
|
|
59
63
|
|
|
60
|
-
const data = `{"hello": "world"}
|
|
64
|
+
const data = `{"hello": "world"}`
|
|
61
65
|
|
|
62
|
-
const headerValue = await httpDigest.
|
|
63
|
-
|
|
66
|
+
const headerValue = await httpDigest.createHeaderValue({
|
|
67
|
+
data,
|
|
68
|
+
algorithm: 'sha256',
|
|
69
|
+
useMultihash: false
|
|
70
|
+
})
|
|
64
71
|
// -> SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
|
|
65
72
|
|
|
66
|
-
const dataToVerify1 = `{"hello": "world"}
|
|
67
|
-
const dataToVerify2 = `{"hello": "planet earth"}
|
|
73
|
+
const dataToVerify1 = `{"hello": "world"}`
|
|
74
|
+
const dataToVerify2 = `{"hello": "planet earth"}`
|
|
68
75
|
|
|
69
|
-
const verifyResult = await httpDigest.verifyHeaderValue({
|
|
76
|
+
const verifyResult = await httpDigest.verifyHeaderValue({
|
|
77
|
+
data: dataToVerify1,
|
|
78
|
+
headerValue
|
|
79
|
+
})
|
|
70
80
|
// -> { verified: true }
|
|
71
|
-
const verifyResult = await httpDigest.verifyHeaderValue({
|
|
81
|
+
const verifyResult = await httpDigest.verifyHeaderValue({
|
|
82
|
+
data: dataToVerify2,
|
|
83
|
+
headerValue
|
|
84
|
+
})
|
|
72
85
|
// -> { verified: false }
|
|
73
86
|
```
|
|
74
87
|
|
|
88
|
+
### Usage in React Native
|
|
89
|
+
|
|
90
|
+
In React Native, this library's `react-native` export resolves the digest
|
|
91
|
+
implementation to one backed by
|
|
92
|
+
[`expo-crypto`](https://docs.expo.dev/versions/latest/sdk/crypto/) (it imports
|
|
93
|
+
`expo-crypto` directly -- no `crypto.subtle` polyfill or global shim required).
|
|
94
|
+
|
|
95
|
+
`expo-crypto` is declared as an (optional) peer dependency, so just make sure it
|
|
96
|
+
is installed in your app:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
npx expo install expo-crypto
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
If `expo-crypto` is missing, `createHeaderValue` / `verifyHeaderValue` will fail
|
|
103
|
+
to resolve their digest dependency at bundle time.
|
|
104
|
+
|
|
75
105
|
## Contribute
|
|
76
106
|
|
|
77
107
|
Please follow the existing code style.
|
|
@@ -83,11 +113,12 @@ If editing the Readme, please conform to the
|
|
|
83
113
|
|
|
84
114
|
## Commercial Support
|
|
85
115
|
|
|
86
|
-
Commercial support for this library is available upon request from
|
|
87
|
-
|
|
116
|
+
Commercial support for this library is available upon request from Digital
|
|
117
|
+
Bazaar: support@digitalbazaar.com
|
|
88
118
|
|
|
89
119
|
## License
|
|
90
120
|
|
|
91
121
|
[BSD-3-Clause](LICENSE.md) © 2019-2025 Digital Bazaar
|
|
92
122
|
|
|
93
|
-
[Web Crypto API]:
|
|
123
|
+
[Web Crypto API]:
|
|
124
|
+
https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest-reactnative.d.ts","sourceRoot":"","sources":["../src/digest-reactnative.ts"],"names":[],"mappings":"AAKA,wBAAsB,MAAM,CAC1B,IAAI,EAAE,UAAU,GAAG,WAAW,GAC7B,OAAO,CAAC,UAAU,CAAC,CAOrB"}
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2021-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import * as Crypto from 'expo-crypto';
|
|
5
|
-
|
|
6
5
|
export async function sha256(data) {
|
|
7
|
-
|
|
8
|
-
await Crypto.digest(Crypto.CryptoDigestAlgorithm.SHA256, data));
|
|
6
|
+
return new Uint8Array(await Crypto.digest(Crypto.CryptoDigestAlgorithm.SHA256, data));
|
|
9
7
|
}
|
|
8
|
+
//# sourceMappingURL=digest-reactnative.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest-reactnative.js","sourceRoot":"","sources":["../src/digest-reactnative.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,IAA8B;IAE9B,OAAO,IAAI,UAAU,CACnB,MAAM,MAAM,CAAC,MAAM,CACjB,MAAM,CAAC,qBAAqB,CAAC,MAAM,EACnC,IAAoB,CACrB,CACF,CAAA;AACH,CAAC"}
|
package/dist/digest.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAKA,wBAAsB,MAAM,CAC1B,IAAI,EAAE,UAAU,GAAG,WAAW,GAC7B,OAAO,CAAC,UAAU,CAAC,CAIrB"}
|
package/dist/digest.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2021-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
const { crypto } = globalThis;
|
|
5
|
+
export async function sha256(data) {
|
|
6
|
+
return new Uint8Array(await crypto.subtle.digest({ name: 'SHA-256' }, data));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.js","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;AAE7B,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,IAA8B;IAE9B,OAAO,IAAI,UAAU,CACnB,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,IAAoB,CAAC,CACtE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
type DigestData = string | object | Blob | Uint8Array;
|
|
2
|
+
/**
|
|
3
|
+
* Creates a value suitable for the HTTP `Digest` header.
|
|
4
|
+
*
|
|
5
|
+
* @param options - The options to use.
|
|
6
|
+
* @param options.data - The data to be hashed (a request or response body).
|
|
7
|
+
* @param options.algorithm - Hash algorithm to use (e.g. 'sha256').
|
|
8
|
+
* @param options.useMultihash - Whether to encode via multihash; if false, the
|
|
9
|
+
* hash will be base64-encoded (non-url).
|
|
10
|
+
*
|
|
11
|
+
* @returns Resolves to `Digest` header value.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createHeaderValue({ data, algorithm, useMultihash }?: {
|
|
14
|
+
data?: DigestData;
|
|
15
|
+
algorithm?: string;
|
|
16
|
+
useMultihash?: boolean;
|
|
17
|
+
}): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Verifies the HTTP `Digest` header value against the given HTTP body `data`.
|
|
20
|
+
*
|
|
21
|
+
* @param options - The options to use.
|
|
22
|
+
* @param options.data - The data to be verified (a request or response body).
|
|
23
|
+
* @param options.headerValue - The digest header value to verify the data
|
|
24
|
+
* against.
|
|
25
|
+
*
|
|
26
|
+
* @returns Resolves to the verification result.
|
|
27
|
+
*/
|
|
28
|
+
export declare function verifyHeaderValue({ data, headerValue }: {
|
|
29
|
+
data: DigestData;
|
|
30
|
+
headerValue: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
verified: boolean;
|
|
33
|
+
error?: Error;
|
|
34
|
+
}>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=httpDigest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpDigest.d.ts","sourceRoot":"","sources":["../src/httpDigest.ts"],"names":[],"mappings":"AAMA,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,UAAU,CAAA;AAErD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,IAAI,EACJ,SAAoB,EACpB,YAAmB,EACpB,GAAE;IACD,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CAOvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,IAAI,EACJ,WAAW,EACZ,EAAE;IACD,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAahD"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2019-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { base64Encode, base64urlEncode } from './util.js';
|
|
5
|
+
import { sha256 } from './digest.js';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a value suitable for the HTTP `Digest` header.
|
|
8
|
+
*
|
|
9
|
+
* @param options - The options to use.
|
|
10
|
+
* @param options.data - The data to be hashed (a request or response body).
|
|
11
|
+
* @param options.algorithm - Hash algorithm to use (e.g. 'sha256').
|
|
12
|
+
* @param options.useMultihash - Whether to encode via multihash; if false, the
|
|
13
|
+
* hash will be base64-encoded (non-url).
|
|
14
|
+
*
|
|
15
|
+
* @returns Resolves to `Digest` header value.
|
|
16
|
+
*/
|
|
17
|
+
export async function createHeaderValue({ data, algorithm = 'sha256', useMultihash = true } = {}) {
|
|
18
|
+
const { key, encodedDigest } = await _createHeaderValueComponents({
|
|
19
|
+
data,
|
|
20
|
+
algorithm,
|
|
21
|
+
useMultihash
|
|
22
|
+
});
|
|
23
|
+
return `${key}=${encodedDigest}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Verifies the HTTP `Digest` header value against the given HTTP body `data`.
|
|
27
|
+
*
|
|
28
|
+
* @param options - The options to use.
|
|
29
|
+
* @param options.data - The data to be verified (a request or response body).
|
|
30
|
+
* @param options.headerValue - The digest header value to verify the data
|
|
31
|
+
* against.
|
|
32
|
+
*
|
|
33
|
+
* @returns Resolves to the verification result.
|
|
34
|
+
*/
|
|
35
|
+
export async function verifyHeaderValue({ data, headerValue }) {
|
|
36
|
+
try {
|
|
37
|
+
const { key, algorithm, encodedDigest } = _parseHeaderValue(headerValue);
|
|
38
|
+
const { encodedDigest: expectedDigest } = await _createHeaderValueComponents({
|
|
39
|
+
data,
|
|
40
|
+
algorithm,
|
|
41
|
+
useMultihash: key === 'mh'
|
|
42
|
+
});
|
|
43
|
+
return { verified: encodedDigest === expectedDigest };
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
return { verified: false, error: error };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function _createHeaderValueComponents({ data, algorithm = 'sha256', useMultihash = true }) {
|
|
50
|
+
if (algorithm !== 'sha256') {
|
|
51
|
+
throw new Error(`Algorithm "${algorithm}" is not supported.`);
|
|
52
|
+
}
|
|
53
|
+
const digest = await _getDigest({ data, algorithm });
|
|
54
|
+
if (useMultihash) {
|
|
55
|
+
return { key: 'mh', encodedDigest: _createMultihash({ digest }) };
|
|
56
|
+
}
|
|
57
|
+
return { key: 'SHA-256', encodedDigest: base64Encode(digest) };
|
|
58
|
+
}
|
|
59
|
+
function _createMultihash({ digest }) {
|
|
60
|
+
// format as multihash digest
|
|
61
|
+
// sha2-256: 0x12, length: 32 (0x20), digest value
|
|
62
|
+
const mh = new Uint8Array(34);
|
|
63
|
+
mh[0] = 0x12;
|
|
64
|
+
mh[1] = 0x20;
|
|
65
|
+
mh.set(digest, 2);
|
|
66
|
+
// encode multihash using multibase, base64url: `u`
|
|
67
|
+
return `u${base64urlEncode(mh)}`;
|
|
68
|
+
}
|
|
69
|
+
function _parseHeaderValue(headerValue) {
|
|
70
|
+
// `String.prototype.split` always yields at least the part before the first
|
|
71
|
+
// `=` at index 0, so `key` is always a string; `digestValue` may be absent.
|
|
72
|
+
const [key = '', digestValue] = headerValue.split(/=(.+)/);
|
|
73
|
+
let encodedDigest;
|
|
74
|
+
let algorithm;
|
|
75
|
+
if (key === 'mh') {
|
|
76
|
+
if (digestValue === undefined) {
|
|
77
|
+
throw new Error(`Only base64url-encoded, sha-256 multihash is supported.`);
|
|
78
|
+
}
|
|
79
|
+
encodedDigest = digestValue;
|
|
80
|
+
// if `encodedDigest` starts with `uEi`, then it is a base64url-encoded
|
|
81
|
+
// sha-256 multihash
|
|
82
|
+
if (encodedDigest.startsWith('uEi')) {
|
|
83
|
+
algorithm = 'sha256';
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
throw new Error(`Only base64url-encoded, sha-256 multihash is supported.`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// per RFC 9651, the digest value could be a structured field value,
|
|
91
|
+
// expressed as a base64-encoded byte array wrapped in colons
|
|
92
|
+
encodedDigest = digestValue?.replace(/^:(.*):$/, '$1');
|
|
93
|
+
algorithm = key.replace('-', '').toLowerCase();
|
|
94
|
+
if (algorithm !== 'sha256') {
|
|
95
|
+
throw new Error(`Algorithm "${algorithm}" is not supported.`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { key, algorithm, encodedDigest };
|
|
99
|
+
}
|
|
100
|
+
async function _getDigest({ data, algorithm }) {
|
|
101
|
+
const normalized = await _normalizeData(data);
|
|
102
|
+
if (algorithm === 'sha256') {
|
|
103
|
+
return sha256(normalized);
|
|
104
|
+
}
|
|
105
|
+
throw new Error(`Algorithm "${algorithm}" is not unsupported.`);
|
|
106
|
+
}
|
|
107
|
+
// normalize all inputs to a `Uint8Array` for hashing
|
|
108
|
+
async function _normalizeData(data) {
|
|
109
|
+
if (data instanceof Uint8Array) {
|
|
110
|
+
return data;
|
|
111
|
+
}
|
|
112
|
+
if (data instanceof Blob) {
|
|
113
|
+
// `Blob.bytes()` is only available in node.js 22+;
|
|
114
|
+
// fallback to `Blob.arrayBuffer()`
|
|
115
|
+
return data.bytes?.() ?? data.arrayBuffer();
|
|
116
|
+
}
|
|
117
|
+
const str = typeof data === 'string' ? data : JSON.stringify(data);
|
|
118
|
+
return new TextEncoder().encode(str);
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=httpDigest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpDigest.js","sourceRoot":"","sources":["../src/httpDigest.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util-browser.d.ts","sourceRoot":"","sources":["../src/util-browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMtD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CASzD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2021-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
export function base64Encode(bytes) {
|
|
5
|
+
const maybe = bytes;
|
|
6
|
+
if (maybe.toBase64) {
|
|
7
|
+
return maybe.toBase64();
|
|
8
|
+
}
|
|
9
|
+
return btoa(Array.from(bytes, b => String.fromCodePoint(b)).join(''));
|
|
10
|
+
}
|
|
11
|
+
export function base64urlEncode(bytes) {
|
|
12
|
+
const maybe = bytes;
|
|
13
|
+
if (maybe.toBase64) {
|
|
14
|
+
return maybe.toBase64({ alphabet: 'base64url', omitPadding: true });
|
|
15
|
+
}
|
|
16
|
+
return base64Encode(bytes)
|
|
17
|
+
.replace(/\+/g, '-')
|
|
18
|
+
.replace(/\//g, '_')
|
|
19
|
+
.replaceAll('=', '');
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=util-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util-browser.js","sourceRoot":"","sources":["../src/util-browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,MAAM,UAAU,YAAY,CAAC,KAAiB;IAC5C,MAAM,KAAK,GAAG,KAAsB,CAAA;IACpC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAA;IACzB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;AACvE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,MAAM,KAAK,GAAG,KAAsB,CAAA;IACpC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IACrE,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACxB,CAAC"}
|
package/dist/util.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAItD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIzD"}
|
package/dist/util.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2021-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
export function base64Encode(bytes) {
|
|
5
|
+
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64');
|
|
6
|
+
}
|
|
7
|
+
export function base64urlEncode(bytes) {
|
|
8
|
+
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64url');
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAiB;IAC5C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAC3E,QAAQ,CACT,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAC3E,WAAW,CACZ,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,31 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/http-digest-header",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Minimal isomorphic library (Node.js and browser) for creating and verifying Digest headers for HTTP Signatures",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
7
|
+
"build": "pnpm run clear && tsc",
|
|
8
|
+
"clear": "rimraf dist/*",
|
|
9
|
+
"dev": "vite",
|
|
10
|
+
"fix": "eslint --fix src test && pnpm run format",
|
|
11
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"*.md\"",
|
|
12
|
+
"lint": "eslint src test",
|
|
13
|
+
"prepare": "pnpm run build",
|
|
14
|
+
"rebuild": "pnpm run clear && pnpm run build",
|
|
15
|
+
"test": "pnpm run fix && pnpm run lint && pnpm run test:node && pnpm run test:browser",
|
|
16
|
+
"test:browser": "playwright test",
|
|
17
|
+
"test:node": "vitest run",
|
|
18
|
+
"test:coverage": "vitest run --coverage"
|
|
15
19
|
},
|
|
16
20
|
"type": "module",
|
|
17
|
-
"exports":
|
|
18
|
-
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"default": "./dist/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"module": "dist/index.js",
|
|
29
|
+
"types": "dist/index.d.ts",
|
|
30
|
+
"sideEffects": false,
|
|
19
31
|
"browser": {
|
|
20
|
-
"./
|
|
32
|
+
"./dist/util.js": "./dist/util-browser.js"
|
|
21
33
|
},
|
|
22
34
|
"react-native": {
|
|
23
|
-
"./
|
|
24
|
-
"./
|
|
35
|
+
"./dist/util.js": "./dist/util-browser.js",
|
|
36
|
+
"./dist/digest.js": "./dist/digest-reactnative.js"
|
|
25
37
|
},
|
|
26
38
|
"files": [
|
|
27
|
-
"
|
|
28
|
-
"
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE.md"
|
|
29
42
|
],
|
|
30
43
|
"peerDependencies": {
|
|
31
44
|
"expo-crypto": ">=13"
|
|
@@ -36,24 +49,19 @@
|
|
|
36
49
|
}
|
|
37
50
|
},
|
|
38
51
|
"devDependencies": {
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"eslint
|
|
44
|
-
"eslint-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"karma-webpack": "^5.0.0",
|
|
53
|
-
"mocha": "^11.7.4",
|
|
54
|
-
"mocha-lcov-reporter": "^1.3.0",
|
|
55
|
-
"typescript": "^6.0.3",
|
|
56
|
-
"webpack": "^5.73.0"
|
|
52
|
+
"@eslint/js": "^10.0.1",
|
|
53
|
+
"@playwright/test": "^1.60.0",
|
|
54
|
+
"@types/node": "^25.9.3",
|
|
55
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
56
|
+
"eslint": "^10.5.0",
|
|
57
|
+
"eslint-config-prettier": "^10.1.8",
|
|
58
|
+
"globals": "^17.6.0",
|
|
59
|
+
"prettier": "^3.8.4",
|
|
60
|
+
"rimraf": "^6.1.3",
|
|
61
|
+
"typescript": "^5.9.3",
|
|
62
|
+
"typescript-eslint": "^8.61.0",
|
|
63
|
+
"vite": "^8.0.16",
|
|
64
|
+
"vitest": "^4.1.8"
|
|
57
65
|
},
|
|
58
66
|
"repository": {
|
|
59
67
|
"type": "git",
|
|
@@ -70,17 +78,15 @@
|
|
|
70
78
|
"url": "https://digitalbazaar.com/"
|
|
71
79
|
},
|
|
72
80
|
"bugs": {
|
|
73
|
-
"url": "https://github.com/
|
|
81
|
+
"url": "https://github.com/interop-alliance/http-digest-header/issues"
|
|
82
|
+
},
|
|
83
|
+
"homepage": "https://github.com/interop-alliance/http-digest-header",
|
|
84
|
+
"publishConfig": {
|
|
85
|
+
"access": "public",
|
|
86
|
+
"provenance": true
|
|
74
87
|
},
|
|
75
|
-
"homepage": "https://github.com/digitalbazaar/http-digest-header",
|
|
76
88
|
"engines": {
|
|
77
|
-
"node": ">=
|
|
89
|
+
"node": ">=24.0"
|
|
78
90
|
},
|
|
79
|
-
"
|
|
80
|
-
"reporter": [
|
|
81
|
-
"lcov",
|
|
82
|
-
"text-summary",
|
|
83
|
-
"text"
|
|
84
|
-
]
|
|
85
|
-
}
|
|
91
|
+
"packageManager": "pnpm@11.5.0"
|
|
86
92
|
}
|
package/lib/digest.js
DELETED
package/lib/httpDigest.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2019-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
import {base64Encode, base64urlEncode} from './util.js';
|
|
5
|
-
import {sha256} from './digest.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Creates a value suitable for the HTTP `Digest` header.
|
|
9
|
-
*
|
|
10
|
-
* @param {object} options - The options to use.
|
|
11
|
-
* @param {string|object|Blob|Uint8Array} [options.data] - The data to be
|
|
12
|
-
* hashed (a request or response body).
|
|
13
|
-
* @param {string} [options.algorithm] - Hash algorithm to use.
|
|
14
|
-
* (e.g. 'sha256').
|
|
15
|
-
* @param {boolean} [options.useMultihash=true] - Whether to encode via
|
|
16
|
-
* multihash; if false, the hash will be base64-encoded (non-url).
|
|
17
|
-
*
|
|
18
|
-
* @returns {Promise<string>} Resolves to `Digest` header value.
|
|
19
|
-
*/
|
|
20
|
-
export async function createHeaderValue({
|
|
21
|
-
data, algorithm = 'sha256', useMultihash = true
|
|
22
|
-
} = {}) {
|
|
23
|
-
const {key, encodedDigest} = await _createHeaderValueComponents({
|
|
24
|
-
data, algorithm, useMultihash
|
|
25
|
-
});
|
|
26
|
-
return `${key}=${encodedDigest}`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Verifies the HTTP `Digest` header value against the given HTTP body `data`.
|
|
31
|
-
*
|
|
32
|
-
* @param {object} options - The options to use.
|
|
33
|
-
* @param {string|object|Blob|Uint8Array} options.data - The data to be
|
|
34
|
-
* verified (a request or response body).
|
|
35
|
-
* @param {string} options.headerValue - The digest header value to verify
|
|
36
|
-
* the data against.
|
|
37
|
-
*
|
|
38
|
-
* @returns {Promise<{verified: boolean, error?: Error}>}
|
|
39
|
-
*/
|
|
40
|
-
export async function verifyHeaderValue({data, headerValue}) {
|
|
41
|
-
try {
|
|
42
|
-
const {key, algorithm, encodedDigest} = _parseHeaderValue(headerValue);
|
|
43
|
-
const {encodedDigest: expectedDigest} = await _createHeaderValueComponents({
|
|
44
|
-
data, algorithm, useMultihash: key === 'mh'
|
|
45
|
-
});
|
|
46
|
-
return {verified: encodedDigest === expectedDigest};
|
|
47
|
-
} catch(error) {
|
|
48
|
-
return {verified: false, error};
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function _createHeaderValueComponents({
|
|
53
|
-
data, algorithm = 'sha256', useMultihash = true
|
|
54
|
-
}) {
|
|
55
|
-
if(algorithm !== 'sha256') {
|
|
56
|
-
throw new Error(`Algorithm "${algorithm}" is not supported.`);
|
|
57
|
-
}
|
|
58
|
-
const digest = await _getDigest({data, algorithm});
|
|
59
|
-
if(useMultihash) {
|
|
60
|
-
return {key: 'mh', encodedDigest: _createMultihash({digest})};
|
|
61
|
-
}
|
|
62
|
-
return {key: 'SHA-256', encodedDigest: base64Encode(digest)};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function _createMultihash({digest}) {
|
|
66
|
-
// format as multihash digest
|
|
67
|
-
// sha2-256: 0x12, length: 32 (0x20), digest value
|
|
68
|
-
const mh = new Uint8Array(34);
|
|
69
|
-
mh[0] = 0x12;
|
|
70
|
-
mh[1] = 0x20;
|
|
71
|
-
mh.set(digest, 2);
|
|
72
|
-
// encode multihash using multibase, base64url: `u`
|
|
73
|
-
return `u${base64urlEncode(mh)}`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function _parseHeaderValue(headerValue) {
|
|
77
|
-
const [key, digestValue] = headerValue.split(/=(.+)/);
|
|
78
|
-
|
|
79
|
-
let encodedDigest;
|
|
80
|
-
let algorithm;
|
|
81
|
-
if(key === 'mh') {
|
|
82
|
-
encodedDigest = digestValue;
|
|
83
|
-
|
|
84
|
-
// if `encodedDigest` starts with `uEi`, then it is a base64url-encoded
|
|
85
|
-
// sha-256 multihash
|
|
86
|
-
if(encodedDigest.startsWith('uEi')) {
|
|
87
|
-
algorithm = 'sha256';
|
|
88
|
-
} else {
|
|
89
|
-
throw new Error(
|
|
90
|
-
`Only base64url-encoded, sha-256 multihash is supported.`);
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
// per RFC 9651, the digest value could be a structured field value,
|
|
94
|
-
// expressed as a base64-encoded byte array wrapped in colons
|
|
95
|
-
encodedDigest = digestValue?.replace(/^:(.*):$/, '$1');
|
|
96
|
-
|
|
97
|
-
algorithm = key.replace('-', '').toLowerCase();
|
|
98
|
-
if(algorithm !== 'sha256') {
|
|
99
|
-
throw new Error(`Algorithm "${algorithm}" is not supported.`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return {key, algorithm, encodedDigest};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function _getDigest({data, algorithm}) {
|
|
106
|
-
data = await _normalizeData(data);
|
|
107
|
-
if(algorithm === 'sha256') {
|
|
108
|
-
return sha256(data);
|
|
109
|
-
}
|
|
110
|
-
throw new Error(`Algorithm "${algorithm}" is not unsupported.`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// normalize all inputs to a `Uint8Array` for hashing
|
|
114
|
-
async function _normalizeData(data) {
|
|
115
|
-
if(data instanceof Uint8Array) {
|
|
116
|
-
return data;
|
|
117
|
-
}
|
|
118
|
-
if(data instanceof Blob) {
|
|
119
|
-
// `Blob.bytes()` is only available in node.js 22+;
|
|
120
|
-
// fallback to `Blob.arrayBuffer()`
|
|
121
|
-
return data?.bytes?.() ?? data.arrayBuffer();
|
|
122
|
-
}
|
|
123
|
-
if(typeof data !== 'string') {
|
|
124
|
-
data = JSON.stringify(data);
|
|
125
|
-
}
|
|
126
|
-
return (new TextEncoder()).encode(data);
|
|
127
|
-
}
|
package/lib/index.js
DELETED
package/lib/util-browser.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2021-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
export function base64Encode(bytes) {
|
|
5
|
-
if(bytes.toBase64) {
|
|
6
|
-
return bytes.toBase64();
|
|
7
|
-
}
|
|
8
|
-
return btoa(Array.from(bytes, b => String.fromCodePoint(b)).join(''));
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function base64urlEncode(bytes) {
|
|
12
|
-
if(bytes.toBase64) {
|
|
13
|
-
return bytes.toBase64({alphabet: 'base64url', omitPadding: true});
|
|
14
|
-
}
|
|
15
|
-
return base64Encode(bytes)
|
|
16
|
-
.replace(/\+/g, '-')
|
|
17
|
-
.replace(/\//g, '_')
|
|
18
|
-
.replaceAll('=', '');
|
|
19
|
-
}
|
package/lib/util.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2021-2025 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
export function base64Encode(bytes) {
|
|
5
|
-
return Buffer.from(bytes.buffer, bytes.offset, bytes.length)
|
|
6
|
-
.toString('base64');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function base64urlEncode(bytes) {
|
|
10
|
-
return Buffer.from(bytes.buffer, bytes.offset, bytes.length)
|
|
11
|
-
.toString('base64url');
|
|
12
|
-
}
|
package/types/httpDigest.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a value suitable for the HTTP `Digest` header.
|
|
3
|
-
*
|
|
4
|
-
* @param {object} options - The options to use.
|
|
5
|
-
* @param {string|object|Blob|Uint8Array} [options.data] - The data to be
|
|
6
|
-
* hashed (a request or response body).
|
|
7
|
-
* @param {string} [options.algorithm] - Hash algorithm to use.
|
|
8
|
-
* (e.g. 'sha256').
|
|
9
|
-
* @param {boolean} [options.useMultihash=true] - Whether to encode via
|
|
10
|
-
* multihash; if false, the hash will be base64-encoded (non-url).
|
|
11
|
-
*
|
|
12
|
-
* @returns {Promise<string>} Resolves to `Digest` header value.
|
|
13
|
-
*/
|
|
14
|
-
export function createHeaderValue({ data, algorithm, useMultihash }?: {
|
|
15
|
-
data?: string | object | Blob | Uint8Array;
|
|
16
|
-
algorithm?: string;
|
|
17
|
-
useMultihash?: boolean;
|
|
18
|
-
}): Promise<string>;
|
|
19
|
-
/**
|
|
20
|
-
* Verifies the HTTP `Digest` header value against the given HTTP body `data`.
|
|
21
|
-
*
|
|
22
|
-
* @param {object} options - The options to use.
|
|
23
|
-
* @param {string|object|Blob|Uint8Array} options.data - The data to be
|
|
24
|
-
* verified (a request or response body).
|
|
25
|
-
* @param {string} options.headerValue - The digest header value to verify
|
|
26
|
-
* the data against.
|
|
27
|
-
*
|
|
28
|
-
* @returns {Promise<{verified: boolean, error?: Error}>}
|
|
29
|
-
*/
|
|
30
|
-
export function verifyHeaderValue({ data, headerValue }: {
|
|
31
|
-
data: string | object | Blob | Uint8Array;
|
|
32
|
-
headerValue: string;
|
|
33
|
-
}): Promise<{
|
|
34
|
-
verified: boolean;
|
|
35
|
-
error?: Error;
|
|
36
|
-
}>;
|
package/types/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createHeaderValue, verifyHeaderValue } from "./httpDigest.js";
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a value suitable for the HTTP `Digest` header.
|
|
3
|
-
*
|
|
4
|
-
* @param {object} options - The options to use.
|
|
5
|
-
* @param {string|object|Blob|Uint8Array} [options.data] - The data to be
|
|
6
|
-
* hashed (a request or response body).
|
|
7
|
-
* @param {string} [options.algorithm] - Hash algorithm to use.
|
|
8
|
-
* (e.g. 'sha256').
|
|
9
|
-
* @param {boolean} [options.useMultihash=true] - Whether to encode via
|
|
10
|
-
* multihash; if false, the hash will be base64-encoded (non-url).
|
|
11
|
-
*
|
|
12
|
-
* @returns {Promise<string>} Resolves to `Digest` header value.
|
|
13
|
-
*/
|
|
14
|
-
export function createHeaderValue({ data, algorithm, useMultihash }?: {
|
|
15
|
-
data?: string | object | Blob | Uint8Array;
|
|
16
|
-
algorithm?: string;
|
|
17
|
-
useMultihash?: boolean;
|
|
18
|
-
}): Promise<string>;
|
|
19
|
-
/**
|
|
20
|
-
* Verifies the HTTP `Digest` header value against the given HTTP body `data`.
|
|
21
|
-
*
|
|
22
|
-
* @param {object} options - The options to use.
|
|
23
|
-
* @param {string|object|Blob|Uint8Array} options.data - The data to be
|
|
24
|
-
* verified (a request or response body).
|
|
25
|
-
* @param {string} options.headerValue - The digest header value to verify
|
|
26
|
-
* the data against.
|
|
27
|
-
*
|
|
28
|
-
* @returns {Promise<{verified: boolean, error?: Error}>}
|
|
29
|
-
*/
|
|
30
|
-
export function verifyHeaderValue({ data, headerValue }: {
|
|
31
|
-
data: string | object | Blob | Uint8Array;
|
|
32
|
-
headerValue: string;
|
|
33
|
-
}): Promise<{
|
|
34
|
-
verified: boolean;
|
|
35
|
-
error?: Error;
|
|
36
|
-
}>;
|
package/types/lib/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createHeaderValue, verifyHeaderValue } from "./httpDigest.js";
|
package/types/lib/util.d.ts
DELETED