@dcl/content-validator 1.0.1-20220125140415.commit-774a1b1 → 1.0.1-20220128144241.commit-9e37746
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/dist/content-validator.api.json +64 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validations/access-checker/scenes.d.ts.map +1 -1
- package/dist/validations/access-checker/scenes.js +120 -121
- package/dist/validations/access-checker/scenes.js.map +1 -1
- package/dist/validations/access-checker/wearables.d.ts.map +1 -1
- package/dist/validations/access-checker/wearables.js +151 -151
- package/dist/validations/access-checker/wearables.js.map +1 -1
- package/package.json +4 -3
|
@@ -321,6 +321,40 @@
|
|
|
321
321
|
"endIndex": 5
|
|
322
322
|
}
|
|
323
323
|
},
|
|
324
|
+
{
|
|
325
|
+
"kind": "TypeAlias",
|
|
326
|
+
"canonicalReference": "@dcl/content-validator!ContentValidatorComponents:type",
|
|
327
|
+
"docComment": "/**\n * Components that can be used to validate deployments.\n *\n * @public\n */\n",
|
|
328
|
+
"excerptTokens": [
|
|
329
|
+
{
|
|
330
|
+
"kind": "Content",
|
|
331
|
+
"text": "export declare type ContentValidatorComponents = "
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"kind": "Content",
|
|
335
|
+
"text": "{\n logs: "
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"kind": "Reference",
|
|
339
|
+
"text": "ILoggerComponent",
|
|
340
|
+
"canonicalReference": "@well-known-components/interfaces!ILoggerComponent:type"
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"kind": "Content",
|
|
344
|
+
"text": ";\n}"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"kind": "Content",
|
|
348
|
+
"text": ";"
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
"releaseTag": "Public",
|
|
352
|
+
"name": "ContentValidatorComponents",
|
|
353
|
+
"typeTokenRange": {
|
|
354
|
+
"startIndex": 1,
|
|
355
|
+
"endIndex": 4
|
|
356
|
+
}
|
|
357
|
+
},
|
|
324
358
|
{
|
|
325
359
|
"kind": "Variable",
|
|
326
360
|
"canonicalReference": "@dcl/content-validator!createValidator:var",
|
|
@@ -341,7 +375,25 @@
|
|
|
341
375
|
},
|
|
342
376
|
{
|
|
343
377
|
"kind": "Content",
|
|
344
|
-
"text": "
|
|
378
|
+
"text": ", components?: "
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"kind": "Reference",
|
|
382
|
+
"text": "Pick",
|
|
383
|
+
"canonicalReference": "!Pick:type"
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
"kind": "Content",
|
|
387
|
+
"text": "<"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"kind": "Reference",
|
|
391
|
+
"text": "ContentValidatorComponents",
|
|
392
|
+
"canonicalReference": "@dcl/content-validator!ContentValidatorComponents:type"
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"kind": "Content",
|
|
396
|
+
"text": ", \"logs\"> | undefined) => "
|
|
345
397
|
},
|
|
346
398
|
{
|
|
347
399
|
"kind": "Reference",
|
|
@@ -353,7 +405,7 @@
|
|
|
353
405
|
"name": "createValidator",
|
|
354
406
|
"variableTypeTokenRange": {
|
|
355
407
|
"startIndex": 1,
|
|
356
|
-
"endIndex":
|
|
408
|
+
"endIndex": 9
|
|
357
409
|
}
|
|
358
410
|
},
|
|
359
411
|
{
|
|
@@ -898,6 +950,15 @@
|
|
|
898
950
|
"text": "ValidationArgs",
|
|
899
951
|
"canonicalReference": "@dcl/content-validator!ValidationArgs:type"
|
|
900
952
|
},
|
|
953
|
+
{
|
|
954
|
+
"kind": "Content",
|
|
955
|
+
"text": ", logs?: "
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
"kind": "Reference",
|
|
959
|
+
"text": "ILoggerComponent.ILogger",
|
|
960
|
+
"canonicalReference": "@well-known-components/interfaces!ILoggerComponent.ILogger:type"
|
|
961
|
+
},
|
|
901
962
|
{
|
|
902
963
|
"kind": "Content",
|
|
903
964
|
"text": ") => "
|
|
@@ -938,7 +999,7 @@
|
|
|
938
999
|
"name": "Validation",
|
|
939
1000
|
"typeTokenRange": {
|
|
940
1001
|
"startIndex": 1,
|
|
941
|
-
"endIndex":
|
|
1002
|
+
"endIndex": 12
|
|
942
1003
|
}
|
|
943
1004
|
},
|
|
944
1005
|
{
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ExternalCalls, Validator } from './types';
|
|
1
|
+
import { ContentValidatorComponents, ExternalCalls, Validator } from './types';
|
|
2
2
|
export * from './types';
|
|
3
3
|
export * from './validations';
|
|
4
4
|
/**
|
|
5
5
|
* Creates a validator instance with given external calls.
|
|
6
6
|
* @public
|
|
7
7
|
*/
|
|
8
|
-
export declare const createValidator: (externalCalls: ExternalCalls) => Validator;
|
|
8
|
+
export declare const createValidator: (externalCalls: ExternalCalls, components?: Pick<ContentValidatorComponents, "logs"> | undefined) => Validator;
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAM,SAAS,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAM,SAAS,EAAE,MAAM,SAAS,CAAA;AAGlF,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAE7B;;;GAGG;AACH,eAAO,MAAM,eAAe,kBACX,aAAa,wEAE3B,SAYD,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -19,12 +19,15 @@ __exportStar(require("./validations"), exports);
|
|
|
19
19
|
* Creates a validator instance with given external calls.
|
|
20
20
|
* @public
|
|
21
21
|
*/
|
|
22
|
-
const createValidator = (externalCalls) => ({
|
|
22
|
+
const createValidator = (externalCalls, components) => ({
|
|
23
23
|
validate: async (deployment) => {
|
|
24
|
+
const logs = components?.logs.getLogger('ContentValidator');
|
|
24
25
|
for (const validation of validations_1.validations) {
|
|
25
|
-
const result = await validation.validate({ deployment, externalCalls });
|
|
26
|
-
if (!result.ok)
|
|
26
|
+
const result = await validation.validate({ deployment, externalCalls }, logs);
|
|
27
|
+
if (!result.ok) {
|
|
28
|
+
logs?.debug(`Validation failed:\n${result.errors?.join('\n')}`);
|
|
27
29
|
return result;
|
|
30
|
+
}
|
|
28
31
|
}
|
|
29
32
|
return types_1.OK;
|
|
30
33
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,mCAAkF;AAClF,+CAA2C;AAE3C,0CAAuB;AACvB,gDAA6B;AAE7B;;;GAGG;AACI,MAAM,eAAe,GAAG,CAC7B,aAA4B,EAC5B,UAAqD,EAC1C,EAAE,CAAC,CAAC;IACf,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAA;QAC3D,KAAK,MAAM,UAAU,IAAI,yBAAW,EAAE;YACpC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,IAAI,CAAC,CAAA;YAC7E,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;gBACd,IAAI,EAAE,KAAK,CAAC,uBAAuB,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;gBAC/D,OAAO,MAAM,CAAA;aACd;SACF;QACD,OAAO,UAAE,CAAA;IACX,CAAC;CACF,CAAC,CAAA;AAfW,QAAA,eAAe,mBAe1B"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ILoggerComponent } from '@well-known-components/interfaces';
|
|
1
2
|
import { AuditInfo, ContentFileHash, Entity, EntityId, Fetcher } from 'dcl-catalyst-commons';
|
|
2
3
|
/**
|
|
3
4
|
* @public
|
|
@@ -77,7 +78,7 @@ export declare type ValidationResponse = {
|
|
|
77
78
|
* @public
|
|
78
79
|
*/
|
|
79
80
|
export declare type Validation = {
|
|
80
|
-
validate: (args: ValidationArgs) => ValidationResponse | Promise<ValidationResponse>;
|
|
81
|
+
validate: (args: ValidationArgs, logs?: ILoggerComponent.ILogger) => ValidationResponse | Promise<ValidationResponse>;
|
|
81
82
|
};
|
|
82
83
|
/**
|
|
83
84
|
* @public
|
|
@@ -102,4 +103,11 @@ export declare const conditionalValidation: (condition: ConditionalValidation) =
|
|
|
102
103
|
* @public
|
|
103
104
|
*/
|
|
104
105
|
export declare const fromErrors: (...errors: Errors) => ValidationResponse;
|
|
106
|
+
/**
|
|
107
|
+
* Components that can be used to validate deployments.
|
|
108
|
+
* @public
|
|
109
|
+
*/
|
|
110
|
+
export declare type ContentValidatorComponents = {
|
|
111
|
+
logs: ILoggerComponent;
|
|
112
|
+
};
|
|
105
113
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAE5F;;GAEG;AACH,oBAAY,wBAAwB,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,CAAC,CAAA;AAErF;;GAEG;AACH,oBAAY,MAAM,GAAG,MAAM,EAAE,CAAA;AAE7B;;GAEG;AACH,oBAAY,QAAQ,GAAG,MAAM,EAAE,CAAA;AAE/B;;GAEG;AACH,oBAAY,oBAAoB,GAAG,MAAM,GAAG;IAC1C,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;GAGG;AACH,oBAAY,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IACvC,SAAS,EAAE,wBAAwB,CAAA;CACpC,CAAA;AAED;;;GAGG;AACH,oBAAY,aAAa,GAAG;IAC1B,sBAAsB,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAA;IAC7F,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACnE,iBAAiB,EAAE,CACjB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,wBAAwB,EACnC,SAAS,EAAE,MAAM,KACd,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC/C,YAAY,EAAE,CAAC,SAAS,EAAE,wBAAwB,KAAK,MAAM,CAAA;IAC7D,4BAA4B,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAA;IAC1D,UAAU,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,EAAE,EAAE;YACF,WAAW,EAAE,MAAM,CAAA;YACnB,MAAM,EAAE,MAAM,CAAA;YACd,WAAW,EAAE,MAAM,CAAA;SACpB,CAAA;QACD,EAAE,EAAE;YACF,MAAM,EAAE,MAAM,CAAA;YACd,WAAW,EAAE,MAAM,CAAA;SACpB,CAAA;KACF,CAAA;CACF,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;CACxE;AAED;;GAEG;AACH,oBAAY,cAAc,GAAG;IAC3B,UAAU,EAAE,oBAAoB,CAAA;IAChC,aAAa,EAAE,aAAa,CAAA;CAC7B,CAAA;AAED;;GAEG;AACH,oBAAY,kBAAkB,GAAG;IAC/B,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;GAEG;AACH,oBAAY,UAAU,GAAG;IACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAsGA;;GAEG;AACU,QAAA,EAAE,GAAuB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AAElD;;GAEG;AACI,MAAM,gBAAgB,GAAG,CAAC,GAAG,KAAe,EAAsB,EAAE,CAAC,CAAC;IAC3E,EAAE,EAAE,KAAK;IACT,MAAM,EAAE,KAAK;CACd,CAAC,CAAA;AAHW,QAAA,gBAAgB,oBAG3B;AAEF;;GAEG;AACI,MAAM,qBAAqB,GAAG,CAAC,SAAgC,EAAc,EAAE,CAAC,CAAC;IACtF,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACvB,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE;YACtC,OAAO,IAAA,wBAAgB,EAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;SACjD;QACD,OAAO,UAAE,CAAA;IACX,CAAC;CACF,CAAC,CAAA;AAPW,QAAA,qBAAqB,yBAOhC;AAEF;;GAEG;AACI,MAAM,UAAU,GAAG,CAAC,GAAG,MAAc,EAAsB,EAAE,CAAC,CAAC;IACpE,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;CAC/C,CAAC,CAAA;AAHW,QAAA,UAAU,cAGrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../../src/validations/access-checker/scenes.ts"],"names":[],"mappings":"AAGA,OAAO,EAA6B,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../../src/validations/access-checker/scenes.ts"],"names":[],"mappings":"AAGA,OAAO,EAA6B,UAAU,EAAE,MAAM,aAAa,CAAA;AA+BnE;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,UAiTpB,CAAA"}
|
|
@@ -7,8 +7,14 @@ exports.scenes = void 0;
|
|
|
7
7
|
const dcl_catalyst_commons_1 = require("dcl-catalyst-commons");
|
|
8
8
|
const ms_1 = __importDefault(require("ms"));
|
|
9
9
|
const types_1 = require("../../types");
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Checks if the given address has access to the given parcel at the given timestamp.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
exports.scenes = {
|
|
15
|
+
validate: async ({ deployment, externalCalls }, logs) => {
|
|
16
|
+
const getAuthorizations = async (owner, operator, timestamp) => {
|
|
17
|
+
const query = `
|
|
12
18
|
query GetAuthorizations($owner: String!, $operator: String!, $timestamp: Int!) {
|
|
13
19
|
authorizations(
|
|
14
20
|
where: {
|
|
@@ -23,26 +29,26 @@ const getAuthorizations = async (owner, operator, timestamp, externalCalls) => {
|
|
|
23
29
|
isApproved
|
|
24
30
|
}
|
|
25
31
|
}`;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
};
|
|
39
|
-
const getEstate = async (estateId, timestamp
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
const variables = {
|
|
33
|
+
owner,
|
|
34
|
+
operator,
|
|
35
|
+
timestamp: Math.floor(timestamp / 1000), // js(ms) -> UNIX(s)
|
|
36
|
+
};
|
|
37
|
+
try {
|
|
38
|
+
return (await externalCalls.queryGraph(externalCalls.subgraphs.L1.landManager, query, variables)).authorizations;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logs?.error(`Error fetching authorizations for ${owner}`);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const getEstate = async (estateId, timestamp) => {
|
|
46
|
+
/**
|
|
47
|
+
* You can use `owner`, `operator` and `updateOperator` to check the current value for that estate.
|
|
48
|
+
* Keep in mind that each association (owners, operators, etc) is capped to a thousand (1000) results.
|
|
49
|
+
* For more information, you can use the query explorer at https://thegraph.com/explorer/subgraph/decentraland/land-manager
|
|
50
|
+
*/
|
|
51
|
+
const query = `
|
|
46
52
|
query GetEstate($estateId: String!, $timestamp: Int!) {
|
|
47
53
|
estates(where:{ id: $estateId }) {
|
|
48
54
|
id
|
|
@@ -72,25 +78,25 @@ const getEstate = async (estateId, timestamp, externalCalls) => {
|
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
}`;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
87
|
-
const getParcel = async (x, y, timestamp
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
81
|
+
const variables = {
|
|
82
|
+
estateId,
|
|
83
|
+
timestamp: Math.floor(timestamp / 1000), // UNIX
|
|
84
|
+
};
|
|
85
|
+
try {
|
|
86
|
+
return (await externalCalls.queryGraph(externalCalls.subgraphs.L1.landManager, query, variables)).estates[0];
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
logs?.error(`Error fetching estate (${estateId})`);
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const getParcel = async (x, y, timestamp) => {
|
|
94
|
+
/**
|
|
95
|
+
* You can use `owner`, `operator` and `updateOperator` to check the current value for that parcel.
|
|
96
|
+
* Keep in mind that each association (owners, operators, etc) is capped to a thousand (1000) results.
|
|
97
|
+
* For more information, you can use the query explorer at https://thegraph.com/explorer/subgraph/decentraland/land-manager
|
|
98
|
+
*/
|
|
99
|
+
const query = `
|
|
94
100
|
query GetParcel($x: Int!, $y: Int!, $timestamp: Int!) {
|
|
95
101
|
parcels(where:{ x: $x, y: $y }) {
|
|
96
102
|
estates(
|
|
@@ -127,86 +133,79 @@ const getParcel = async (x, y, timestamp, externalCalls) => {
|
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
135
|
}`;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
};
|
|
147
|
-
const hasAccessThroughAuthorizations = async (owner, ethAddress, timestamp
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
};
|
|
163
|
-
const hasAccessThroughFirstLevelAuthorities = async (target, ethAddress) => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
};
|
|
169
|
-
const isEstateUpdateAuthorized = async (estateId, timestamp, ethAddress
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
};
|
|
177
|
-
const isParcelUpdateAuthorized = async (x, y, timestamp, ethAddress, externalCalls) => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const SCENE_LOOKBACK_TIME = (0, ms_1.default)('5m');
|
|
204
|
-
/**
|
|
205
|
-
* Checks if the given address has access to the given parcel at the given timestamp.
|
|
206
|
-
* @public
|
|
207
|
-
*/
|
|
208
|
-
exports.scenes = {
|
|
209
|
-
validate: async ({ deployment, externalCalls }) => {
|
|
136
|
+
const variables = {
|
|
137
|
+
x,
|
|
138
|
+
y,
|
|
139
|
+
timestamp: Math.floor(timestamp / 1000), // UNIX
|
|
140
|
+
};
|
|
141
|
+
try {
|
|
142
|
+
const r = await externalCalls.queryGraph(externalCalls.subgraphs.L1.landManager, query, variables);
|
|
143
|
+
if (r.parcels && r.parcels.length)
|
|
144
|
+
return r.parcels[0];
|
|
145
|
+
logs?.error(`Error fetching parcel (${x}, ${y}, ${timestamp}): ${JSON.stringify(r)}`);
|
|
146
|
+
throw new Error(`Error fetching parcel (${x}, ${y}), ${timestamp}`);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
logs?.error(`Error fetching parcel (${x}, ${y}, ${timestamp})`);
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const hasAccessThroughAuthorizations = async (owner, ethAddress, timestamp) => {
|
|
154
|
+
/* You also get access if you received:
|
|
155
|
+
* - an authorization with isApproved and type Operator, ApprovalForAll or UpdateManager
|
|
156
|
+
* at that time
|
|
157
|
+
*/
|
|
158
|
+
const authorizations = await getAuthorizations(owner.toLowerCase(), ethAddress.toLowerCase(), timestamp);
|
|
159
|
+
const firstOperatorAuthorization = authorizations.find((authorization) => authorization.type === 'Operator');
|
|
160
|
+
const firstApprovalForAllAuthorization = authorizations.find((authorization) => authorization.type === 'ApprovalForAll');
|
|
161
|
+
const firstUpdateManagerAuthorization = authorizations.find((authorization) => authorization.type === 'UpdateManager');
|
|
162
|
+
if (firstOperatorAuthorization?.isApproved ||
|
|
163
|
+
firstApprovalForAllAuthorization?.isApproved ||
|
|
164
|
+
firstUpdateManagerAuthorization?.isApproved) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
};
|
|
169
|
+
const hasAccessThroughFirstLevelAuthorities = async (target, ethAddress) => {
|
|
170
|
+
const firstLevelAuthorities = [...target.owners, ...target.operators, ...target.updateOperators]
|
|
171
|
+
.filter((addressSnapshot) => addressSnapshot.address)
|
|
172
|
+
.map((addressSnapshot) => addressSnapshot.address.toLowerCase());
|
|
173
|
+
return firstLevelAuthorities.includes(ethAddress.toLowerCase());
|
|
174
|
+
};
|
|
175
|
+
const isEstateUpdateAuthorized = async (estateId, timestamp, ethAddress) => {
|
|
176
|
+
const estate = await getEstate(estateId.toString(), timestamp);
|
|
177
|
+
if (estate) {
|
|
178
|
+
return ((await hasAccessThroughFirstLevelAuthorities(estate, ethAddress)) ||
|
|
179
|
+
(await hasAccessThroughAuthorizations(estate.owners[0].address, ethAddress, timestamp)));
|
|
180
|
+
}
|
|
181
|
+
throw new Error(`Couldn\'t find the state ${estateId}`);
|
|
182
|
+
};
|
|
183
|
+
const isParcelUpdateAuthorized = async (x, y, timestamp, ethAddress, externalCalls) => {
|
|
184
|
+
/* You get direct access if you were the:
|
|
185
|
+
* - owner
|
|
186
|
+
* - operator
|
|
187
|
+
* - update operator
|
|
188
|
+
* at that time
|
|
189
|
+
*/
|
|
190
|
+
const parcel = await getParcel(x, y, timestamp);
|
|
191
|
+
if (parcel) {
|
|
192
|
+
const belongsToEstate = parcel.estates != undefined && parcel.estates.length > 0 && parcel.estates[0].estateId != undefined;
|
|
193
|
+
return ((await hasAccessThroughFirstLevelAuthorities(parcel, ethAddress)) ||
|
|
194
|
+
(await hasAccessThroughAuthorizations(parcel.owners[0].address, ethAddress, timestamp)) ||
|
|
195
|
+
(belongsToEstate && (await isEstateUpdateAuthorized(parcel.estates[0].estateId, timestamp, ethAddress))));
|
|
196
|
+
}
|
|
197
|
+
throw new Error(`Parcel(${x},${y},${timestamp}) not found`);
|
|
198
|
+
};
|
|
199
|
+
const checkParcelAccess = async (x, y, timestamp, ethAddress, externalCalls) => {
|
|
200
|
+
try {
|
|
201
|
+
return await (0, dcl_catalyst_commons_1.retry)(() => isParcelUpdateAuthorized(x, y, timestamp, ethAddress, externalCalls), 5, '0.1s');
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
logs?.error(`Error checking parcel access (${x}, ${y}, ${timestamp}, ${ethAddress}).`);
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const SCENE_LOOKBACK_TIME = (0, ms_1.default)('5m');
|
|
210
209
|
const { entity } = deployment;
|
|
211
210
|
const { pointers, timestamp } = entity;
|
|
212
211
|
const ethAddress = externalCalls.ownerAddress(deployment.auditInfo);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenes.js","sourceRoot":"","sources":["../../../src/validations/access-checker/scenes.ts"],"names":[],"mappings":";;;;;;AACA,+DAAuD;AACvD,4CAAmB;AACnB,uCAAmE;AA+BnE,MAAM,iBAAiB,GAAG,KAAK,EAC7B,KAAiB,EACjB,QAAoB,EACpB,SAAoB,
|
|
1
|
+
{"version":3,"file":"scenes.js","sourceRoot":"","sources":["../../../src/validations/access-checker/scenes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wearables.d.ts","sourceRoot":"","sources":["../../../src/validations/access-checker/wearables.ts"],"names":[],"mappings":"AAKA,OAAO,EAAM,UAAU,EAAE,MAAM,aAAa,CAAA;AA0B5C,oBAAY,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,sBAAsB,EAAE,CAAA;CAChC,CAAA;AAED,aAAK,sBAAsB,GAAG;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;
|
|
1
|
+
{"version":3,"file":"wearables.d.ts","sourceRoot":"","sources":["../../../src/validations/access-checker/wearables.ts"],"names":[],"mappings":"AAKA,OAAO,EAAM,UAAU,EAAE,MAAM,aAAa,CAAA;AA0B5C,oBAAY,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,sBAAsB,EAAE,CAAA;CAChC,CAAA;AAED,aAAK,sBAAsB,GAAG;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AA8BD;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,UA2QvB,CAAA"}
|
|
@@ -40,162 +40,159 @@ const parseUrnNoFail = async (urn) => {
|
|
|
40
40
|
catch { }
|
|
41
41
|
return null;
|
|
42
42
|
};
|
|
43
|
-
const hasPermission = async (subgraphUrl, collection, itemId, block, entity, externalCalls) => {
|
|
44
|
-
try {
|
|
45
|
-
const { content, metadata } = entity;
|
|
46
|
-
const permissions = await getCollectionItems(subgraphUrl, collection, itemId, block, externalCalls);
|
|
47
|
-
const ethAddressLowercase = entity.ethAddress.toLowerCase();
|
|
48
|
-
if (!!permissions.contentHash) {
|
|
49
|
-
const deployedByCommittee = permissions.committee.includes(ethAddressLowercase);
|
|
50
|
-
const calculateHashes = () => {
|
|
51
|
-
// Compare both by key and hash
|
|
52
|
-
const compare = (a, b) => {
|
|
53
|
-
if (a.hash > b.hash)
|
|
54
|
-
return 1;
|
|
55
|
-
else if (a.hash < b.hash)
|
|
56
|
-
return -1;
|
|
57
|
-
else
|
|
58
|
-
return a.key > b.key ? 1 : -1;
|
|
59
|
-
};
|
|
60
|
-
const contentAsJson = (content ?? []).map(({ file, hash }) => ({ key: file, hash })).sort(compare);
|
|
61
|
-
const buffer = Buffer.from(JSON.stringify({ content: contentAsJson, metadata }));
|
|
62
|
-
return Promise.all([dcl_catalyst_commons_1.Hashing.calculateBufferHash(buffer), dcl_catalyst_commons_1.Hashing.calculateIPFSHash(buffer)]);
|
|
63
|
-
};
|
|
64
|
-
return deployedByCommittee && (await calculateHashes()).includes(permissions.contentHash);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
const addressHasAccess = (permissions.collectionCreator && permissions.collectionCreator === ethAddressLowercase) ||
|
|
68
|
-
(permissions.collectionManagers && permissions.collectionManagers.includes(ethAddressLowercase)) ||
|
|
69
|
-
(permissions.itemManagers && permissions.itemManagers.includes(ethAddressLowercase));
|
|
70
|
-
// Deployments to the content server are made after the collection is completed, so that the committee can then approve it.
|
|
71
|
-
// That's why isCompleted must be true, but isApproved must be false. After the committee approves the wearable, there can't be any more changes
|
|
72
|
-
const isCollectionValid = !permissions.isApproved && permissions.isCompleted;
|
|
73
|
-
return addressHasAccess && isCollectionValid;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
// this.LOGGER.error(`Error checking permission for (${collection}-${itemId}) at block ${block}`, error)
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
const getCollectionItems = async (subgraphUrl, collection, itemId, block, externalCalls) => {
|
|
82
|
-
const query = `
|
|
83
|
-
query getCollectionRoles($collection: String!, $itemId: String!, $block: Int!) {
|
|
84
|
-
collections(where:{ id: $collection }, block: { number: $block }) {
|
|
85
|
-
creator
|
|
86
|
-
managers
|
|
87
|
-
isApproved
|
|
88
|
-
isCompleted
|
|
89
|
-
items(where:{ id: $itemId }) {
|
|
90
|
-
managers
|
|
91
|
-
contentHash
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
accounts(where:{ isCommitteeMember: true }, block: { number: $block }) {
|
|
96
|
-
id
|
|
97
|
-
}
|
|
98
|
-
}`;
|
|
99
|
-
const result = await externalCalls.queryGraph(subgraphUrl, query, {
|
|
100
|
-
collection,
|
|
101
|
-
itemId: `${collection}-${itemId}`,
|
|
102
|
-
block,
|
|
103
|
-
});
|
|
104
|
-
const collectionResult = result.collections[0];
|
|
105
|
-
const itemResult = collectionResult?.items[0];
|
|
106
|
-
return {
|
|
107
|
-
collectionCreator: collectionResult?.creator,
|
|
108
|
-
collectionManagers: collectionResult?.managers,
|
|
109
|
-
isApproved: collectionResult?.isApproved,
|
|
110
|
-
isCompleted: collectionResult?.isCompleted,
|
|
111
|
-
itemManagers: itemResult?.managers,
|
|
112
|
-
contentHash: itemResult?.contentHash,
|
|
113
|
-
committee: result.accounts.map(({ id }) => id.toLowerCase()),
|
|
114
|
-
};
|
|
115
|
-
};
|
|
116
|
-
const getWindowFromTimestamp = (timestamp) => {
|
|
117
|
-
const windowMin = timestamp - Math.floor(ACCESS_WINDOW_IN_SECONDS / 2);
|
|
118
|
-
const windowMax = timestamp + Math.ceil(ACCESS_WINDOW_IN_SECONDS / 2);
|
|
119
|
-
return {
|
|
120
|
-
max: windowMax,
|
|
121
|
-
min: windowMin,
|
|
122
|
-
};
|
|
123
|
-
};
|
|
124
|
-
const findBlocksForTimestamp = async (blocksSubgraphUrl, timestamp, externalCalls) => {
|
|
125
|
-
const query = `
|
|
126
|
-
query getBlockForTimestamp($timestamp: Int!, $timestampMin: Int!, $timestampMax: Int!, $timestamp5Min: Int!, $timestamp5MinMax: Int!, $timestamp5MinMin: Int!) {
|
|
127
|
-
before: blocks(where: { timestamp_lte: $timestamp, timestamp_gte: $timestampMin }, first: 1, orderBy: timestamp, orderDirection: desc) {
|
|
128
|
-
number
|
|
129
|
-
}
|
|
130
|
-
after: blocks(where: { timestamp_gte: $timestamp, timestamp_lte: $timestampMax }, first: 1, orderBy: timestamp, orderDirection: asc) {
|
|
131
|
-
number
|
|
132
|
-
}
|
|
133
|
-
fiveMinBefore: blocks(where: { timestamp_lte: $timestamp5Min, timestamp_gte: $timestamp5MinMin, }, first: 1, orderBy: timestamp, orderDirection: desc) {
|
|
134
|
-
number
|
|
135
|
-
}
|
|
136
|
-
fiveMinAfter: blocks(where: { timestamp_gte: $timestamp5Min, timestamp_lte: $timestamp5MinMax }, first: 1, orderBy: timestamp, orderDirection: asc) {
|
|
137
|
-
number
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
`;
|
|
141
|
-
try {
|
|
142
|
-
const timestampSec = Math.ceil(timestamp / 1000);
|
|
143
|
-
const timestamp5MinAgo = timestampSec - 60 * 5;
|
|
144
|
-
const window = getWindowFromTimestamp(timestampSec);
|
|
145
|
-
const window5MinAgo = getWindowFromTimestamp(timestamp5MinAgo);
|
|
146
|
-
const result = await externalCalls.queryGraph(blocksSubgraphUrl, query, {
|
|
147
|
-
timestamp: timestampSec,
|
|
148
|
-
timestampMax: window.max,
|
|
149
|
-
timestampMin: window.min,
|
|
150
|
-
timestamp5Min: timestamp5MinAgo,
|
|
151
|
-
timestamp5MinMax: window5MinAgo.max,
|
|
152
|
-
timestamp5MinMin: window5MinAgo.min,
|
|
153
|
-
});
|
|
154
|
-
// To get the deployment's block number, we check the one immediately after the entity's timestamp. Since it could not exist, we default to the one immediately before.
|
|
155
|
-
const blockNumberAtDeployment = result.after[0]?.number ?? result.before[0]?.number;
|
|
156
|
-
const blockNumberFiveMinBeforeDeployment = result.fiveMinAfter[0]?.number ?? result.fiveMinBefore[0]?.number;
|
|
157
|
-
if (blockNumberAtDeployment === undefined && blockNumberFiveMinBeforeDeployment === undefined) {
|
|
158
|
-
throw new Error(`Failed to find blocks for the specific timestamp`);
|
|
159
|
-
}
|
|
160
|
-
return {
|
|
161
|
-
blockNumberAtDeployment: !!blockNumberAtDeployment ? parseInt(blockNumberAtDeployment) : undefined,
|
|
162
|
-
blockNumberFiveMinBeforeDeployment: !!blockNumberFiveMinBeforeDeployment
|
|
163
|
-
? parseInt(blockNumberFiveMinBeforeDeployment)
|
|
164
|
-
: undefined,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
// this.LOGGER.error(`Error fetching the block number for timestamp`, { timestamp, error: error.message })
|
|
169
|
-
throw error;
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
const checkCollectionAccess = async (blocksSubgraphUrl, collectionsSubgraphUrl, collection, itemId, entity, externalCalls) => {
|
|
173
|
-
const { timestamp } = entity;
|
|
174
|
-
try {
|
|
175
|
-
const { blockNumberAtDeployment, blockNumberFiveMinBeforeDeployment } = await findBlocksForTimestamp(blocksSubgraphUrl, timestamp, externalCalls);
|
|
176
|
-
// It could happen that the subgraph hasn't synced yet, so someone who just lost access still managed to make a deployment. The problem would be that when other catalysts perform
|
|
177
|
-
// the same check, the subgraph might have synced and the deployment is no longer valid. So, in order to prevent inconsistencies between catalysts, we will allow all deployments that
|
|
178
|
-
// have access now, or had access 5 minutes ago.
|
|
179
|
-
const hasPermissionOnBlock = async (blockNumber) => !!blockNumber &&
|
|
180
|
-
(await hasPermission(collectionsSubgraphUrl, collection, itemId, blockNumber, entity, externalCalls));
|
|
181
|
-
return ((await hasPermissionOnBlock(blockNumberAtDeployment)) ||
|
|
182
|
-
(await hasPermissionOnBlock(blockNumberFiveMinBeforeDeployment)));
|
|
183
|
-
}
|
|
184
|
-
catch (error) {
|
|
185
|
-
// this.LOGGER.error(
|
|
186
|
-
// `Error checking wearable access (${collection}, ${itemId}, ${accessParams.ethAddress}, ${timestamp}, ${blocksSubgraphUrl}).`,
|
|
187
|
-
// error
|
|
188
|
-
// )
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
43
|
/**
|
|
193
44
|
* Given the pointers (URNs), determine which layer should be used to check the access.
|
|
194
45
|
* Checks if the ethereum address has access to the collection.
|
|
195
46
|
* @public
|
|
196
47
|
*/
|
|
197
48
|
exports.wearables = {
|
|
198
|
-
validate: async ({ deployment, externalCalls }) => {
|
|
49
|
+
validate: async ({ deployment, externalCalls }, logs) => {
|
|
50
|
+
const hasPermission = async (subgraphUrl, collection, itemId, block, entity) => {
|
|
51
|
+
try {
|
|
52
|
+
const { content, metadata } = entity;
|
|
53
|
+
const permissions = await getCollectionItems(subgraphUrl, collection, itemId, block);
|
|
54
|
+
const ethAddressLowercase = entity.ethAddress.toLowerCase();
|
|
55
|
+
if (!!permissions.contentHash) {
|
|
56
|
+
const deployedByCommittee = permissions.committee.includes(ethAddressLowercase);
|
|
57
|
+
const calculateHashes = () => {
|
|
58
|
+
// Compare both by key and hash
|
|
59
|
+
const compare = (a, b) => {
|
|
60
|
+
if (a.hash > b.hash)
|
|
61
|
+
return 1;
|
|
62
|
+
else if (a.hash < b.hash)
|
|
63
|
+
return -1;
|
|
64
|
+
else
|
|
65
|
+
return a.key > b.key ? 1 : -1;
|
|
66
|
+
};
|
|
67
|
+
const contentAsJson = (content ?? []).map(({ file, hash }) => ({ key: file, hash })).sort(compare);
|
|
68
|
+
const buffer = Buffer.from(JSON.stringify({ content: contentAsJson, metadata }));
|
|
69
|
+
return Promise.all([dcl_catalyst_commons_1.Hashing.calculateBufferHash(buffer), dcl_catalyst_commons_1.Hashing.calculateIPFSHash(buffer)]);
|
|
70
|
+
};
|
|
71
|
+
return deployedByCommittee && (await calculateHashes()).includes(permissions.contentHash);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const addressHasAccess = (permissions.collectionCreator && permissions.collectionCreator === ethAddressLowercase) ||
|
|
75
|
+
(permissions.collectionManagers && permissions.collectionManagers.includes(ethAddressLowercase)) ||
|
|
76
|
+
(permissions.itemManagers && permissions.itemManagers.includes(ethAddressLowercase));
|
|
77
|
+
// Deployments to the content server are made after the collection is completed, so that the committee can then approve it.
|
|
78
|
+
// That's why isCompleted must be true, but isApproved must be false. After the committee approves the wearable, there can't be any more changes
|
|
79
|
+
const isCollectionValid = !permissions.isApproved && permissions.isCompleted;
|
|
80
|
+
return addressHasAccess && isCollectionValid;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
logs?.error(`Error checking permission for (${collection}-${itemId}) at block ${block}`);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const getCollectionItems = async (subgraphUrl, collection, itemId, block) => {
|
|
89
|
+
const query = `
|
|
90
|
+
query getCollectionRoles($collection: String!, $itemId: String!, $block: Int!) {
|
|
91
|
+
collections(where:{ id: $collection }, block: { number: $block }) {
|
|
92
|
+
creator
|
|
93
|
+
managers
|
|
94
|
+
isApproved
|
|
95
|
+
isCompleted
|
|
96
|
+
items(where:{ id: $itemId }) {
|
|
97
|
+
managers
|
|
98
|
+
contentHash
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
accounts(where:{ isCommitteeMember: true }, block: { number: $block }) {
|
|
103
|
+
id
|
|
104
|
+
}
|
|
105
|
+
}`;
|
|
106
|
+
const result = await externalCalls.queryGraph(subgraphUrl, query, {
|
|
107
|
+
collection,
|
|
108
|
+
itemId: `${collection}-${itemId}`,
|
|
109
|
+
block,
|
|
110
|
+
});
|
|
111
|
+
const collectionResult = result.collections[0];
|
|
112
|
+
const itemResult = collectionResult?.items[0];
|
|
113
|
+
return {
|
|
114
|
+
collectionCreator: collectionResult?.creator,
|
|
115
|
+
collectionManagers: collectionResult?.managers,
|
|
116
|
+
isApproved: collectionResult?.isApproved,
|
|
117
|
+
isCompleted: collectionResult?.isCompleted,
|
|
118
|
+
itemManagers: itemResult?.managers,
|
|
119
|
+
contentHash: itemResult?.contentHash,
|
|
120
|
+
committee: result.accounts.map(({ id }) => id.toLowerCase()),
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
const getWindowFromTimestamp = (timestamp) => {
|
|
124
|
+
const windowMin = timestamp - Math.floor(ACCESS_WINDOW_IN_SECONDS / 2);
|
|
125
|
+
const windowMax = timestamp + Math.ceil(ACCESS_WINDOW_IN_SECONDS / 2);
|
|
126
|
+
return {
|
|
127
|
+
max: windowMax,
|
|
128
|
+
min: windowMin,
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
const findBlocksForTimestamp = async (blocksSubgraphUrl, timestamp) => {
|
|
132
|
+
const query = `
|
|
133
|
+
query getBlockForTimestamp($timestamp: Int!, $timestampMin: Int!, $timestampMax: Int!, $timestamp5Min: Int!, $timestamp5MinMax: Int!, $timestamp5MinMin: Int!) {
|
|
134
|
+
before: blocks(where: { timestamp_lte: $timestamp, timestamp_gte: $timestampMin }, first: 1, orderBy: timestamp, orderDirection: desc) {
|
|
135
|
+
number
|
|
136
|
+
}
|
|
137
|
+
after: blocks(where: { timestamp_gte: $timestamp, timestamp_lte: $timestampMax }, first: 1, orderBy: timestamp, orderDirection: asc) {
|
|
138
|
+
number
|
|
139
|
+
}
|
|
140
|
+
fiveMinBefore: blocks(where: { timestamp_lte: $timestamp5Min, timestamp_gte: $timestamp5MinMin, }, first: 1, orderBy: timestamp, orderDirection: desc) {
|
|
141
|
+
number
|
|
142
|
+
}
|
|
143
|
+
fiveMinAfter: blocks(where: { timestamp_gte: $timestamp5Min, timestamp_lte: $timestamp5MinMax }, first: 1, orderBy: timestamp, orderDirection: asc) {
|
|
144
|
+
number
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
`;
|
|
148
|
+
try {
|
|
149
|
+
const timestampSec = Math.ceil(timestamp / 1000);
|
|
150
|
+
const timestamp5MinAgo = timestampSec - 60 * 5;
|
|
151
|
+
const window = getWindowFromTimestamp(timestampSec);
|
|
152
|
+
const window5MinAgo = getWindowFromTimestamp(timestamp5MinAgo);
|
|
153
|
+
const result = await externalCalls.queryGraph(blocksSubgraphUrl, query, {
|
|
154
|
+
timestamp: timestampSec,
|
|
155
|
+
timestampMax: window.max,
|
|
156
|
+
timestampMin: window.min,
|
|
157
|
+
timestamp5Min: timestamp5MinAgo,
|
|
158
|
+
timestamp5MinMax: window5MinAgo.max,
|
|
159
|
+
timestamp5MinMin: window5MinAgo.min,
|
|
160
|
+
});
|
|
161
|
+
// To get the deployment's block number, we check the one immediately after the entity's timestamp. Since it could not exist, we default to the one immediately before.
|
|
162
|
+
const blockNumberAtDeployment = result.after[0]?.number ?? result.before[0]?.number;
|
|
163
|
+
const blockNumberFiveMinBeforeDeployment = result.fiveMinAfter[0]?.number ?? result.fiveMinBefore[0]?.number;
|
|
164
|
+
if (blockNumberAtDeployment === undefined && blockNumberFiveMinBeforeDeployment === undefined) {
|
|
165
|
+
throw new Error(`Failed to find blocks for the specific timestamp`);
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
blockNumberAtDeployment: !!blockNumberAtDeployment ? parseInt(blockNumberAtDeployment) : undefined,
|
|
169
|
+
blockNumberFiveMinBeforeDeployment: !!blockNumberFiveMinBeforeDeployment
|
|
170
|
+
? parseInt(blockNumberFiveMinBeforeDeployment)
|
|
171
|
+
: undefined,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
const error = e?.message;
|
|
176
|
+
logs?.error(`Error fetching the block number for timestamp`, { timestamp, error });
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
const checkCollectionAccess = async (blocksSubgraphUrl, collectionsSubgraphUrl, collection, itemId, entity) => {
|
|
181
|
+
const { timestamp } = entity;
|
|
182
|
+
try {
|
|
183
|
+
const { blockNumberAtDeployment, blockNumberFiveMinBeforeDeployment } = await findBlocksForTimestamp(blocksSubgraphUrl, timestamp);
|
|
184
|
+
// It could happen that the subgraph hasn't synced yet, so someone who just lost access still managed to make a deployment. The problem would be that when other catalysts perform
|
|
185
|
+
// the same check, the subgraph might have synced and the deployment is no longer valid. So, in order to prevent inconsistencies between catalysts, we will allow all deployments that
|
|
186
|
+
// have access now, or had access 5 minutes ago.
|
|
187
|
+
const hasPermissionOnBlock = async (blockNumber) => !!blockNumber && (await hasPermission(collectionsSubgraphUrl, collection, itemId, blockNumber, entity));
|
|
188
|
+
return ((await hasPermissionOnBlock(blockNumberAtDeployment)) ||
|
|
189
|
+
(await hasPermissionOnBlock(blockNumberFiveMinBeforeDeployment)));
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
logs?.error(`Error checking wearable access (${collection}, ${itemId}, ${entity.ethAddress}, ${timestamp}, ${blocksSubgraphUrl}).`);
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
199
196
|
const { pointers } = deployment.entity;
|
|
200
197
|
const ethAddress = externalCalls.ownerAddress(deployment.auditInfo);
|
|
201
198
|
const resolvedPointers = [];
|
|
@@ -229,7 +226,10 @@ exports.wearables = {
|
|
|
229
226
|
const collectionsSubgraphUrl = isL1
|
|
230
227
|
? externalCalls.subgraphs.L1.collections
|
|
231
228
|
: externalCalls.subgraphs.L2.collections;
|
|
232
|
-
const hasAccess = await checkCollectionAccess(blocksSubgraphUrl, collectionsSubgraphUrl, collection, parsed.id, {
|
|
229
|
+
const hasAccess = await checkCollectionAccess(blocksSubgraphUrl, collectionsSubgraphUrl, collection, parsed.id, {
|
|
230
|
+
...deployment.entity,
|
|
231
|
+
ethAddress,
|
|
232
|
+
});
|
|
233
233
|
if (!hasAccess) {
|
|
234
234
|
if (isL2)
|
|
235
235
|
return (0, __1.validationFailed)(`The provided Eth Address does not have access to the following wearable: (${parsed.contractAddress}, ${parsed.id})`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wearables.js","sourceRoot":"","sources":["../../../src/validations/access-checker/wearables.ts"],"names":[],"mappings":";;;;;;AACA,oDAAqH;AACrH,+DAAyD;AACzD,4CAAmB;AACnB,
|
|
1
|
+
{"version":3,"file":"wearables.js","sourceRoot":"","sources":["../../../src/validations/access-checker/wearables.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/content-validator",
|
|
3
|
-
"version": "1.0.1-
|
|
3
|
+
"version": "1.0.1-20220128144241.commit-9e37746",
|
|
4
4
|
"description": "Catalyst content validations",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -36,12 +36,13 @@
|
|
|
36
36
|
"@dcl/schemas": "^3.1.1",
|
|
37
37
|
"@dcl/urn-resolver": "^1.3.0",
|
|
38
38
|
"@ethersproject/address": "^5.5.0",
|
|
39
|
-
"
|
|
39
|
+
"@well-known-components/interfaces": "1.1.1",
|
|
40
|
+
"dcl-catalyst-commons": "7.2.2",
|
|
40
41
|
"ms": "^2.1.3",
|
|
41
42
|
"sharp": "^0.29.3"
|
|
42
43
|
},
|
|
43
44
|
"files": [
|
|
44
45
|
"dist"
|
|
45
46
|
],
|
|
46
|
-
"commit": "
|
|
47
|
+
"commit": "9e37746ed16e2839e8f714a2d5b8291afdc36d8c"
|
|
47
48
|
}
|