@bedrock/validation 6.0.1 → 7.1.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/.github/workflows/main.yml +3 -3
- package/CHANGELOG.md +12 -0
- package/README.md +7 -17
- package/lib/config.js +2 -2
- package/lib/helpers.js +40 -0
- package/lib/index.js +2 -2
- package/package.json +4 -3
- package/schemas/comment.js +3 -2
- package/schemas/credential.js +3 -2
- package/schemas/description.js +3 -2
- package/schemas/email.js +3 -2
- package/schemas/helpers/idOrObjectWithId.js +26 -0
- package/schemas/identifier.js +3 -2
- package/schemas/jsonPatch.js +3 -2
- package/schemas/jsonldContext.js +3 -2
- package/schemas/label.js +3 -2
- package/schemas/linkedDataSignature.js +3 -2
- package/schemas/nonce.js +3 -2
- package/schemas/personName.js +3 -2
- package/schemas/privateKeyPem.js +3 -2
- package/schemas/proof.js +21 -0
- package/schemas/publicKeyPem.js +3 -2
- package/schemas/sequencedPatch.js +3 -2
- package/schemas/slug.js +3 -2
- package/schemas/title.js +3 -2
- package/schemas/url.js +3 -2
- package/schemas/verifiableCredential.js +67 -0
- package/schemas/verifiablePresentation.js +58 -0
- package/schemas/w3cDateTime.js +3 -2
- package/test/mocha/001-schemas.js +30 -17
- package/test/mocha/mock.data.js +30 -0
- package/test/package.json +2 -2
- package/test/test.config.js +2 -2
|
@@ -8,7 +8,7 @@ jobs:
|
|
|
8
8
|
timeout-minutes: 10
|
|
9
9
|
strategy:
|
|
10
10
|
matrix:
|
|
11
|
-
node-version: [
|
|
11
|
+
node-version: [18.x]
|
|
12
12
|
steps:
|
|
13
13
|
- uses: actions/checkout@v2
|
|
14
14
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
@@ -24,7 +24,7 @@ jobs:
|
|
|
24
24
|
timeout-minutes: 10
|
|
25
25
|
strategy:
|
|
26
26
|
matrix:
|
|
27
|
-
node-version: [14.x]
|
|
27
|
+
node-version: [14.x, 16.x, 18.x]
|
|
28
28
|
steps:
|
|
29
29
|
- uses: actions/checkout@v2
|
|
30
30
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
@@ -45,7 +45,7 @@ jobs:
|
|
|
45
45
|
timeout-minutes: 10
|
|
46
46
|
strategy:
|
|
47
47
|
matrix:
|
|
48
|
-
node-version: [
|
|
48
|
+
node-version: [18.x]
|
|
49
49
|
steps:
|
|
50
50
|
- uses: actions/checkout@v2
|
|
51
51
|
- name: Use Node.js ${{ matrix.node-version }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# bedrock-validation ChangeLog
|
|
2
2
|
|
|
3
|
+
## 7.1.0 - 2022-10-16
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Added a validator for `VerifiablePresentation`
|
|
7
|
+
- Added a validator for `VerifiableCredential`.
|
|
8
|
+
|
|
9
|
+
## 7.0.0 - 2022-04-28
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- **BREAKING**: Update peer deps:
|
|
13
|
+
- `@bedrock/core@6`.
|
|
14
|
+
|
|
3
15
|
## 6.0.1 - 2022-04-01
|
|
4
16
|
|
|
5
17
|
### Fixed
|
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@ npm install @bedrock/validation
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
import * as bedrock from '@bedrock/core';
|
|
21
|
-
import {
|
|
21
|
+
import {postBarValidator, postBarQueryValidator} from '../schemas/my-schemas.js';
|
|
22
|
+
import {createValidateMiddleware as validate} from '@bedrock/validation';
|
|
22
23
|
|
|
23
24
|
// load schemas from '/foo'
|
|
24
25
|
bedrock.config.validation.schema.paths.push('/foo');
|
|
@@ -28,7 +29,7 @@ bedrock.events.on('bedrock-express.configure.routes', function(app) {
|
|
|
28
29
|
app.post('/bar',
|
|
29
30
|
// validate the query using the 'postBarQueryValidator'
|
|
30
31
|
// validate the response body using the 'postBarValidator'
|
|
31
|
-
validate({query:
|
|
32
|
+
validate({query: postBarQueryValidator, body: postBarValidator}),
|
|
32
33
|
function(req, res) {
|
|
33
34
|
// do something
|
|
34
35
|
});
|
|
@@ -50,23 +51,12 @@ For more documentation on configuration, see [config.js](./lib/config.js).
|
|
|
50
51
|
|
|
51
52
|
## API
|
|
52
53
|
|
|
53
|
-
###
|
|
54
|
+
### createValidateMiddleware({query: schema, body: schema})
|
|
54
55
|
|
|
55
|
-
This method may be called with either
|
|
56
|
+
This method may be called with either `query` or `body` defined.
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* The method returns express middleware that will be used to validate a request
|
|
60
|
-
using the schema associated with the given name.
|
|
61
|
-
* If a string is provided for the first parameter, then it will be used as the
|
|
62
|
-
schema name for validating the request body.
|
|
63
|
-
* If an object is provided for the first parameter, then the object can contain
|
|
64
|
-
`body` and `query` schema names as properties of the object.
|
|
65
|
-
|
|
66
|
-
If two parameters are given:
|
|
67
|
-
|
|
68
|
-
* The first parameter must be a string and the second parameter must be the
|
|
69
|
-
data to validate. The return value will contain the result of the validation.
|
|
58
|
+
The method returns express middleware that will be used to validate a request
|
|
59
|
+
using the schema associated with either `query` or `body`.
|
|
70
60
|
|
|
71
61
|
### getSchema(name)
|
|
72
62
|
|
package/lib/config.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import {config} from '@bedrock/core';
|
|
5
|
-
import {fileURLToPath} from 'url';
|
|
6
|
-
import path from 'path';
|
|
5
|
+
import {fileURLToPath} from 'node:url';
|
|
6
|
+
import path from 'node:path';
|
|
7
7
|
|
|
8
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
|
package/lib/helpers.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Merges the contents of one or more objects into the first object.
|
|
7
|
+
*
|
|
8
|
+
* Arguments:
|
|
9
|
+
* `deep` (optional), true to do a deep-merge
|
|
10
|
+
* `target` the target object to merge properties into
|
|
11
|
+
* `objects` N objects to merge into the target.
|
|
12
|
+
*
|
|
13
|
+
* @returns {object} - The extended object.
|
|
14
|
+
*/
|
|
15
|
+
export function extend() {
|
|
16
|
+
let deep = false;
|
|
17
|
+
let i = 0;
|
|
18
|
+
if(arguments.length > 0 && typeof arguments[0] === 'boolean') {
|
|
19
|
+
deep = arguments[0];
|
|
20
|
+
++i;
|
|
21
|
+
}
|
|
22
|
+
const target = arguments[i] || {};
|
|
23
|
+
i++;
|
|
24
|
+
for(; i < arguments.length; ++i) {
|
|
25
|
+
const obj = arguments[i] || {};
|
|
26
|
+
Object.keys(obj).forEach(function(name) {
|
|
27
|
+
const value = obj[name];
|
|
28
|
+
if(deep && _isObject(value) && !Array.isArray(value)) {
|
|
29
|
+
target[name] = extend(true, target[name], value);
|
|
30
|
+
} else {
|
|
31
|
+
target[name] = value;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function _isObject(x) {
|
|
39
|
+
return x && typeof x === 'object';
|
|
40
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
import * as bedrock from '@bedrock/core';
|
|
5
5
|
import Ajv from 'ajv';
|
|
6
6
|
import {Cache} from './Cache.js';
|
|
7
|
-
import {promises as fs} from 'fs';
|
|
7
|
+
import {promises as fs} from 'node:fs';
|
|
8
8
|
import {logger} from './logger.js';
|
|
9
|
-
import PATH from 'path';
|
|
9
|
+
import PATH from 'node:path';
|
|
10
10
|
|
|
11
11
|
const ajv = new Ajv({cache: new Cache(), serialize: false, verbose: true});
|
|
12
12
|
const {util: {BedrockError}} = bedrock;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bedrock/validation",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Bedrock validation",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -24,10 +24,11 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/digitalbazaar/bedrock-validation",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"ajv": "^6.12.0"
|
|
27
|
+
"ajv": "^6.12.0",
|
|
28
|
+
"klona": "^2.0.5"
|
|
28
29
|
},
|
|
29
30
|
"peerDependencies": {
|
|
30
|
-
"@bedrock/core": "^
|
|
31
|
+
"@bedrock/core": "^6.0.0"
|
|
31
32
|
},
|
|
32
33
|
"directories": {
|
|
33
34
|
"lib": "./lib"
|
package/schemas/comment.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Comment',
|
|
@@ -18,7 +19,7 @@ const schema = {
|
|
|
18
19
|
|
|
19
20
|
export default function(extend) {
|
|
20
21
|
if(extend) {
|
|
21
|
-
return
|
|
22
|
+
return _extend(true, klona(schema), extend);
|
|
22
23
|
}
|
|
23
24
|
return schema;
|
|
24
25
|
}
|
package/schemas/credential.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
5
|
import identifier from './identifier.js';
|
|
6
6
|
import jsonldContext from './jsonldContext.js';
|
|
7
|
+
import {klona} from 'klona';
|
|
7
8
|
import w3cDateTime from './w3cDateTime.js';
|
|
8
9
|
|
|
9
10
|
// TODO: Improve this schema
|
|
@@ -31,7 +32,7 @@ const schema = {
|
|
|
31
32
|
|
|
32
33
|
export default function(extend) {
|
|
33
34
|
if(extend) {
|
|
34
|
-
return
|
|
35
|
+
return _extend(true, klona(schema), extend);
|
|
35
36
|
}
|
|
36
37
|
return schema;
|
|
37
38
|
}
|
package/schemas/description.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Description',
|
|
@@ -18,7 +19,7 @@ const schema = {
|
|
|
18
19
|
|
|
19
20
|
export default function(extend) {
|
|
20
21
|
if(extend) {
|
|
21
|
-
return
|
|
22
|
+
return _extend(true, klona(schema), extend);
|
|
22
23
|
}
|
|
23
24
|
return schema;
|
|
24
25
|
}
|
package/schemas/email.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
// RFC 1034 - All labels have a max length of 63 octets.
|
|
7
8
|
// https://tools.ietf.org/html/rfc1034#section-3.1
|
|
@@ -28,7 +29,7 @@ export default function(extend, options) {
|
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
if(extend) {
|
|
31
|
-
return
|
|
32
|
+
return _extend(true, klona(schema), extend);
|
|
32
33
|
}
|
|
33
34
|
return schema;
|
|
34
35
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import {extend as _extend} from '../../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
6
|
+
import identifier from '../identifier.js';
|
|
7
|
+
|
|
8
|
+
const schema = {
|
|
9
|
+
title: 'identifier or an object with an id',
|
|
10
|
+
anyOf: [
|
|
11
|
+
identifier(),
|
|
12
|
+
{
|
|
13
|
+
type: 'object',
|
|
14
|
+
additionalProperties: true,
|
|
15
|
+
properties: {id: identifier()},
|
|
16
|
+
required: ['id']
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default function(extend) {
|
|
22
|
+
if(extend) {
|
|
23
|
+
return _extend(true, klona(schema), extend);
|
|
24
|
+
}
|
|
25
|
+
return schema;
|
|
26
|
+
}
|
package/schemas/identifier.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'ID',
|
|
@@ -16,7 +17,7 @@ const schema = {
|
|
|
16
17
|
|
|
17
18
|
export default function(extend) {
|
|
18
19
|
if(extend) {
|
|
19
|
-
return
|
|
20
|
+
return _extend(true, klona(schema), extend);
|
|
20
21
|
}
|
|
21
22
|
return schema;
|
|
22
23
|
}
|
package/schemas/jsonPatch.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'JSON Patch',
|
|
@@ -32,7 +33,7 @@ const schema = {
|
|
|
32
33
|
|
|
33
34
|
export default function(extend) {
|
|
34
35
|
if(extend) {
|
|
35
|
-
return
|
|
36
|
+
return _extend(true, klona(schema), extend);
|
|
36
37
|
}
|
|
37
38
|
return schema;
|
|
38
39
|
}
|
package/schemas/jsonldContext.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
export default function(context, extend) {
|
|
7
8
|
const schema = {
|
|
@@ -48,7 +49,7 @@ export default function(context, extend) {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
if(extend) {
|
|
51
|
-
return
|
|
52
|
+
return _extend(true, klona(schema), extend);
|
|
52
53
|
}
|
|
53
54
|
return schema;
|
|
54
55
|
}
|
package/schemas/label.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Label',
|
|
@@ -19,7 +20,7 @@ const schema = {
|
|
|
19
20
|
|
|
20
21
|
export default function(extend) {
|
|
21
22
|
if(extend) {
|
|
22
|
-
return
|
|
23
|
+
return _extend(true, klona(schema), extend);
|
|
23
24
|
}
|
|
24
25
|
return schema;
|
|
25
26
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
5
|
import identifier from './identifier.js';
|
|
6
|
+
import {klona} from 'klona';
|
|
6
7
|
import w3cDateTime from './w3cDateTime.js';
|
|
7
8
|
|
|
8
9
|
const signature = {
|
|
@@ -40,7 +41,7 @@ const schema = {
|
|
|
40
41
|
|
|
41
42
|
export default function(extend) {
|
|
42
43
|
if(extend) {
|
|
43
|
-
return
|
|
44
|
+
return _extend(true, klona(schema), extend);
|
|
44
45
|
}
|
|
45
46
|
return schema;
|
|
46
47
|
}
|
package/schemas/nonce.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Nonce',
|
|
@@ -19,7 +20,7 @@ const schema = {
|
|
|
19
20
|
|
|
20
21
|
export default function(extend) {
|
|
21
22
|
if(extend) {
|
|
22
|
-
return
|
|
23
|
+
return _extend(true, klona(schema), extend);
|
|
23
24
|
}
|
|
24
25
|
return schema;
|
|
25
26
|
}
|
package/schemas/personName.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Person Name',
|
|
@@ -19,7 +20,7 @@ const schema = {
|
|
|
19
20
|
|
|
20
21
|
export default function(extend) {
|
|
21
22
|
if(extend) {
|
|
22
|
-
return
|
|
23
|
+
return _extend(true, klona(schema), extend);
|
|
23
24
|
}
|
|
24
25
|
return schema;
|
|
25
26
|
}
|
package/schemas/privateKeyPem.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Private Key PEM',
|
|
@@ -17,7 +18,7 @@ const schema = {
|
|
|
17
18
|
|
|
18
19
|
export default function(extend) {
|
|
19
20
|
if(extend) {
|
|
20
|
-
return
|
|
21
|
+
return _extend(true, klona(schema), extend);
|
|
21
22
|
}
|
|
22
23
|
return schema;
|
|
23
24
|
}
|
package/schemas/proof.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
6
|
+
|
|
7
|
+
// schema for a proof on a VerifiableCredential or Presentation
|
|
8
|
+
const schema = {
|
|
9
|
+
title: 'Proof',
|
|
10
|
+
anyOf: [
|
|
11
|
+
{type: 'object'},
|
|
12
|
+
{type: 'array', minItems: 1, items: {type: 'object'}}
|
|
13
|
+
]
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default function(extend) {
|
|
17
|
+
if(extend) {
|
|
18
|
+
return _extend(true, klona(schema), extend);
|
|
19
|
+
}
|
|
20
|
+
return schema;
|
|
21
|
+
}
|
package/schemas/publicKeyPem.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Public Key PEM',
|
|
@@ -17,7 +18,7 @@ const schema = {
|
|
|
17
18
|
|
|
18
19
|
export default function(extend) {
|
|
19
20
|
if(extend) {
|
|
20
|
-
return
|
|
21
|
+
return _extend(true, klona(schema), extend);
|
|
21
22
|
}
|
|
22
23
|
return schema;
|
|
23
24
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
5
|
import jsonPatch from './jsonPatch.js';
|
|
6
|
+
import {klona} from 'klona';
|
|
6
7
|
|
|
7
8
|
const schema = {
|
|
8
9
|
required: ['patch', 'sequence', 'target'],
|
|
@@ -25,7 +26,7 @@ const schema = {
|
|
|
25
26
|
|
|
26
27
|
export default function(extend) {
|
|
27
28
|
if(extend) {
|
|
28
|
-
return
|
|
29
|
+
return _extend(true, klona(schema), extend);
|
|
29
30
|
}
|
|
30
31
|
return schema;
|
|
31
32
|
}
|
package/schemas/slug.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Slug',
|
|
@@ -21,7 +22,7 @@ const schema = {
|
|
|
21
22
|
|
|
22
23
|
export default function(extend) {
|
|
23
24
|
if(extend) {
|
|
24
|
-
return
|
|
25
|
+
return _extend(true, klona(schema), extend);
|
|
25
26
|
}
|
|
26
27
|
return schema;
|
|
27
28
|
}
|
package/schemas/title.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'Title',
|
|
@@ -19,7 +20,7 @@ const schema = {
|
|
|
19
20
|
|
|
20
21
|
export default function(extend) {
|
|
21
22
|
if(extend) {
|
|
22
|
-
return
|
|
23
|
+
return _extend(true, klona(schema), extend);
|
|
23
24
|
}
|
|
24
25
|
return schema;
|
|
25
26
|
}
|
package/schemas/url.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'URL',
|
|
@@ -16,7 +17,7 @@ const schema = {
|
|
|
16
17
|
|
|
17
18
|
export default function(extend) {
|
|
18
19
|
if(extend) {
|
|
19
|
-
return
|
|
20
|
+
return _extend(true, klona(schema), extend);
|
|
20
21
|
}
|
|
21
22
|
return schema;
|
|
22
23
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import proof from './proof.js';
|
|
6
|
+
import idOrObjectWithId from './helpers/idOrObjectWithId.js';
|
|
7
|
+
import {klona} from 'klona';
|
|
8
|
+
import w3cDateTime from './w3cDateTime.js';
|
|
9
|
+
|
|
10
|
+
// https://www.w3.org/TR/vc-data-model/
|
|
11
|
+
// Based off of the VC Data Model 1.1
|
|
12
|
+
const schema = {
|
|
13
|
+
type: 'object',
|
|
14
|
+
title: 'Verifiable Credential',
|
|
15
|
+
additionalProperties: true,
|
|
16
|
+
properties: {
|
|
17
|
+
'@context': {
|
|
18
|
+
type: 'array',
|
|
19
|
+
minItems: 1,
|
|
20
|
+
// the first context must be the VC context
|
|
21
|
+
items: [{
|
|
22
|
+
type: 'string',
|
|
23
|
+
const: 'https://www.w3.org/2018/credentials/v1'
|
|
24
|
+
}],
|
|
25
|
+
// additional contexts maybe strings or objects
|
|
26
|
+
additionalItems: {
|
|
27
|
+
anyOf: [{type: 'string'}, {type: 'object'}]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
credentialSubject: {
|
|
31
|
+
anyOf: [
|
|
32
|
+
{type: 'object'},
|
|
33
|
+
{type: 'array', minItems: 1, items: {type: 'object'}}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
id: idOrObjectWithId(),
|
|
37
|
+
issuer: idOrObjectWithId(),
|
|
38
|
+
issuanceDate: w3cDateTime(),
|
|
39
|
+
proof: proof(),
|
|
40
|
+
type: {
|
|
41
|
+
type: 'array',
|
|
42
|
+
minItems: 1,
|
|
43
|
+
// this first type must be VerifiableCredential
|
|
44
|
+
items: [
|
|
45
|
+
{type: 'string', const: 'VerifiableCredential'},
|
|
46
|
+
],
|
|
47
|
+
// additional types must be strings
|
|
48
|
+
additionalItems: {
|
|
49
|
+
type: 'string'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
required: [
|
|
54
|
+
'@context',
|
|
55
|
+
'credentialSubject',
|
|
56
|
+
'issuer',
|
|
57
|
+
'issuanceDate',
|
|
58
|
+
'type'
|
|
59
|
+
]
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default function(extend) {
|
|
63
|
+
if(extend) {
|
|
64
|
+
return _extend(true, klona(schema), extend);
|
|
65
|
+
}
|
|
66
|
+
return schema;
|
|
67
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import verifiableCredential from './verifiableCredential.js';
|
|
5
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
6
|
+
import proof from './proof.js';
|
|
7
|
+
import idOrObjectWithId from './helpers/idOrObjectWithId.js';
|
|
8
|
+
import {klona} from 'klona';
|
|
9
|
+
|
|
10
|
+
const schema = {
|
|
11
|
+
title: 'Verifiable Presentation',
|
|
12
|
+
type: 'object',
|
|
13
|
+
additionalProperties: true,
|
|
14
|
+
properties: {
|
|
15
|
+
'@context': {
|
|
16
|
+
type: 'array',
|
|
17
|
+
minItems: 1,
|
|
18
|
+
// the first context must be the VC context
|
|
19
|
+
items: [{
|
|
20
|
+
type: 'string',
|
|
21
|
+
const: 'https://www.w3.org/2018/credentials/v1'
|
|
22
|
+
}],
|
|
23
|
+
// additional contexts maybe strings or objects
|
|
24
|
+
additionalItems: {
|
|
25
|
+
anyOf: [{type: 'string'}, {type: 'object'}]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
id: idOrObjectWithId(),
|
|
29
|
+
type: {
|
|
30
|
+
type: 'array',
|
|
31
|
+
minItems: 1,
|
|
32
|
+
// this first type must be VerifiablePresentation
|
|
33
|
+
items: [
|
|
34
|
+
{type: 'string', const: 'VerifiablePresentation'},
|
|
35
|
+
],
|
|
36
|
+
// additional types must be strings
|
|
37
|
+
additionalItems: {
|
|
38
|
+
type: 'string'
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
verifiableCredential: {
|
|
42
|
+
anyOf: [
|
|
43
|
+
verifiableCredential(),
|
|
44
|
+
{type: 'array', minItems: 1, items: verifiableCredential()}
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
holder: idOrObjectWithId(),
|
|
48
|
+
proof: proof()
|
|
49
|
+
},
|
|
50
|
+
required: ['@context', 'type']
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default function(extend) {
|
|
54
|
+
if(extend) {
|
|
55
|
+
return _extend(true, klona(schema), extend);
|
|
56
|
+
}
|
|
57
|
+
return schema;
|
|
58
|
+
}
|
package/schemas/w3cDateTime.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import {extend as _extend} from '../lib/helpers.js';
|
|
5
|
+
import {klona} from 'klona';
|
|
5
6
|
|
|
6
7
|
const schema = {
|
|
7
8
|
title: 'W3C Date/Time',
|
|
@@ -18,7 +19,7 @@ const schema = {
|
|
|
18
19
|
|
|
19
20
|
export default function(extend) {
|
|
20
21
|
if(extend) {
|
|
21
|
-
return
|
|
22
|
+
return _extend(true, klona(schema), extend);
|
|
22
23
|
}
|
|
23
24
|
return schema;
|
|
24
25
|
}
|
|
@@ -986,36 +986,49 @@ describe('bedrock-validation', function() {
|
|
|
986
986
|
});
|
|
987
987
|
});
|
|
988
988
|
|
|
989
|
-
describe('
|
|
990
|
-
const schema = validation.getSchema({name: '
|
|
989
|
+
describe('verifiableCredential', function() {
|
|
990
|
+
const schema = validation.getSchema({name: 'verifiableCredential'});
|
|
991
991
|
it('should be an Object', function() {
|
|
992
992
|
schema.should.be.an.instanceof(Object);
|
|
993
993
|
});
|
|
994
994
|
it('should validate a credential', function() {
|
|
995
|
-
const credential = {
|
|
996
|
-
issuer: 'test',
|
|
997
|
-
issued: '1997-07-16T19:20:30',
|
|
998
|
-
claim: {
|
|
999
|
-
id: '1234'
|
|
1000
|
-
}
|
|
1001
|
-
};
|
|
995
|
+
const credential = {...mock.credentials.valid};
|
|
1002
996
|
const result = validateInstance({instance: credential, schema});
|
|
1003
997
|
result.valid.should.be.true;
|
|
1004
998
|
});
|
|
1005
999
|
it('should validate a credential with an extend', function() {
|
|
1006
|
-
const credential = {
|
|
1007
|
-
issuer: 'test',
|
|
1008
|
-
issued: '2016-01-01T01:00:00Z',
|
|
1009
|
-
claim: {
|
|
1010
|
-
id: '1234'
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1000
|
+
const credential = {...mock.credentials.valid};
|
|
1013
1001
|
const extend = {name: 'test'};
|
|
1014
|
-
const schema = validation.schemas.
|
|
1002
|
+
const schema = validation.schemas.verifiableCredential(extend);
|
|
1015
1003
|
const result = validateInstance({instance: credential, schema});
|
|
1016
1004
|
schema.name.should.equal('test');
|
|
1017
1005
|
result.valid.should.be.true;
|
|
1018
1006
|
});
|
|
1007
|
+
it('should not validate a credential with an invalid @context', function() {
|
|
1008
|
+
const credential = {...mock.credentials.invalid.invalidContext};
|
|
1009
|
+
const result = validateInstance({instance: credential, schema});
|
|
1010
|
+
result.valid.should.be.false;
|
|
1011
|
+
});
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
describe('verifiablePresentation', function() {
|
|
1015
|
+
const schema = validation.getSchema({name: 'verifiablePresentation'});
|
|
1016
|
+
it('should be an Object', function() {
|
|
1017
|
+
schema.should.be.an.instanceof(Object);
|
|
1018
|
+
});
|
|
1019
|
+
it('should validate a presentation', function() {
|
|
1020
|
+
const presentation = {...mock.presentations.valid};
|
|
1021
|
+
const result = validateInstance({instance: presentation, schema});
|
|
1022
|
+
result.valid.should.be.true;
|
|
1023
|
+
});
|
|
1024
|
+
it('should validate a presentation with an extend', function() {
|
|
1025
|
+
const presentation = {...mock.presentations.valid};
|
|
1026
|
+
const extend = {name: 'test'};
|
|
1027
|
+
const schema = validation.schemas.verifiablePresentation(extend);
|
|
1028
|
+
const result = validateInstance({instance: presentation, schema});
|
|
1029
|
+
schema.name.should.equal('test');
|
|
1030
|
+
result.valid.should.be.true;
|
|
1031
|
+
});
|
|
1019
1032
|
});
|
|
1020
1033
|
|
|
1021
1034
|
describe('jsonPatch', function() {
|
package/test/mocha/mock.data.js
CHANGED
|
@@ -43,3 +43,33 @@ keys.alpha = {
|
|
|
43
43
|
'42EADs/ajTEckTxULdirbEk2rINRwQC5kWMde3fcwAnn6xt3wvOyuwg=\n' +
|
|
44
44
|
'-----END RSA PRIVATE KEY-----'
|
|
45
45
|
};
|
|
46
|
+
|
|
47
|
+
const credentialsContext = 'https://www.w3.org/2018/credentials/v1';
|
|
48
|
+
const credentials = mock.credentials = {};
|
|
49
|
+
|
|
50
|
+
credentials.valid = {
|
|
51
|
+
'@context': [credentialsContext, 'https://www.schema.org'],
|
|
52
|
+
id: 'urn:uuid:test-vc',
|
|
53
|
+
issuer: 'test',
|
|
54
|
+
issuanceDate: '1997-07-16T19:20:30',
|
|
55
|
+
type: ['VerifiableCredential', 'TestCredential'],
|
|
56
|
+
credentialSubject: {
|
|
57
|
+
id: '1234'
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
credentials.invalid = {
|
|
62
|
+
invalidContext: {
|
|
63
|
+
...credentials.valid,
|
|
64
|
+
'@context': ['https://www.schema.org']
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const presentations = mock.presentations = {};
|
|
69
|
+
|
|
70
|
+
presentations.valid = {
|
|
71
|
+
'@context': [credentialsContext],
|
|
72
|
+
type: ['VerifiablePresentation'],
|
|
73
|
+
id: 'urn:uuid:test-vc',
|
|
74
|
+
verifiableCredential: [{...credentials.valid}]
|
|
75
|
+
};
|
package/test/package.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"coverage-report": "c8 report"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@bedrock/core": "^
|
|
14
|
-
"@bedrock/test": "^
|
|
13
|
+
"@bedrock/core": "^6.0.0",
|
|
14
|
+
"@bedrock/test": "^8.0.0",
|
|
15
15
|
"@bedrock/validation": "file:..",
|
|
16
16
|
"c8": "^7.11.0",
|
|
17
17
|
"cross-env": "^7.0.3"
|
package/test/test.config.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Copyright (c) 2017-2022 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import {config} from '@bedrock/core';
|
|
5
|
-
import {fileURLToPath} from 'url';
|
|
6
|
-
import path from 'path';
|
|
5
|
+
import {fileURLToPath} from 'node:url';
|
|
6
|
+
import path from 'node:path';
|
|
7
7
|
|
|
8
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
|