diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml
index 84353e56..9cc56eaf 100644
--- a/.github/workflows/cypress.yml
+++ b/.github/workflows/cypress.yml
@@ -26,6 +26,11 @@ jobs:
restore-keys: |
${{ runner.os }}-node_modules-build-
+ - name: Lint
+ run: |
+ yarn install
+ yarn run lint
+
# Install NPM dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
diff --git a/cypress/integration/loadSite.spec.ts b/cypress/integration/loadSite.spec.ts
index c83d6d14..57e3e397 100644
--- a/cypress/integration/loadSite.spec.ts
+++ b/cypress/integration/loadSite.spec.ts
@@ -1,3 +1,5 @@
+import { toBase64 } from 'js-base64';
+
describe('Site Loads', () => {
beforeEach(() => {
cy.clearLocalStorage();
@@ -31,12 +33,29 @@ describe('Site Loads', () => {
});
it('should prevent setting the "securityLevel" option via URL', () => {
- const b64State = btoa(
- `{"code":"graph TD\\nA[\\"
\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`
+ const b64State = toBase64(
+ `{"code":"graph TD\\nA[\\"
\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`,
+ true
);
+ cy.on('window:confirm', () => true);
cy.visit(`/edit#${b64State}`);
cy.contains('Config').click();
- cy.contains('forest').should('exist');
+ cy.contains('forest');
cy.contains('securityLevel').should('not.exist');
+ cy.get('#view').find('img').should('not.exist');
+ cy.get('#view').contains('
{
+ const b64State = toBase64(
+ `{"code":"graph TD\\nA[\\"
\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`,
+ true
+ );
+ cy.on('window:confirm', () => false);
+ cy.visit(`/edit#${b64State}`);
+ cy.contains('Config').click();
+ cy.contains('forest');
+ cy.contains('securityLevel');
+ cy.get('#view').find('img').should('be.visible');
});
});
diff --git a/cypress/snapshots.js b/cypress/snapshots.js
index e2663900..f769a8db 100644
--- a/cypress/snapshots.js
+++ b/cypress/snapshots.js
@@ -7,7 +7,7 @@ module.exports = {
"1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":false}"
}
},
- "__version": "7.4.0",
+ "__version": "7.5.0",
"Auto sync tests": {
"should dim diagram when code is edited": {
"1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n C --> Test\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":false,\"updateDiagram\":false}"
diff --git a/src/lib/components/view.svelte b/src/lib/components/view.svelte
index 35e5cb31..7b3204e8 100644
--- a/src/lib/components/view.svelte
+++ b/src/lib/components/view.svelte
@@ -7,6 +7,7 @@
const mermaid: Mermaid = window.mermaid as unknown as Mermaid;
let code = '';
+ let config = '';
let container: HTMLDivElement;
let error = false;
let outOfSync = false;
@@ -20,7 +21,12 @@
}
outOfSync = false;
manualUpdate = true;
+ if (code === state.code && config === state.mermaid) {
+ // Do not render if there is no change in Code/Config
+ return;
+ }
code = state.code;
+ config = state.mermaid;
const scroll = container.parentElement.parentElement.parentElement.scrollTop;
delete container.dataset.processed;
mermaid.initialize(Object.assign({}, JSON.parse(state.mermaid)));
diff --git a/src/lib/util/state.ts b/src/lib/util/state.ts
index d0f8ee82..3669b6ac 100644
--- a/src/lib/util/state.ts
+++ b/src/lib/util/state.ts
@@ -37,9 +37,14 @@ export const loadState = (data: string): void => {
state = JSON.parse(stateStr);
const mermaidConfig =
typeof state.mermaid === 'string' ? JSON.parse(state.mermaid) : state.mermaid;
- if(mermaidConfig.securityLevel) {
- alert(`securityLevel was removed from config. Please add "securityLevel":"${mermaidConfig.securityLevel}" to your config if you trust the source of this Diagram`);
- delete mermaidConfig.securityLevel; // Prevent setting overriding securityLevel when loading state to mitigate possible XSS attack
+ if (
+ mermaidConfig.securityLevel &&
+ mermaidConfig.securityLevel !== 'strict' &&
+ confirm(
+ `Removing "securityLevel":"${mermaidConfig.securityLevel}" from the config for safety.\nClick Cancel if you trust the source of this Diagram.`
+ )
+ ) {
+ delete mermaidConfig.securityLevel; // Prevent setting overriding securityLevel when loading state to mitigate possible XSS attack
}
state.mermaid = JSON.stringify(mermaidConfig, null, 2);