@json-editor/json-editor 2.15.2 → 2.16.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.
@@ -24,7 +24,7 @@
24
24
  Try yourself, submit the form and look in the network tab of the developer tool.
25
25
  </p>
26
26
  <div class="form-group"></div>
27
- <form action="/docs/form-submission.html" method="get">
27
+ <form method="get">
28
28
  <input id="input" type="hidden" name="json">
29
29
  <div id='editor-container'></div>
30
30
  <input id="submit" class="btn btn-primary" width="100" type="submit">
package/docs/index.html CHANGED
@@ -10,9 +10,27 @@
10
10
  <script src="./scripts/ajv-validator.js"></script>
11
11
  <link rel='stylesheet' id='theme-link'>
12
12
  <link rel='stylesheet' id='iconlib-link'>
13
+ <style>
14
+ .maintenance-notice {
15
+ background-color: #fff3cd;
16
+ border: 1px solid #ffeaa7;
17
+ border-radius: 4px;
18
+ padding: 12px 16px;
19
+ margin-bottom: 20px;
20
+ color: #856404;
21
+ }
22
+ .maintenance-notice a {
23
+ color: #533102;
24
+ text-decoration: underline;
25
+ }
26
+ </style>
13
27
  </head>
14
28
  <body>
15
29
  <div class="container grid-xl" style="padding-top: 15px; padding-bottom: 30px;">
30
+ <div class="maintenance-notice">
31
+ <strong>Maintenance Mode:</strong> This library is in maintenance mode.
32
+ For active development, consider <a href="https://github.com/germanbisurgi/jedison" target="_blank">Jedison</a>.
33
+ </div>
16
34
  <div class="row columns md:flex">
17
35
  <div class='col-7 col-md-7 w-7/12'>
18
36
  <h1>Editor</h1>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@json-editor/json-editor",
3
3
  "title": "JSONEditor",
4
4
  "description": "JSON Schema based editor",
5
- "version": "2.15.2",
5
+ "version": "2.16.0",
6
6
  "main": "dist/jsoneditor.js",
