@sphereon/ssi-sdk.resource-resolver 0.30.2-unstable.22 → 0.31.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 +4 -3
- package/dist/agent/ResourceResolver.d.ts +2 -0
- package/dist/agent/ResourceResolver.d.ts.map +1 -1
- package/dist/agent/ResourceResolver.js +31 -10
- package/dist/agent/ResourceResolver.js.map +1 -1
- package/dist/types/IResourceResolver.d.ts +8 -1
- package/dist/types/IResourceResolver.d.ts.map +1 -1
- package/dist/utils/ResourceResolverUtils.d.ts +1 -4
- package/dist/utils/ResourceResolverUtils.d.ts.map +1 -1
- package/dist/utils/ResourceResolverUtils.js +4 -9
- package/dist/utils/ResourceResolverUtils.js.map +1 -1
- package/package.json +5 -4
- package/src/agent/ResourceResolver.ts +39 -47
- package/src/types/IResourceResolver.ts +10 -2
- package/src/utils/ResourceResolverUtils.ts +12 -23
package/README.md
CHANGED
@@ -21,7 +21,8 @@ A Veramo resource resolver plugin. This plugin has the option to cache resources
|
|
21
21
|
- resourceDefaultStoreId
|
22
22
|
- resourceDefaultNamespace
|
23
23
|
- resourceDefaultTtl
|
24
|
-
-
|
24
|
+
-
|
25
|
+
|
25
26
|
## Usage
|
26
27
|
|
27
28
|
```typescript
|
@@ -42,8 +43,8 @@ const dbConnection = createConnection({
|
|
42
43
|
const agent = createAgent<IResourceResolver>({
|
43
44
|
plugins: [
|
44
45
|
new ResourceResolver({
|
45
|
-
resourceStores: new KeyValueStore({
|
46
|
-
store: new KeyValueTypeORMStoreAdapter({ dbConnection })
|
46
|
+
resourceStores: new KeyValueStore({
|
47
|
+
store: new KeyValueTypeORMStoreAdapter({ dbConnection }),
|
47
48
|
}),
|
48
49
|
}),
|
49
50
|
],
|
@@ -9,10 +9,12 @@ export declare class ResourceResolver implements IAgentPlugin {
|
|
9
9
|
private readonly defaultStoreId;
|
10
10
|
private readonly defaultNamespace;
|
11
11
|
private readonly defaultTtl;
|
12
|
+
private readonly detectLocation;
|
12
13
|
private readonly _resourceStores;
|
13
14
|
constructor(options?: ResourceResolverOptions);
|
14
15
|
/** {@inheritDoc IResourceResolver.resourceResolve} */
|
15
16
|
private resourceResolve;
|
17
|
+
private retrieveLocation;
|
16
18
|
/** {@inheritDoc IResourceResolver.resourceClearAllResources} */
|
17
19
|
private resourceClearAllResources;
|
18
20
|
/** {@inheritDoc IResourceResolver.resourceDefaultStoreId} */
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ResourceResolver.d.ts","sourceRoot":"","sources":["../../src/agent/ResourceResolver.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"ResourceResolver.d.ts","sourceRoot":"","sources":["../../src/agent/ResourceResolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAI3C,OAAO,EAIL,iBAAiB,EAKjB,uBAAuB,EAIxB,MAAM,4BAA4B,CAAA;AAEnC;;GAEG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IACnD,QAAQ,CAAC,MAAM,MAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAMlC;IAED,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAuC;gBAE3D,OAAO,CAAC,EAAE,uBAAuB;IAwB7C,sDAAsD;YACxC,eAAe;YAkDf,gBAAgB;IAc9B,gEAAgE;YAClD,yBAAyB;IAOvC,6DAA6D;YAC/C,sBAAsB;IAIpC,+DAA+D;YACjD,wBAAwB;IAItC,yDAAyD;YAC3C,kBAAkB;YAIlB,WAAW;YAUX,eAAe;IAe7B,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,MAAM;CAIf"}
|
@@ -50,10 +50,11 @@ class ResourceResolver {
|
|
50
50
|
resourceDefaultNamespace: this.resourceDefaultNamespace.bind(this),
|
51
51
|
resourceDefaultTtl: this.resourceDefaultTtl.bind(this),
|
52
52
|
};
|
53
|
-
const { defaultStore, defaultNamespace, resourceStores, ttl } = options !== null && options !== void 0 ? options : {};
|
53
|
+
const { defaultStore, defaultNamespace, resourceStores, ttl, detectLocation } = options !== null && options !== void 0 ? options : {};
|
54
54
|
this.defaultStoreId = defaultStore !== null && defaultStore !== void 0 ? defaultStore : '_default';
|
55
55
|
this.defaultNamespace = defaultNamespace !== null && defaultNamespace !== void 0 ? defaultNamespace : 'resources';
|
56
56
|
this.defaultTtl = ttl !== null && ttl !== void 0 ? ttl : 3600;
|
57
|
+
this.detectLocation = detectLocation !== null && detectLocation !== void 0 ? detectLocation : false;
|
57
58
|
if (resourceStores && resourceStores instanceof Map) {
|
58
59
|
this._resourceStores = resourceStores;
|
59
60
|
}
|
@@ -64,7 +65,7 @@ class ResourceResolver {
|
|
64
65
|
this._resourceStores = new Map().set(this.defaultStoreId, new ssi_sdk_kv_store_temp_1.KeyValueStore({
|
65
66
|
namespace: this.defaultNamespace,
|
66
67
|
store: new Map(),
|
67
|
-
ttl: this.defaultTtl
|
68
|
+
ttl: this.defaultTtl,
|
68
69
|
}));
|
69
70
|
}
|
70
71
|
}
|
@@ -74,32 +75,35 @@ class ResourceResolver {
|
|
74
75
|
const { input, init, resourceType, resolveOpts, partyCorrelationId, storeId, namespace } = args;
|
75
76
|
const resourceIdentifier = (0, ResourceResolverUtils_1.getResourceIdentifier)(input);
|
76
77
|
const cachedResource = yield this.getResource({ resourceIdentifier, storeId, namespace });
|
77
|
-
if (cachedResource.value &&
|
78
|
-
(0, ResourceResolverUtils_1.isCacheWithinMaxAge)(cachedResource, resolveOpts) &&
|
79
|
-
(0, ResourceResolverUtils_1.isRequestCacheable)(input, resolveOpts)) {
|
78
|
+
if (cachedResource.value && (0, ResourceResolverUtils_1.isCacheWithinMaxAge)(cachedResource.value, resolveOpts)) {
|
80
79
|
return (0, ResourceResolverUtils_1.deserializeResponse)(cachedResource.value.response);
|
81
80
|
}
|
82
81
|
if (resolveOpts === null || resolveOpts === void 0 ? void 0 : resolveOpts.onlyCache) {
|
83
82
|
return new cross_fetch_1.Response(JSON.stringify({ error: 'Resource not found' }), {
|
84
83
|
status: 404,
|
85
84
|
statusText: 'Not Found',
|
86
|
-
headers: new cross_fetch_1.Headers({ 'Content-Type': 'application/json' })
|
85
|
+
headers: new cross_fetch_1.Headers({ 'Content-Type': 'application/json' }),
|
87
86
|
});
|
88
87
|
}
|
88
|
+
let location;
|
89
|
+
if (this.detectLocation) {
|
90
|
+
location = yield this.retrieveLocation(input, context);
|
91
|
+
}
|
89
92
|
const response = yield (0, cross_fetch_1.default)(input, init);
|
90
|
-
if (!(resolveOpts === null || resolveOpts === void 0 ? void 0 : resolveOpts.skipPersistence) &&
|
93
|
+
if (!(resolveOpts === null || resolveOpts === void 0 ? void 0 : resolveOpts.skipPersistence) && response.status >= 200 && response.status < 300) {
|
91
94
|
const serializedResponse = yield (0, ResourceResolverUtils_1.serializeResponse)(response);
|
92
95
|
const resource = {
|
96
|
+
location,
|
93
97
|
response: serializedResponse,
|
94
98
|
resourceType,
|
95
99
|
insertedAt: Date.now(),
|
96
|
-
partyCorrelationId
|
100
|
+
partyCorrelationId,
|
97
101
|
};
|
98
102
|
const cachedResource = yield this.persistResource({
|
99
103
|
resource,
|
100
104
|
resourceIdentifier,
|
101
105
|
namespace,
|
102
|
-
storeId
|
106
|
+
storeId,
|
103
107
|
});
|
104
108
|
if (!cachedResource.value) {
|
105
109
|
return Promise.reject(Error('Resource not present in persistence result'));
|
@@ -109,6 +113,23 @@ class ResourceResolver {
|
|
109
113
|
return response;
|
110
114
|
});
|
111
115
|
}
|
116
|
+
retrieveLocation(input, context) {
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
118
|
+
let url;
|
119
|
+
if (input instanceof Request && input.url !== undefined && input.url !== null) {
|
120
|
+
url = new URL(input.url);
|
121
|
+
}
|
122
|
+
else if (input instanceof URL) {
|
123
|
+
url = input;
|
124
|
+
}
|
125
|
+
else {
|
126
|
+
throw Error(`input type is required to be RequestInfo | URL`);
|
127
|
+
}
|
128
|
+
return yield context.agent.anomalyDetectionLookupLocation({
|
129
|
+
ipOrHostname: url.hostname,
|
130
|
+
});
|
131
|
+
});
|
132
|
+
}
|
112
133
|
/** {@inheritDoc IResourceResolver.resourceClearAllResources} */
|
113
134
|
resourceClearAllResources(args, context) {
|
114
135
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -141,7 +162,7 @@ class ResourceResolver {
|
|
141
162
|
const { resourceIdentifier, storeId, namespace } = args;
|
142
163
|
return this.store({ stores: this._resourceStores, storeId }).getAsValueData(this.prefix({
|
143
164
|
namespace,
|
144
|
-
resourceIdentifier
|
165
|
+
resourceIdentifier,
|
145
166
|
}));
|
146
167
|
});
|
147
168
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ResourceResolver.js","sourceRoot":"","sources":["../../src/agent/ResourceResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
1
|
+
{"version":3,"file":"ResourceResolver.js","sourceRoot":"","sources":["../../src/agent/ResourceResolver.ts"],"names":[],"mappings":"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"}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { IKeyValueStore, ValueStoreType } from '@sphereon/ssi-sdk.kv-store-temp';
|
2
2
|
import { IAgentContext, IPluginMethodMap } from '@veramo/core';
|
3
|
+
import { IAnomalyDetection } from '@sphereon/ssi-sdk.anomaly-detection';
|
3
4
|
export interface IResourceResolver extends IPluginMethodMap {
|
4
5
|
resourceResolve(args: ResolveArgs, context: RequiredContext): Promise<Response>;
|
5
6
|
resourceClearAllResources(args: ClearAllResourcesArgs, context: RequiredContext): Promise<boolean>;
|
@@ -12,6 +13,7 @@ export type ResourceResolverOptions = {
|
|
12
13
|
defaultNamespace?: string;
|
13
14
|
resourceStores?: Map<string, IKeyValueStore<Resource>> | IKeyValueStore<Resource>;
|
14
15
|
ttl?: number;
|
16
|
+
detectLocation?: boolean;
|
15
17
|
};
|
16
18
|
export type ResolveArgs = {
|
17
19
|
input: RequestInfo | URL;
|
@@ -58,7 +60,12 @@ export type StoreArgs<T extends ValueStoreType> = {
|
|
58
60
|
stores: Map<string, IKeyValueStore<T>>;
|
59
61
|
storeId?: string;
|
60
62
|
};
|
63
|
+
export type Location = {
|
64
|
+
continent?: string;
|
65
|
+
country?: string;
|
66
|
+
};
|
61
67
|
export type Resource = {
|
68
|
+
location?: Location | null;
|
62
69
|
response: SerializedResponse;
|
63
70
|
resourceType: ResourceType;
|
64
71
|
insertedAt: number;
|
@@ -72,5 +79,5 @@ export type SerializedResponse = {
|
|
72
79
|
};
|
73
80
|
body: string;
|
74
81
|
};
|
75
|
-
export type RequiredContext = IAgentContext<
|
82
|
+
export type RequiredContext = IAgentContext<IAnomalyDetection>;
|
76
83
|
//# sourceMappingURL=IResourceResolver.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"IResourceResolver.d.ts","sourceRoot":"","sources":["../../src/types/IResourceResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;
|
1
|
+
{"version":3,"file":"IResourceResolver.d.ts","sourceRoot":"","sources":["../../src/types/IResourceResolver.ts"],"names":[],"mappings":"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"}
|
@@ -1,9 +1,6 @@
|
|
1
|
-
import { IValueData } from '@sphereon/ssi-sdk.kv-store-temp';
|
2
|
-
import { Response, Request } from 'cross-fetch';
|
3
1
|
import { ResolveOptions, Resource, SerializedResponse } from '../types/IResourceResolver';
|
4
2
|
export declare const getResourceIdentifier: (input: Request | string | URL) => string;
|
5
3
|
export declare const serializeResponse: (response: Response) => Promise<SerializedResponse>;
|
6
4
|
export declare const deserializeResponse: (data: SerializedResponse) => Promise<Response>;
|
7
|
-
export declare const isCacheWithinMaxAge: (cachedResource:
|
8
|
-
export declare const isRequestCacheable: (input: RequestInfo | URL, resolveOpts?: ResolveOptions) => boolean;
|
5
|
+
export declare const isCacheWithinMaxAge: (cachedResource: Resource, resolveOpts?: ResolveOptions) => boolean;
|
9
6
|
//# sourceMappingURL=ResourceResolverUtils.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ResourceResolverUtils.d.ts","sourceRoot":"","sources":["../../src/utils/ResourceResolverUtils.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"ResourceResolverUtils.d.ts","sourceRoot":"","sources":["../../src/utils/ResourceResolverUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAEzF,eAAO,MAAM,qBAAqB,UAAW,OAAO,GAAG,MAAM,GAAG,GAAG,KAAG,MAUrE,CAAA;AAED,eAAO,MAAM,iBAAiB,aAAoB,QAAQ,KAAG,OAAO,CAAC,kBAAkB,CAUtF,CAAA;AAED,eAAO,MAAM,mBAAmB,SAAgB,kBAAkB,KAAG,OAAO,CAAC,QAAQ,CAWpF,CAAA;AAGD,eAAO,MAAM,mBAAmB,mBAAoB,QAAQ,gBAAgB,cAAc,KAAG,OAE5F,CAAA"}
|
@@ -32,7 +32,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
32
32
|
});
|
33
33
|
};
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
35
|
-
exports.
|
35
|
+
exports.isCacheWithinMaxAge = exports.deserializeResponse = exports.serializeResponse = exports.getResourceIdentifier = void 0;
|
36
36
|
const cross_fetch_1 = require("cross-fetch");
|
37
37
|
const u8a = __importStar(require("uint8arrays"));
|
38
38
|
const getResourceIdentifier = (input) => {
|
@@ -55,7 +55,7 @@ const serializeResponse = (response) => __awaiter(void 0, void 0, void 0, functi
|
|
55
55
|
status: response.status,
|
56
56
|
statusText: response.statusText,
|
57
57
|
headers: Object.fromEntries(response.headers.entries()),
|
58
|
-
body: base64Url
|
58
|
+
body: base64Url,
|
59
59
|
};
|
60
60
|
});
|
61
61
|
exports.serializeResponse = serializeResponse;
|
@@ -66,18 +66,13 @@ const deserializeResponse = (data) => __awaiter(void 0, void 0, void 0, function
|
|
66
66
|
return new cross_fetch_1.Response(arrayBuffer, {
|
67
67
|
status,
|
68
68
|
statusText,
|
69
|
-
headers: new cross_fetch_1.Headers(headers)
|
69
|
+
headers: new cross_fetch_1.Headers(headers),
|
70
70
|
});
|
71
71
|
});
|
72
72
|
exports.deserializeResponse = deserializeResponse;
|
73
73
|
// Check if the cache is still within the acceptable age
|
74
74
|
const isCacheWithinMaxAge = (cachedResource, resolveOpts) => {
|
75
|
-
return
|
75
|
+
return cachedResource && ((resolveOpts === null || resolveOpts === void 0 ? void 0 : resolveOpts.maxAgeMs) === undefined || Date.now() - cachedResource.insertedAt < resolveOpts.maxAgeMs);
|
76
76
|
};
|
77
77
|
exports.isCacheWithinMaxAge = isCacheWithinMaxAge;
|
78
|
-
// Check if the request should use the cache
|
79
|
-
const isRequestCacheable = (input, resolveOpts) => {
|
80
|
-
return !(input instanceof cross_fetch_1.Request) || input.method === 'GET' || input.method === 'HEAD' || !!(resolveOpts === null || resolveOpts === void 0 ? void 0 : resolveOpts.onlyCache);
|
81
|
-
};
|
82
|
-
exports.isRequestCacheable = isRequestCacheable;
|
83
78
|
//# sourceMappingURL=ResourceResolverUtils.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ResourceResolverUtils.js","sourceRoot":"","sources":["../../src/utils/ResourceResolverUtils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
1
|
+
{"version":3,"file":"ResourceResolverUtils.js","sourceRoot":"","sources":["../../src/utils/ResourceResolverUtils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAwD;AACxD,iDAAkC;AAG3B,MAAM,qBAAqB,GAAG,CAAC,KAA6B,EAAU,EAAE;IAC7E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;SAAM,IAAI,KAAK,YAAY,qBAAO,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,GAAG,CAAA;IAClB,CAAC;SAAM,IAAI,KAAK,YAAY,GAAG,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAA;IACzB,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;AAC1E,CAAC,CAAA;AAVY,QAAA,qBAAqB,yBAUjC;AAEM,MAAM,iBAAiB,GAAG,CAAO,QAAkB,EAA+B,EAAE;IACzF,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;IAChD,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,CAAA;IAExE,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACvD,IAAI,EAAE,SAAS;KAChB,CAAA;AACH,CAAC,CAAA,CAAA;AAVY,QAAA,iBAAiB,qBAU7B;AAEM,MAAM,mBAAmB,GAAG,CAAO,IAAwB,EAAqB,EAAE;IACvF,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;IAElD,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IACpD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;IAEjH,OAAO,IAAI,sBAAQ,CAAC,WAAW,EAAE;QAC/B,MAAM;QACN,UAAU;QACV,OAAO,EAAE,IAAI,qBAAO,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAA;AACJ,CAAC,CAAA,CAAA;AAXY,QAAA,mBAAmB,uBAW/B;AAED,wDAAwD;AACjD,MAAM,mBAAmB,GAAG,CAAC,cAAwB,EAAE,WAA4B,EAAW,EAAE;IACrG,OAAO,cAAc,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ,MAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AACjI,CAAC,CAAA;AAFY,QAAA,mBAAmB,uBAE/B"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@sphereon/ssi-sdk.resource-resolver",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.31.0",
|
4
4
|
"source": "src/index.ts",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -14,14 +14,15 @@
|
|
14
14
|
"build:clean": "tsc --build --clean && tsc --build"
|
15
15
|
},
|
16
16
|
"dependencies": {
|
17
|
-
"@sphereon/ssi-sdk.
|
17
|
+
"@sphereon/ssi-sdk.anomaly-detection": "0.31.0",
|
18
|
+
"@sphereon/ssi-sdk.kv-store-temp": "0.31.0",
|
18
19
|
"cross-fetch": "^3.1.8",
|
19
20
|
"debug": "^4.3.5",
|
20
21
|
"typeorm": "^0.3.20",
|
21
22
|
"uint8arrays": "^3.1.1"
|
22
23
|
},
|
23
24
|
"devDependencies": {
|
24
|
-
"@sphereon/ssi-sdk.agent-config": "0.
|
25
|
+
"@sphereon/ssi-sdk.agent-config": "0.31.0",
|
25
26
|
"@veramo/remote-client": "4.2.0",
|
26
27
|
"@veramo/remote-server": "4.2.0",
|
27
28
|
"nock": "^13.5.4",
|
@@ -48,5 +49,5 @@
|
|
48
49
|
"Resource Management",
|
49
50
|
"Caching"
|
50
51
|
],
|
51
|
-
"gitHead": "
|
52
|
+
"gitHead": "3010f7bc57ed5f8d7953b6bf893e3164ea1821e8"
|
52
53
|
}
|
@@ -1,19 +1,8 @@
|
|
1
|
-
import {
|
2
|
-
IKeyValueStore,
|
3
|
-
IValueData,
|
4
|
-
KeyValueStore,
|
5
|
-
ValueStoreType
|
6
|
-
} from '@sphereon/ssi-sdk.kv-store-temp'
|
1
|
+
import { IKeyValueStore, IValueData, KeyValueStore, ValueStoreType } from '@sphereon/ssi-sdk.kv-store-temp'
|
7
2
|
import { IAgentPlugin } from '@veramo/core'
|
8
3
|
import fetch, { Response, Headers } from 'cross-fetch'
|
9
4
|
import { schema } from '../index'
|
10
|
-
import {
|
11
|
-
deserializeResponse,
|
12
|
-
getResourceIdentifier,
|
13
|
-
isCacheWithinMaxAge,
|
14
|
-
isRequestCacheable,
|
15
|
-
serializeResponse
|
16
|
-
} from '../utils/ResourceResolverUtils'
|
5
|
+
import { deserializeResponse, getResourceIdentifier, isCacheWithinMaxAge, serializeResponse } from '../utils/ResourceResolverUtils'
|
17
6
|
import {
|
18
7
|
ClearAllResourcesArgs,
|
19
8
|
ResolveArgs,
|
@@ -26,7 +15,7 @@ import {
|
|
26
15
|
ResourceResolverOptions,
|
27
16
|
StoreArgs,
|
28
17
|
StoreIdStrArgs,
|
29
|
-
Resource
|
18
|
+
Resource,
|
30
19
|
} from '../types/IResourceResolver'
|
31
20
|
|
32
21
|
/**
|
@@ -45,19 +34,16 @@ export class ResourceResolver implements IAgentPlugin {
|
|
45
34
|
private readonly defaultStoreId: string
|
46
35
|
private readonly defaultNamespace: string
|
47
36
|
private readonly defaultTtl: number
|
37
|
+
private readonly detectLocation: boolean
|
48
38
|
private readonly _resourceStores: Map<string, IKeyValueStore<Resource>>
|
49
39
|
|
50
40
|
constructor(options?: ResourceResolverOptions) {
|
51
|
-
const {
|
52
|
-
defaultStore,
|
53
|
-
defaultNamespace,
|
54
|
-
resourceStores,
|
55
|
-
ttl
|
56
|
-
} = options ?? {}
|
41
|
+
const { defaultStore, defaultNamespace, resourceStores, ttl, detectLocation } = options ?? {}
|
57
42
|
|
58
43
|
this.defaultStoreId = defaultStore ?? '_default'
|
59
44
|
this.defaultNamespace = defaultNamespace ?? 'resources'
|
60
45
|
this.defaultTtl = ttl ?? 3600
|
46
|
+
this.detectLocation = detectLocation ?? false
|
61
47
|
|
62
48
|
if (resourceStores && resourceStores instanceof Map) {
|
63
49
|
this._resourceStores = resourceStores
|
@@ -69,57 +55,51 @@ export class ResourceResolver implements IAgentPlugin {
|
|
69
55
|
new KeyValueStore({
|
70
56
|
namespace: this.defaultNamespace,
|
71
57
|
store: new Map<string, Resource>(),
|
72
|
-
ttl: this.defaultTtl
|
73
|
-
})
|
58
|
+
ttl: this.defaultTtl,
|
59
|
+
}),
|
74
60
|
)
|
75
61
|
}
|
76
62
|
}
|
77
63
|
|
78
64
|
/** {@inheritDoc IResourceResolver.resourceResolve} */
|
79
65
|
private async resourceResolve(args: ResolveArgs, context: RequiredContext): Promise<Response> {
|
80
|
-
const {
|
81
|
-
input,
|
82
|
-
init,
|
83
|
-
resourceType,
|
84
|
-
resolveOpts,
|
85
|
-
partyCorrelationId,
|
86
|
-
storeId,
|
87
|
-
namespace
|
88
|
-
} = args
|
66
|
+
const { input, init, resourceType, resolveOpts, partyCorrelationId, storeId, namespace } = args
|
89
67
|
|
90
68
|
const resourceIdentifier = getResourceIdentifier(input)
|
91
69
|
|
92
70
|
const cachedResource = await this.getResource({ resourceIdentifier, storeId, namespace })
|
93
|
-
if (
|
94
|
-
cachedResource.value
|
95
|
-
isCacheWithinMaxAge(cachedResource, resolveOpts) &&
|
96
|
-
isRequestCacheable(input, resolveOpts)
|
97
|
-
) {
|
98
|
-
return deserializeResponse(cachedResource.value.response);
|
71
|
+
if (cachedResource.value && isCacheWithinMaxAge(cachedResource.value, resolveOpts)) {
|
72
|
+
return deserializeResponse(cachedResource.value.response)
|
99
73
|
}
|
100
74
|
|
101
75
|
if (resolveOpts?.onlyCache) {
|
102
76
|
return new Response(JSON.stringify({ error: 'Resource not found' }), {
|
103
77
|
status: 404,
|
104
78
|
statusText: 'Not Found',
|
105
|
-
headers: new Headers({ 'Content-Type': 'application/json' })
|
106
|
-
})
|
79
|
+
headers: new Headers({ 'Content-Type': 'application/json' }),
|
80
|
+
})
|
81
|
+
}
|
82
|
+
|
83
|
+
let location
|
84
|
+
if (this.detectLocation) {
|
85
|
+
location = await this.retrieveLocation(input, context)
|
107
86
|
}
|
108
87
|
|
109
88
|
const response = await fetch(input, init)
|
110
|
-
if (!resolveOpts?.skipPersistence &&
|
111
|
-
const serializedResponse = await serializeResponse(response)
|
112
|
-
const resource = {
|
89
|
+
if (!resolveOpts?.skipPersistence && response.status >= 200 && response.status < 300) {
|
90
|
+
const serializedResponse = await serializeResponse(response)
|
91
|
+
const resource: Resource = {
|
92
|
+
location,
|
113
93
|
response: serializedResponse,
|
114
94
|
resourceType,
|
115
95
|
insertedAt: Date.now(),
|
116
|
-
partyCorrelationId
|
96
|
+
partyCorrelationId,
|
117
97
|
}
|
118
98
|
const cachedResource = await this.persistResource({
|
119
99
|
resource,
|
120
100
|
resourceIdentifier,
|
121
101
|
namespace,
|
122
|
-
storeId
|
102
|
+
storeId,
|
123
103
|
})
|
124
104
|
|
125
105
|
if (!cachedResource.value) {
|
@@ -132,6 +112,20 @@ export class ResourceResolver implements IAgentPlugin {
|
|
132
112
|
return response
|
133
113
|
}
|
134
114
|
|
115
|
+
private async retrieveLocation(input: RequestInfo | URL, context: RequiredContext) {
|
116
|
+
let url: URL
|
117
|
+
if (input instanceof Request && input.url !== undefined && input.url !== null) {
|
118
|
+
url = new URL(input.url)
|
119
|
+
} else if (input instanceof URL) {
|
120
|
+
url = input
|
121
|
+
} else {
|
122
|
+
throw Error(`input type is required to be RequestInfo | URL`)
|
123
|
+
}
|
124
|
+
return await context.agent.anomalyDetectionLookupLocation({
|
125
|
+
ipOrHostname: url.hostname,
|
126
|
+
})
|
127
|
+
}
|
128
|
+
|
135
129
|
/** {@inheritDoc IResourceResolver.resourceClearAllResources} */
|
136
130
|
private async resourceClearAllResources(args: ClearAllResourcesArgs, context: RequiredContext): Promise<boolean> {
|
137
131
|
const { storeId } = args
|
@@ -160,7 +154,7 @@ export class ResourceResolver implements IAgentPlugin {
|
|
160
154
|
return this.store({ stores: this._resourceStores, storeId }).getAsValueData(
|
161
155
|
this.prefix({
|
162
156
|
namespace,
|
163
|
-
resourceIdentifier
|
157
|
+
resourceIdentifier,
|
164
158
|
}),
|
165
159
|
)
|
166
160
|
}
|
@@ -203,6 +197,4 @@ export class ResourceResolver implements IAgentPlugin {
|
|
203
197
|
const { namespace, resourceIdentifier } = args
|
204
198
|
return `${this.namespaceStr({ namespace })}:${resourceIdentifier}`
|
205
199
|
}
|
206
|
-
|
207
200
|
}
|
208
|
-
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { IKeyValueStore, ValueStoreType } from '@sphereon/ssi-sdk.kv-store-temp'
|
2
2
|
import { IAgentContext, IPluginMethodMap } from '@veramo/core'
|
3
|
+
import { IAnomalyDetection } from '@sphereon/ssi-sdk.anomaly-detection'
|
3
4
|
|
4
5
|
export interface IResourceResolver extends IPluginMethodMap {
|
5
6
|
resourceResolve(args: ResolveArgs, context: RequiredContext): Promise<Response>
|
@@ -14,6 +15,7 @@ export type ResourceResolverOptions = {
|
|
14
15
|
defaultNamespace?: string
|
15
16
|
resourceStores?: Map<string, IKeyValueStore<Resource>> | IKeyValueStore<Resource>
|
16
17
|
ttl?: number
|
18
|
+
detectLocation?: boolean
|
17
19
|
}
|
18
20
|
|
19
21
|
export type ResolveArgs = {
|
@@ -62,7 +64,7 @@ export type NamespaceStrArgs = {
|
|
62
64
|
}
|
63
65
|
|
64
66
|
export type PrefixArgs = {
|
65
|
-
namespace?: string
|
67
|
+
namespace?: string
|
66
68
|
resourceIdentifier: string
|
67
69
|
}
|
68
70
|
|
@@ -71,7 +73,13 @@ export type StoreArgs<T extends ValueStoreType> = {
|
|
71
73
|
storeId?: string
|
72
74
|
}
|
73
75
|
|
76
|
+
export type Location = {
|
77
|
+
continent?: string
|
78
|
+
country?: string
|
79
|
+
}
|
80
|
+
|
74
81
|
export type Resource = {
|
82
|
+
location?: Location | null
|
75
83
|
response: SerializedResponse
|
76
84
|
resourceType: ResourceType
|
77
85
|
insertedAt: number
|
@@ -85,4 +93,4 @@ export type SerializedResponse = {
|
|
85
93
|
body: string
|
86
94
|
}
|
87
95
|
|
88
|
-
export type RequiredContext = IAgentContext<
|
96
|
+
export type RequiredContext = IAgentContext<IAnomalyDetection>
|
@@ -1,56 +1,45 @@
|
|
1
|
-
import { IValueData } from '@sphereon/ssi-sdk.kv-store-temp'
|
2
1
|
import { Headers, Response, Request } from 'cross-fetch'
|
3
2
|
import * as u8a from 'uint8arrays'
|
4
3
|
import { ResolveOptions, Resource, SerializedResponse } from '../types/IResourceResolver'
|
5
4
|
|
6
5
|
export const getResourceIdentifier = (input: Request | string | URL): string => {
|
7
6
|
if (typeof input === 'string') {
|
8
|
-
return input
|
7
|
+
return input
|
9
8
|
} else if (input instanceof Request) {
|
10
|
-
return input.url
|
9
|
+
return input.url
|
11
10
|
} else if (input instanceof URL) {
|
12
|
-
return input.toString()
|
11
|
+
return input.toString()
|
13
12
|
}
|
14
13
|
|
15
|
-
throw new Error('Invalid input type. Expected Request, string, or URL.')
|
14
|
+
throw new Error('Invalid input type. Expected Request, string, or URL.')
|
16
15
|
}
|
17
16
|
|
18
17
|
export const serializeResponse = async (response: Response): Promise<SerializedResponse> => {
|
19
|
-
const arrayBuffer = await response.arrayBuffer()
|
20
|
-
const base64Url = u8a.toString(new Uint8Array(arrayBuffer), 'base64url')
|
18
|
+
const arrayBuffer = await response.arrayBuffer()
|
19
|
+
const base64Url = u8a.toString(new Uint8Array(arrayBuffer), 'base64url')
|
21
20
|
|
22
21
|
return {
|
23
22
|
status: response.status,
|
24
23
|
statusText: response.statusText,
|
25
24
|
headers: Object.fromEntries(response.headers.entries()),
|
26
|
-
body: base64Url
|
25
|
+
body: base64Url,
|
27
26
|
}
|
28
27
|
}
|
29
28
|
|
30
29
|
export const deserializeResponse = async (data: SerializedResponse): Promise<Response> => {
|
31
|
-
const {
|
32
|
-
status,
|
33
|
-
statusText,
|
34
|
-
headers,
|
35
|
-
body
|
36
|
-
} = data
|
30
|
+
const { status, statusText, headers, body } = data
|
37
31
|
|
38
32
|
const uint8Array = u8a.fromString(body, 'base64url')
|
39
|
-
const arrayBuffer = uint8Array.buffer.slice(uint8Array.byteOffset, uint8Array.byteOffset + uint8Array.byteLength)
|
33
|
+
const arrayBuffer = uint8Array.buffer.slice(uint8Array.byteOffset, uint8Array.byteOffset + uint8Array.byteLength)
|
40
34
|
|
41
35
|
return new Response(arrayBuffer, {
|
42
36
|
status,
|
43
37
|
statusText,
|
44
|
-
headers: new Headers(headers)
|
38
|
+
headers: new Headers(headers),
|
45
39
|
})
|
46
40
|
}
|
47
41
|
|
48
42
|
// Check if the cache is still within the acceptable age
|
49
|
-
export const isCacheWithinMaxAge = (cachedResource:
|
50
|
-
return
|
51
|
-
}
|
52
|
-
|
53
|
-
// Check if the request should use the cache
|
54
|
-
export const isRequestCacheable = (input: RequestInfo | URL, resolveOpts?: ResolveOptions): boolean => {
|
55
|
-
return !(input instanceof Request) || input.method === 'GET' || input.method === 'HEAD' || !!resolveOpts?.onlyCache
|
43
|
+
export const isCacheWithinMaxAge = (cachedResource: Resource, resolveOpts?: ResolveOptions): boolean => {
|
44
|
+
return cachedResource && (resolveOpts?.maxAgeMs === undefined || Date.now() - cachedResource.insertedAt < resolveOpts.maxAgeMs)
|
56
45
|
}
|