@interop/edv-client 17.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/LICENSE +27 -0
- package/README.md +276 -0
- package/dist/EdvClient.d.ts +412 -0
- package/dist/EdvClient.d.ts.map +1 -0
- package/dist/EdvClient.js +663 -0
- package/dist/EdvClient.js.map +1 -0
- package/dist/EdvClientCore.d.ts +264 -0
- package/dist/EdvClientCore.d.ts.map +1 -0
- package/dist/EdvClientCore.js +698 -0
- package/dist/EdvClientCore.js.map +1 -0
- package/dist/EdvDocument.d.ts +92 -0
- package/dist/EdvDocument.d.ts.map +1 -0
- package/dist/EdvDocument.js +149 -0
- package/dist/EdvDocument.js.map +1 -0
- package/dist/HttpsTransport.d.ts +87 -0
- package/dist/HttpsTransport.d.ts.map +1 -0
- package/dist/HttpsTransport.js +415 -0
- package/dist/HttpsTransport.js.map +1 -0
- package/dist/IndexHelper.d.ts +163 -0
- package/dist/IndexHelper.d.ts.map +1 -0
- package/dist/IndexHelper.js +539 -0
- package/dist/IndexHelper.js.map +1 -0
- package/dist/LegacyIndexHelperVersion1.d.ts +150 -0
- package/dist/LegacyIndexHelperVersion1.d.ts.map +1 -0
- package/dist/LegacyIndexHelperVersion1.js +475 -0
- package/dist/LegacyIndexHelperVersion1.js.map +1 -0
- package/dist/Transport.d.ts +142 -0
- package/dist/Transport.d.ts.map +1 -0
- package/dist/Transport.js +181 -0
- package/dist/Transport.js.map +1 -0
- package/dist/assert.d.ts +6 -0
- package/dist/assert.d.ts.map +1 -0
- package/dist/assert.js +61 -0
- package/dist/assert.js.map +1 -0
- package/dist/baseX.d.ts +7 -0
- package/dist/baseX.d.ts.map +1 -0
- package/dist/baseX.js +8 -0
- package/dist/baseX.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/util.d.ts +3 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +13 -0
- package/dist/util.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export declare class LegacyIndexHelperVersion1 {
|
|
2
|
+
indexes: any;
|
|
3
|
+
compoundIndexes: any;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new LegacyIndexHelperVersion1 instance that can be used to blind
|
|
6
|
+
* EDV document attributes to enable indexing.
|
|
7
|
+
*
|
|
8
|
+
* This is a legacy version that builds version 1 blinded attributes; it
|
|
9
|
+
* should only be used when migrating old blinded attributes.
|
|
10
|
+
*
|
|
11
|
+
* @returns {LegacyIndexHelperVersion1} A LegacyIndexHelperVersion1 instance.
|
|
12
|
+
*/
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Ensures that future documents inserted or updated using this client
|
|
16
|
+
* instance will be indexed according to the given attribute, provided that
|
|
17
|
+
* they contain that attribute. Compound indexes can be specified by
|
|
18
|
+
* providing an array for `attribute`.
|
|
19
|
+
*
|
|
20
|
+
* Queries may be performed using compound indexes without specifying all
|
|
21
|
+
* attributes in the compound index so long as there is at least one value
|
|
22
|
+
* (or the attribute name for "has" queries) specified for consecutive
|
|
23
|
+
* attributes starting with the first. This allows for querying using only
|
|
24
|
+
* a prefix of a compound index. However, uniqueness will not be enforced
|
|
25
|
+
* unless all attributes in the compound index are present in a document.
|
|
26
|
+
*
|
|
27
|
+
* @param {object} options - The options to use.
|
|
28
|
+
* @param {string|string[]} options.attribute - The attribute name or an
|
|
29
|
+
* array of attribute names to create a unique compound index.
|
|
30
|
+
* @param {boolean} [options.unique=false] - Set to `true` if the index
|
|
31
|
+
* should be considered unique, `false` if not.
|
|
32
|
+
*/
|
|
33
|
+
ensureIndex({ attribute, unique }?: any): void;
|
|
34
|
+
/**
|
|
35
|
+
* Creates an indexable entry of blinded attributes for the given document
|
|
36
|
+
* using the HMAC associated with this instance.
|
|
37
|
+
*
|
|
38
|
+
* @param {object} options - The options to use.
|
|
39
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
40
|
+
* properties.
|
|
41
|
+
* @param {object} options.doc - The document to create the indexable entry
|
|
42
|
+
* for.
|
|
43
|
+
*
|
|
44
|
+
* @returns {Promise<object>} - Resolves to the new indexable entry.
|
|
45
|
+
*/
|
|
46
|
+
createEntry({ hmac, doc }: any): Promise<{
|
|
47
|
+
hmac: {
|
|
48
|
+
id: any;
|
|
49
|
+
type: any;
|
|
50
|
+
};
|
|
51
|
+
sequence: any;
|
|
52
|
+
attributes: any[];
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Returns a shallow copy of the array of indexed entries for the given
|
|
56
|
+
* document where any existing entry matching the HMAC associated with this
|
|
57
|
+
* instance is updated to include the current document attributes. If no
|
|
58
|
+
* existing entry is found, a new entry is appended to the shallow copy
|
|
59
|
+
* prior to its return.
|
|
60
|
+
*
|
|
61
|
+
* @param {object} options - The options to use.
|
|
62
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
63
|
+
* properties.
|
|
64
|
+
* @param {object} options.doc - The document to create or update an indexable
|
|
65
|
+
* entry for.
|
|
66
|
+
*
|
|
67
|
+
* @returns {Promise<Array>} - Resolves to the updated array of indexable
|
|
68
|
+
* entries.
|
|
69
|
+
*/
|
|
70
|
+
updateEntry({ hmac, doc }: any): Promise<any>;
|
|
71
|
+
/**
|
|
72
|
+
* Builds a query that can be submitted to an EDV index service.
|
|
73
|
+
*
|
|
74
|
+
* @param {object} options - The options to use.
|
|
75
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
76
|
+
* properties.
|
|
77
|
+
* @param {object|Array} [options.equals] - An object with key-value
|
|
78
|
+
* attribute pairs to match or an array of such objects.
|
|
79
|
+
* @param {string|Array} [options.has] - A string with an attribute name to
|
|
80
|
+
* match or an array of such strings.
|
|
81
|
+
*
|
|
82
|
+
* @returns {Promise<object>} - Resolves to the built query.
|
|
83
|
+
*/
|
|
84
|
+
buildQuery({ hmac, equals, has }: any): Promise<any>;
|
|
85
|
+
/**
|
|
86
|
+
* Blinds a single attribute using the given HMAC API.
|
|
87
|
+
*
|
|
88
|
+
* @param {object} options - The options to use.
|
|
89
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
90
|
+
* properties.
|
|
91
|
+
* @param {string} options.key - A key associated with a value.
|
|
92
|
+
* @param {any} options.value - The value associated with the key for the
|
|
93
|
+
* attribute.
|
|
94
|
+
*
|
|
95
|
+
* @returns {Promise<object>} - Resolves to an object `{name, value}`.
|
|
96
|
+
*/
|
|
97
|
+
_blindAttribute({ hmac, key, value }: any): Promise<{
|
|
98
|
+
name: string;
|
|
99
|
+
value: string;
|
|
100
|
+
}>;
|
|
101
|
+
/**
|
|
102
|
+
* Builds a blind compound attribute from an array of blind attributes
|
|
103
|
+
* via the given HMAC API.
|
|
104
|
+
*
|
|
105
|
+
* @param {object} options - The options to use.
|
|
106
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
107
|
+
* properties.
|
|
108
|
+
* @param {Array} options.blindAttributes - The blind attributes that
|
|
109
|
+
* comprise the compound index.
|
|
110
|
+
* @param {number} [options.length=options.blindAttributes.length] - The
|
|
111
|
+
* number of blind attributes to go into the compound attribute
|
|
112
|
+
* (<= `blindAttributes.length`).
|
|
113
|
+
*
|
|
114
|
+
* @returns {Promise<string>} - Resolves to the blinded compound attribute.
|
|
115
|
+
*/
|
|
116
|
+
_blindCompoundAttribute({ hmac, blindAttributes, length }: any): Promise<{
|
|
117
|
+
name: string;
|
|
118
|
+
value: string;
|
|
119
|
+
}>;
|
|
120
|
+
/**
|
|
121
|
+
* Blinds a string using the given HMAC API.
|
|
122
|
+
*
|
|
123
|
+
* @param {object} hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
124
|
+
* properties.
|
|
125
|
+
* @param {string} value - The value to blind.
|
|
126
|
+
*
|
|
127
|
+
* @returns {Promise<string>} - Resolves to the blinded value.
|
|
128
|
+
*/
|
|
129
|
+
_blindString(hmac: any, value: any): Promise<string>;
|
|
130
|
+
_buildBlindAttributes({ hmac, doc, equal, has }: any): Promise<any[]>;
|
|
131
|
+
_getMatchingIndexes({ doc, equal, has }?: any): {
|
|
132
|
+
attributeValues: Map<any, any>;
|
|
133
|
+
simpleMatches: {
|
|
134
|
+
attribute: any;
|
|
135
|
+
unique: any;
|
|
136
|
+
}[];
|
|
137
|
+
compoundMatches: any[];
|
|
138
|
+
};
|
|
139
|
+
_matchIndexes({ matchFn }?: any): {
|
|
140
|
+
simpleMatches: {
|
|
141
|
+
attribute: any;
|
|
142
|
+
unique: any;
|
|
143
|
+
}[];
|
|
144
|
+
compoundMatches: any[];
|
|
145
|
+
};
|
|
146
|
+
_matchDocument({ attribute, attributeValues, doc }: any): boolean;
|
|
147
|
+
_parseAttribute(attribute: any): any;
|
|
148
|
+
_dereferenceAttribute({ attribute, keys, doc }: any): any;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=LegacyIndexHelperVersion1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LegacyIndexHelperVersion1.d.ts","sourceRoot":"","sources":["../src/LegacyIndexHelperVersion1.ts"],"names":[],"mappings":"AAUA,qBAAa,yBAAyB;IACpC,OAAO,EAAE,GAAG,CAAA;IACZ,eAAe,EAAE,GAAG,CAAA;IAEpB;;;;;;;;OAQG;;IAMH;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,EAAE,SAAS,EAAE,MAAc,EAAE,GAAE,GAAQ;IA0BnD;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG;;;;;;;;IAapC;;;;;;;;;;;;;;;OAeG;IACG,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG;IA4BpC;;;;;;;;;;;;OAYG;IACG,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG;IAgE3C;;;;;;;;;;;OAWG;IACG,eAAe,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG;;;;IAU/C;;;;;;;;;;;;;;OAcG;IACG,uBAAuB,CAAC,EAC5B,IAAI,EACJ,eAAe,EACf,MAA+B,EAChC,EAAE,GAAG;;;;IAcN;;;;;;;;OAQG;IACG,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG;IAYlC,qBAAqB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG;IAyG1D,mBAAmB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,GAAQ;;;;;;;;IAiCjD,aAAa,CAAC,EAAE,OAAO,EAAE,GAAE,GAAQ;;;;;;;IA+BnC,cAAc,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,EAAE,GAAG;IAuBvD,eAAe,CAAC,SAAS,EAAE,GAAG;IAkB9B,qBAAqB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,GAAG;CAoB1D"}
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2019-2023 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { base64url } from './baseX.js';
|
|
5
|
+
import canonicalize from 'canonicalize';
|
|
6
|
+
import { sha256 } from './util.js';
|
|
7
|
+
import split from 'split-string';
|
|
8
|
+
const ATTRIBUTE_PREFIXES = ['content', 'meta'];
|
|
9
|
+
export class LegacyIndexHelperVersion1 {
|
|
10
|
+
indexes;
|
|
11
|
+
compoundIndexes;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new LegacyIndexHelperVersion1 instance that can be used to blind
|
|
14
|
+
* EDV document attributes to enable indexing.
|
|
15
|
+
*
|
|
16
|
+
* This is a legacy version that builds version 1 blinded attributes; it
|
|
17
|
+
* should only be used when migrating old blinded attributes.
|
|
18
|
+
*
|
|
19
|
+
* @returns {LegacyIndexHelperVersion1} A LegacyIndexHelperVersion1 instance.
|
|
20
|
+
*/
|
|
21
|
+
constructor() {
|
|
22
|
+
this.indexes = new Map();
|
|
23
|
+
this.compoundIndexes = new Map();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Ensures that future documents inserted or updated using this client
|
|
27
|
+
* instance will be indexed according to the given attribute, provided that
|
|
28
|
+
* they contain that attribute. Compound indexes can be specified by
|
|
29
|
+
* providing an array for `attribute`.
|
|
30
|
+
*
|
|
31
|
+
* Queries may be performed using compound indexes without specifying all
|
|
32
|
+
* attributes in the compound index so long as there is at least one value
|
|
33
|
+
* (or the attribute name for "has" queries) specified for consecutive
|
|
34
|
+
* attributes starting with the first. This allows for querying using only
|
|
35
|
+
* a prefix of a compound index. However, uniqueness will not be enforced
|
|
36
|
+
* unless all attributes in the compound index are present in a document.
|
|
37
|
+
*
|
|
38
|
+
* @param {object} options - The options to use.
|
|
39
|
+
* @param {string|string[]} options.attribute - The attribute name or an
|
|
40
|
+
* array of attribute names to create a unique compound index.
|
|
41
|
+
* @param {boolean} [options.unique=false] - Set to `true` if the index
|
|
42
|
+
* should be considered unique, `false` if not.
|
|
43
|
+
*/
|
|
44
|
+
ensureIndex({ attribute, unique = false } = {}) {
|
|
45
|
+
let attributes = attribute;
|
|
46
|
+
if (!Array.isArray(attribute)) {
|
|
47
|
+
attributes = [attribute];
|
|
48
|
+
}
|
|
49
|
+
if (!(attributes.length > 0 &&
|
|
50
|
+
attributes.every((x) => typeof x === 'string'))) {
|
|
51
|
+
throw new TypeError('"attribute" must be a string or an array of strings.');
|
|
52
|
+
}
|
|
53
|
+
if (attributes.length === 1) {
|
|
54
|
+
// add simple index
|
|
55
|
+
this.indexes.set(attributes[0], unique);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// add compound index
|
|
59
|
+
const key = attributes.map((x) => encodeURIComponent(x)).join('|');
|
|
60
|
+
this.compoundIndexes.set(key, { attributes, unique });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Creates an indexable entry of blinded attributes for the given document
|
|
65
|
+
* using the HMAC associated with this instance.
|
|
66
|
+
*
|
|
67
|
+
* @param {object} options - The options to use.
|
|
68
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
69
|
+
* properties.
|
|
70
|
+
* @param {object} options.doc - The document to create the indexable entry
|
|
71
|
+
* for.
|
|
72
|
+
*
|
|
73
|
+
* @returns {Promise<object>} - Resolves to the new indexable entry.
|
|
74
|
+
*/
|
|
75
|
+
async createEntry({ hmac, doc }) {
|
|
76
|
+
_assertHmac(hmac);
|
|
77
|
+
const entry = {
|
|
78
|
+
hmac: {
|
|
79
|
+
id: hmac.id,
|
|
80
|
+
type: hmac.type
|
|
81
|
+
},
|
|
82
|
+
sequence: doc.sequence,
|
|
83
|
+
attributes: await this._buildBlindAttributes({ hmac, doc })
|
|
84
|
+
};
|
|
85
|
+
return entry;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns a shallow copy of the array of indexed entries for the given
|
|
89
|
+
* document where any existing entry matching the HMAC associated with this
|
|
90
|
+
* instance is updated to include the current document attributes. If no
|
|
91
|
+
* existing entry is found, a new entry is appended to the shallow copy
|
|
92
|
+
* prior to its return.
|
|
93
|
+
*
|
|
94
|
+
* @param {object} options - The options to use.
|
|
95
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
96
|
+
* properties.
|
|
97
|
+
* @param {object} options.doc - The document to create or update an indexable
|
|
98
|
+
* entry for.
|
|
99
|
+
*
|
|
100
|
+
* @returns {Promise<Array>} - Resolves to the updated array of indexable
|
|
101
|
+
* entries.
|
|
102
|
+
*/
|
|
103
|
+
async updateEntry({ hmac, doc }) {
|
|
104
|
+
_assertHmac(hmac);
|
|
105
|
+
// get previously indexed entries to update
|
|
106
|
+
let { indexed = [] } = doc;
|
|
107
|
+
if (!Array.isArray(indexed)) {
|
|
108
|
+
throw new TypeError('"indexed" must be an array.');
|
|
109
|
+
}
|
|
110
|
+
// create new entry
|
|
111
|
+
const entry = await this.createEntry({ hmac, doc });
|
|
112
|
+
// find existing entry in `indexed` by hmac ID and type
|
|
113
|
+
const i = indexed.findIndex((e) => e.hmac.id === hmac.id && e.hmac.type === hmac.type);
|
|
114
|
+
// replace or append new entry
|
|
115
|
+
indexed = indexed.slice();
|
|
116
|
+
if (i === -1) {
|
|
117
|
+
indexed.push(entry);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
indexed[i] = entry;
|
|
121
|
+
}
|
|
122
|
+
return indexed;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Builds a query that can be submitted to an EDV index service.
|
|
126
|
+
*
|
|
127
|
+
* @param {object} options - The options to use.
|
|
128
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
129
|
+
* properties.
|
|
130
|
+
* @param {object|Array} [options.equals] - An object with key-value
|
|
131
|
+
* attribute pairs to match or an array of such objects.
|
|
132
|
+
* @param {string|Array} [options.has] - A string with an attribute name to
|
|
133
|
+
* match or an array of such strings.
|
|
134
|
+
*
|
|
135
|
+
* @returns {Promise<object>} - Resolves to the built query.
|
|
136
|
+
*/
|
|
137
|
+
async buildQuery({ hmac, equals, has }) {
|
|
138
|
+
_assertHmac(hmac);
|
|
139
|
+
// validate params
|
|
140
|
+
if (equals === undefined && has === undefined) {
|
|
141
|
+
throw new Error('Either "equals" or "has" must be defined.');
|
|
142
|
+
}
|
|
143
|
+
if (equals !== undefined && has !== undefined) {
|
|
144
|
+
throw new Error('Only one of "equals" or "has" may be defined at once.');
|
|
145
|
+
}
|
|
146
|
+
if (equals !== undefined) {
|
|
147
|
+
if (Array.isArray(equals)) {
|
|
148
|
+
if (!equals.every((x) => x && typeof x === 'object')) {
|
|
149
|
+
throw new TypeError('"equals" must be an array of objects.');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (!(equals && typeof equals === 'object')) {
|
|
153
|
+
throw new TypeError('"equals" must be an object or an array of objects.');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (has !== undefined) {
|
|
157
|
+
if (Array.isArray(has)) {
|
|
158
|
+
if (!has.every((x) => x && typeof x === 'string')) {
|
|
159
|
+
throw new TypeError('"has" must be an array of strings.');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (typeof has !== 'string') {
|
|
163
|
+
throw new TypeError('"has" must be a string or an array of strings.');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const query = {
|
|
167
|
+
index: hmac.id
|
|
168
|
+
};
|
|
169
|
+
if (equals) {
|
|
170
|
+
// normalize to array
|
|
171
|
+
if (!Array.isArray(equals)) {
|
|
172
|
+
equals = [equals];
|
|
173
|
+
}
|
|
174
|
+
// blind all values in each `equal`
|
|
175
|
+
query.equals = await Promise.all(equals.map(async (equal) => {
|
|
176
|
+
const result = {};
|
|
177
|
+
const blinded = await this._buildBlindAttributes({ hmac, equal });
|
|
178
|
+
for (const { name, value } of blinded) {
|
|
179
|
+
result[name] = value;
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
}));
|
|
183
|
+
}
|
|
184
|
+
else if (has !== undefined) {
|
|
185
|
+
// normalize to array
|
|
186
|
+
if (!Array.isArray(has)) {
|
|
187
|
+
has = [has];
|
|
188
|
+
}
|
|
189
|
+
// blind every attribute name in `has`
|
|
190
|
+
query.has = (await this._buildBlindAttributes({ hmac, has })).map(({ name }) => name);
|
|
191
|
+
}
|
|
192
|
+
return query;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Blinds a single attribute using the given HMAC API.
|
|
196
|
+
*
|
|
197
|
+
* @param {object} options - The options to use.
|
|
198
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
199
|
+
* properties.
|
|
200
|
+
* @param {string} options.key - A key associated with a value.
|
|
201
|
+
* @param {any} options.value - The value associated with the key for the
|
|
202
|
+
* attribute.
|
|
203
|
+
*
|
|
204
|
+
* @returns {Promise<object>} - Resolves to an object `{name, value}`.
|
|
205
|
+
*/
|
|
206
|
+
async _blindAttribute({ hmac, key, value }) {
|
|
207
|
+
// salt values with key to prevent cross-key leakage
|
|
208
|
+
value = canonicalize({ key: value });
|
|
209
|
+
const [blindedName, blindedValue] = await Promise.all([
|
|
210
|
+
this._blindString(hmac, key),
|
|
211
|
+
this._blindString(hmac, value)
|
|
212
|
+
]);
|
|
213
|
+
return { name: blindedName, value: blindedValue };
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Builds a blind compound attribute from an array of blind attributes
|
|
217
|
+
* via the given HMAC API.
|
|
218
|
+
*
|
|
219
|
+
* @param {object} options - The options to use.
|
|
220
|
+
* @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
221
|
+
* properties.
|
|
222
|
+
* @param {Array} options.blindAttributes - The blind attributes that
|
|
223
|
+
* comprise the compound index.
|
|
224
|
+
* @param {number} [options.length=options.blindAttributes.length] - The
|
|
225
|
+
* number of blind attributes to go into the compound attribute
|
|
226
|
+
* (<= `blindAttributes.length`).
|
|
227
|
+
*
|
|
228
|
+
* @returns {Promise<string>} - Resolves to the blinded compound attribute.
|
|
229
|
+
*/
|
|
230
|
+
async _blindCompoundAttribute({ hmac, blindAttributes, length = blindAttributes.length }) {
|
|
231
|
+
const selection = length === blindAttributes.length
|
|
232
|
+
? blindAttributes
|
|
233
|
+
: blindAttributes.slice(0, length);
|
|
234
|
+
const nameInput = selection.map((x) => x.name).join(':');
|
|
235
|
+
const valueInput = selection.map((x) => x.value).join(':');
|
|
236
|
+
const [name, value] = await Promise.all([
|
|
237
|
+
this._blindString(hmac, nameInput),
|
|
238
|
+
this._blindString(hmac, valueInput)
|
|
239
|
+
]);
|
|
240
|
+
return { name, value };
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Blinds a string using the given HMAC API.
|
|
244
|
+
*
|
|
245
|
+
* @param {object} hmac - An HMAC API with `id`, `sign`, and `verify`
|
|
246
|
+
* properties.
|
|
247
|
+
* @param {string} value - The value to blind.
|
|
248
|
+
*
|
|
249
|
+
* @returns {Promise<string>} - Resolves to the blinded value.
|
|
250
|
+
*/
|
|
251
|
+
async _blindString(hmac, value) {
|
|
252
|
+
// convert value to Uint8Array and hash it
|
|
253
|
+
const data = await sha256(new TextEncoder().encode(value));
|
|
254
|
+
const signature = await hmac.sign({ data });
|
|
255
|
+
if (typeof signature === 'string') {
|
|
256
|
+
// presume base64url-encoded
|
|
257
|
+
return signature;
|
|
258
|
+
}
|
|
259
|
+
// base64url-encode Uint8Array signature
|
|
260
|
+
return base64url.encode(signature);
|
|
261
|
+
}
|
|
262
|
+
async _buildBlindAttributes({ hmac, doc, equal, has }) {
|
|
263
|
+
const result = [];
|
|
264
|
+
// get all matching indexes and corresponding attribute values
|
|
265
|
+
const { simpleMatches, compoundMatches, attributeValues } = this._getMatchingIndexes({ doc, equal, has });
|
|
266
|
+
// compute and store all blinded attributes in parallel
|
|
267
|
+
const blindedAttributes = new Map();
|
|
268
|
+
const blindPromises = [];
|
|
269
|
+
for (const [attribute, valueSet] of attributeValues.entries()) {
|
|
270
|
+
// create a blinded set for each attribute name; it will hold the
|
|
271
|
+
// blinded attribute associated with each attribute+value pair
|
|
272
|
+
const blindedSet = new Set();
|
|
273
|
+
blindedAttributes.set(attribute, blindedSet);
|
|
274
|
+
for (const v of valueSet) {
|
|
275
|
+
// use an IIFE to push a promise onto `blindPromises` to await all
|
|
276
|
+
// promises in parallel and within IIFE add the resolved blinded
|
|
277
|
+
// attribute to the current attribute's `blindedSet`
|
|
278
|
+
blindPromises.push((async () => {
|
|
279
|
+
blindedSet.add(await this._blindAttribute({ hmac, key: attribute, value: v }));
|
|
280
|
+
})());
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
await Promise.all(blindPromises);
|
|
284
|
+
// add all matching simple index blinded attributes and track simple
|
|
285
|
+
// attributes to avoid duplicating entries when processing compound
|
|
286
|
+
// indexes
|
|
287
|
+
const simpleAttributes = new Set();
|
|
288
|
+
for (const { attribute, unique } of simpleMatches) {
|
|
289
|
+
const blindedSet = blindedAttributes.get(attribute);
|
|
290
|
+
for (const blinded of blindedSet) {
|
|
291
|
+
result.push({ ...blinded, unique });
|
|
292
|
+
}
|
|
293
|
+
simpleAttributes.add(attribute);
|
|
294
|
+
}
|
|
295
|
+
// compute and add all matching compound index blinded attributes
|
|
296
|
+
const compoundPromises = [];
|
|
297
|
+
for (const { attributes, unique } of compoundMatches) {
|
|
298
|
+
/* Note: For each matching index, there are some number of matching
|
|
299
|
+
attributes that need to be combinatorially spread. For example, for this
|
|
300
|
+
index: `['content.a', 'content.b', 'content.c']`, there may be multiple
|
|
301
|
+
values for each attribute such as `A` values for `content.a`, `B` values
|
|
302
|
+
for `content.b`, and `C` values for `content.c`. Each combination these
|
|
303
|
+
values will produce a new blinded attribute to add to `entry`.
|
|
304
|
+
Combinations must also include partial ones, e.g., combinations of
|
|
305
|
+
values for `content.a` alone as well as values for `content.a` and
|
|
306
|
+
`content.b` without `content.c`. */
|
|
307
|
+
const combinations = [];
|
|
308
|
+
let previous = [[]];
|
|
309
|
+
for (const attribute of attributes) {
|
|
310
|
+
const blindedSet = blindedAttributes.get(attribute);
|
|
311
|
+
if (!blindedSet) {
|
|
312
|
+
// no values for current attribute, so no more entries to produce
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
// produce a new combination for every `blinded` value and every
|
|
316
|
+
// combination from the previous attribute
|
|
317
|
+
const next = [];
|
|
318
|
+
for (const blinded of blindedSet) {
|
|
319
|
+
for (const combination of previous) {
|
|
320
|
+
next.push([...combination, blinded]);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
combinations.push(...next);
|
|
324
|
+
previous = next;
|
|
325
|
+
}
|
|
326
|
+
// now generate entries from every combination
|
|
327
|
+
for (const combination of combinations) {
|
|
328
|
+
// skip generating an entry for this combination if it has just the
|
|
329
|
+
// first attribute and an entry for it was already added
|
|
330
|
+
if (combination.length === 1 && simpleAttributes.has(attributes[0])) {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
// use an IIFE to push a promise onto `compoundPromises` to await all
|
|
334
|
+
// promises in parallel and within IIFE return blinded attribute to
|
|
335
|
+
// add to `entry` below
|
|
336
|
+
compoundPromises.push((async () => {
|
|
337
|
+
const attribute = await this._blindCompoundAttribute({
|
|
338
|
+
hmac,
|
|
339
|
+
blindAttributes: combination
|
|
340
|
+
});
|
|
341
|
+
// an encrypted attribute is only unique for a compound index when
|
|
342
|
+
// it contains a value for every attribute in the index
|
|
343
|
+
attribute.unique =
|
|
344
|
+
unique && combination.length === attributes.length;
|
|
345
|
+
return attribute;
|
|
346
|
+
})());
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
result.push(...(await Promise.all(compoundPromises)));
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
_getMatchingIndexes({ doc, equal, has } = {}) {
|
|
353
|
+
// build a map of `attribute name => set of values` whilst matching
|
|
354
|
+
const attributeValues = new Map();
|
|
355
|
+
let matchFn;
|
|
356
|
+
if (doc) {
|
|
357
|
+
// build a map of `attribute name => set of values` whilst matching
|
|
358
|
+
// against the document
|
|
359
|
+
matchFn = ({ attribute }) => {
|
|
360
|
+
return this._matchDocument({ attribute, attributeValues, doc });
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
// any attribute in `equal` or `has` entry is a match
|
|
365
|
+
let attributes;
|
|
366
|
+
if (equal) {
|
|
367
|
+
attributes = Object.keys(equal);
|
|
368
|
+
for (const [name, value] of Object.entries(equal)) {
|
|
369
|
+
attributeValues.set(name, new Set([value]));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
attributes = has;
|
|
374
|
+
for (const name of has) {
|
|
375
|
+
// use dummy value of `true`; values will not be used in a `has`
|
|
376
|
+
// query; note that this could be optimized to avoid the unnecessary
|
|
377
|
+
// blinding of values in the future with more complex code
|
|
378
|
+
attributeValues.set(name, new Set([true]));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
matchFn = ({ attribute }) => attributes.includes(attribute);
|
|
382
|
+
}
|
|
383
|
+
const result = this._matchIndexes({ matchFn });
|
|
384
|
+
return { ...result, attributeValues };
|
|
385
|
+
}
|
|
386
|
+
_matchIndexes({ matchFn } = {}) {
|
|
387
|
+
// any simple index that has a value defined for its attribute is a match
|
|
388
|
+
const simpleMatches = [];
|
|
389
|
+
for (const [attribute, unique] of this.indexes.entries()) {
|
|
390
|
+
if (matchFn({ attribute })) {
|
|
391
|
+
simpleMatches.push({ attribute, unique });
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// any compound index that has a value defined for its first attribute is a
|
|
395
|
+
// match; continue to process consecutive attributes whilst at least one
|
|
396
|
+
// value per consecutive attribute is defined
|
|
397
|
+
const compoundMatches = [];
|
|
398
|
+
for (const index of this.compoundIndexes.values()) {
|
|
399
|
+
let first = true;
|
|
400
|
+
const { attributes } = index;
|
|
401
|
+
for (const attribute of attributes) {
|
|
402
|
+
if (!matchFn({ attribute })) {
|
|
403
|
+
// consecutive value not defined
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
if (first) {
|
|
407
|
+
first = false;
|
|
408
|
+
compoundMatches.push(index);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return { simpleMatches, compoundMatches };
|
|
413
|
+
}
|
|
414
|
+
_matchDocument({ attribute, attributeValues, doc }) {
|
|
415
|
+
// get attribute value from document
|
|
416
|
+
const value = this._dereferenceAttribute({ attribute, doc });
|
|
417
|
+
if (value === undefined) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
// get set of values
|
|
421
|
+
let valueSet = attributeValues.get(attribute);
|
|
422
|
+
if (!valueSet) {
|
|
423
|
+
attributeValues.set(attribute, (valueSet = new Set()));
|
|
424
|
+
}
|
|
425
|
+
// add each value in an array as a separate attribute value
|
|
426
|
+
if (Array.isArray(value)) {
|
|
427
|
+
value.forEach(valueSet.add, valueSet);
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
valueSet.add(value);
|
|
431
|
+
}
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
_parseAttribute(attribute) {
|
|
435
|
+
const keys = split(attribute);
|
|
436
|
+
if (keys.length === 0) {
|
|
437
|
+
throw new Error(`Invalid attribute "${attribute}"; it must be of the form ` +
|
|
438
|
+
'"content.foo.bar".');
|
|
439
|
+
}
|
|
440
|
+
// ensure prefix is valid
|
|
441
|
+
if (!ATTRIBUTE_PREFIXES.includes(keys[0])) {
|
|
442
|
+
throw new Error('Attribute "${attribute}" must be prefixed with one of the ' +
|
|
443
|
+
`following: ${ATTRIBUTE_PREFIXES.join(', ')}`);
|
|
444
|
+
}
|
|
445
|
+
return keys;
|
|
446
|
+
}
|
|
447
|
+
_dereferenceAttribute({ attribute, keys, doc }) {
|
|
448
|
+
keys = keys || this._parseAttribute(attribute);
|
|
449
|
+
let value = doc;
|
|
450
|
+
while (keys.length > 0) {
|
|
451
|
+
if (!(value && typeof value === 'object')) {
|
|
452
|
+
return undefined;
|
|
453
|
+
}
|
|
454
|
+
const key = keys.shift();
|
|
455
|
+
value = value[key];
|
|
456
|
+
if (Array.isArray(value)) {
|
|
457
|
+
// there are more keys, so recurse into array
|
|
458
|
+
return value
|
|
459
|
+
.map((v) => this._dereferenceAttribute({ keys: keys.slice(), doc: v }))
|
|
460
|
+
.filter((v) => v !== undefined);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return value;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function _assertHmac(hmac) {
|
|
467
|
+
if (!(hmac &&
|
|
468
|
+
typeof hmac === 'object' &&
|
|
469
|
+
typeof hmac.id === 'string' &&
|
|
470
|
+
typeof hmac.sign === 'function' &&
|
|
471
|
+
typeof hmac.verify === 'function')) {
|
|
472
|
+
throw new TypeError('"hmac" must be an object with "id", "sign", and "verify" properties.');
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
//# sourceMappingURL=LegacyIndexHelperVersion1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LegacyIndexHelperVersion1.js","sourceRoot":"","sources":["../src/LegacyIndexHelperVersion1.ts"],"names":[],"mappings":"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"}
|