7
7
  "author": {
8
8
  "name": "Jeremy Dorn",
package/src/editor.js CHANGED
@@ -176,7 +176,7 @@ export class AbstractEditor {
176
176
  const editor = this.jsoneditor.getEditor(path)
177
177
  const value = editor ? editor.getValue() : undefined
178
178
 
179
- if (!editor || !editor.dependenciesFulfilled || !value) {
179
+ if (!editor || !editor.dependenciesFulfilled || value === undefined || value === null) {
180
180
  this.dependenciesFulfilled = false
181
181
  } else if (Array.isArray(choices)) {
182
182
  this.dependenciesFulfilled = choices.some(choice => {
@@ -521,6 +521,20 @@ export class AbstractEditor {
521
521
  }
522
522
  }
523
523
 
524
+ purify (val) {
525
+ if (typeof val !== 'string') {
526
+ return val
527
+ }
528
+
529
+ if (window.DOMPurify) {
530
+ val = window.DOMPurify.sanitize(val)
531
+ } else {
532
+ val = this.cleanText(val)
533
+ }
534
+
535
+ return val
536
+ }
537
+
524
538
  getHeaderText (titleOnly) {
525
539
  if (this.header_text) return this.header_text
526
540
  else if (titleOnly) return this.translateProperty(this.schema.title)
@@ -84,6 +84,7 @@ export class HiddenEditor extends AbstractEditor {
84
84
  * This is overridden in derivative editors
85
85
  */
86
86
  sanitize (value) {
87
+ value = this.purify(value)
87
88
  return value
88
89
  }
89
90
 
@@ -178,6 +178,7 @@ export class MultiSelectEditor extends AbstractEditor {
178
178
  }
179
179
 
180
180
  sanitize (value) {
181
+ value = this.purify(value)
181
182
  if (this.schema.items.type === 'boolean') return !!value
182
183
  else if (this.schema.items.type === 'number') return 1 * value || 0
183
184
  else if (this.schema.items.type === 'integer') return Math.floor(value * 1 || 0)
@@ -18,6 +18,7 @@ export class StringEditor extends AbstractEditor {
18
18
  }
19
19
 
20
20
  setValue (value, initial, fromTemplate) {
21
+ value = this.purify(value)
21
22
  value = this.applyConstFilter(value)
22
23
 
23
24
  if (this.template && !fromTemplate) return
@@ -362,6 +363,7 @@ export class StringEditor extends AbstractEditor {
362
363
  * This is overridden in derivative editors
363
364
  */
364
365
  sanitize (value) {
366
+ value = this.purify(value)
365
367
  return value
366
368
  }
367
369
 
@@ -26,6 +26,7 @@ export class UuidEditor extends StringEditor {
26
26
  }
27
27
 
28
28
  sanitize (value) {
29
+ value = this.purify(value)
29
30
  if (!this.testUuid(value)) value = this.uuid
30
31
  return value
31
32
  }
@@ -0,0 +1,26 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('purify')
4
+
5
+ Scenario('Should @purify @optional XSS from direct input', async ({ I }) => {
6
+ I.amOnPage('purify.html')
7
+ I.waitForElement('[name="root[string]"]')
8
+ I.fillField('[name="root[string]"]', 'bla</script><script>alert(1)</script>')
9
+ I.pressKey('Tab')
10
+ I.wait(1)
11
+ I.click('.get-value')
12
+ I.wait(1)
13
+ I.waitForValue('#value', '{"string":"bla"}')
14
+ })
15
+
16
+ Scenario('Should @purify @optional XSS from setValue() via textarea', async ({ I }) => {
17
+ I.amOnPage('purify.html')
18
+ I.waitForElement('#value')
19
+ I.fillField('#value', 'bla</script><script>alert(1)</script>')
20
+ I.pressKey('Tab')
21
+ I.click('.set-value')
22
+ I.wait(2)
23
+ I.click('.get-value')
24
+ I.wait(1)
25
+ I.waitForValue('#value', '{"string":"bla"}')
26
+ })
@@ -0,0 +1,15 @@
1
+ /* global Feature Scenario */
2
+
3
+ Feature('issues')
4
+
5
+ Scenario('GitHub issue 1559 should remain fixed @issue-1559', async ({ I }) => {
6
+ I.amOnPage('issues/issue-gh-1559.html')
7
+ I.waitForElement('.je-ready')
8
+ I.dontSeeElement('[data-schemapath="root.dependent_on_false"]')
9
+ I.click('[data-schemapath="root.dependent_on_true"] input')
10
+ I.waitForElement('[data-schemapath="root.dependent_on_false"]', 2)
11
+ I.seeElement('[data-schemapath="root.dependent_on_false"]')
12
+ I.click('[data-schemapath="root.dependent_on_true"] input')
13
+ I.waitForInvisible('[data-schemapath="root.dependent_on_false"]', 2)
14
+ I.dontSeeElement('[data-schemapath="root.dependent_on_false"]')
15
+ })
@@ -1,4 +1,5 @@
1
- version: '3'
2
1
  services:
3
2
  chrome:
4
- image: seleniarm/standalone-chromium:114.0
3
+ image: seleniarm/standalone-chromium
4
+ firefox:
5
+ image: seleniarm/standalone-firefox
@@ -0,0 +1,68 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>GitHub Issue 1559 - Dependencies with false values not fulfilled</title>
6
+ <script src="../../../dist/jsoneditor.js"></script>
7
+ <link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
8
+ <link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
9
+ </head>
10
+ <body>
11
+
12
+ <div class="container">
13
+ <h1>Test - Dependencies with false values not fulfilled</h1>
14
+ <p>When <code>dependent_on_true</code> is unchecked (false), the <code>dependent_on_false</code> field should appear. This tests GitHub issue #1559 - dependencies with false values not being fulfilled.</p>
15
+ <div id='editor-container'></div>
16
+ </div>
17
+
18
+ <script>
19
+ var editorContainer = document.querySelector('#editor-container')
20
+ var schema = {
21
+ "type": "object",
22
+ "title": "Test configuration",
23
+ "description": "Test configuration for dependencies with false values (GitHub issue #1559)",
24
+ "properties": {
25
+ "master_field": {
26
+ "type": "boolean",
27
+ "title": "Master field",
28
+ "format": "checkbox",
29
+ "description": "Master toggle field.",
30
+ "default": true
31
+ },
32
+ "dependent_on_true": {
33
+ "type": "boolean",
34
+ "format": "checkbox",
35
+ "title": "Dependent on true",
36
+ "description": "This field depends on master_field being true.",
37
+ "default": true,
38
+ "options": {
39
+ "dependencies": {
40
+ "master_field": true
41
+ }
42
+ }
43
+ },
44
+ "dependent_on_false": {
45
+ "type": "string",
46
+ "format": "password",
47
+ "title": "Dependent on false",
48
+ "description": "This field depends on dependent_on_true being false.",
49
+ "minLength": 1,
50
+ "options": {
51
+ "dependencies": {
52
+ "dependent_on_true": false
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ var editor = new JSONEditor(editorContainer, {
60
+ schema: schema,
61
+ theme: 'bootstrap4',
62
+ iconlib: 'fontawesome',
63
+ show_errors: 'always'
64
+ })
65
+ </script>
66
+
67
+ </body>
68
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>Purify</title>
6
+ <script src="https://cdn.jsdelivr.net/npm/dompurify@3.3.1/dist/purify.min.js"></script>
7
+ <script src="../../dist/jsoneditor.js"></script>
8
+ <link rel="stylesheet" id="theme-link" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
9
+ <link rel="stylesheet" id="iconlib-link" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css">
10
+ </head>
11
+ <body>
12
+
13
+ <div class="container">
14
+ <div id='editor-container'></div>
15
+ <label for="value">Value</label>
16
+ <textarea id="value" class="form-control value" rows="10"></textarea>
17
+ <button class="get-value btn btn-primary">Get Value</button>
18
+ <button class="set-value btn btn-secondary">Set Value</button>
19
+ </div>
20
+
21
+ <script>
22
+ const editorContainer = document.querySelector('#editor-container')
23
+ const value = document.querySelector('#value');
24
+ const schema = {
25
+ "type": "object",
26
+ "title": "Purify",
27
+ "properties": {
28
+ "string": {
29
+ "title": "string (StringEditor)",
30
+ "type": "string"
31
+ }
32
+ }
33
+ }
34
+
35
+ const editor = new JSONEditor(editorContainer, {
36
+ schema: schema,
37
+ theme: 'bootstrap4',
38
+ iconlib: 'fontawesome',
39
+ disable_properties: true,
40
+ disable_collapse: true,
41
+ disable_edit_json: true,
42
+ })
43
+
44
+ const getValueBtn = document.querySelector('.get-value')
45
+ const setValueBtn = document.querySelector('.set-value')
46
+
47
+ editor.on('change', function () {
48
+ value.value = JSON.stringify(editor.getValue())
49
+ })
50
+
51
+ getValueBtn.addEventListener('click', function () {
52
+ value.value = JSON.stringify(editor.getValue())
53
+ })
54
+
55
+ setValueBtn.addEventListener('click', function () {
56
+ try {
57
+ editor.setValue(JSON.parse(value.value))
58
+ } catch (e) {
59
+ editor.setValue({ string: value.value })
60
+ }
61
+ })
62
+ </script>
63
+
64
+ </body>
65
+ </html>
66
+