├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── documentation ├── additional_storage.yaml ├── decrypt-form.tpl.html ├── docs │ ├── explanations.md │ ├── features │ │ ├── index.md │ │ ├── jsext.md │ │ ├── modifypages.md │ │ ├── search.md │ │ └── security.md │ ├── img │ │ ├── howitworks.svg │ │ ├── logo.ico │ │ └── logo.svg │ ├── index.md │ ├── installation.md │ ├── testbench │ │ ├── anchor.md │ │ ├── hashfilenames.md │ │ ├── index.de.md │ │ ├── index.md │ │ ├── jstest.md │ │ ├── obfuscate.de.md │ │ ├── obfuscate.md │ │ ├── onlypasswords1.de.md │ │ ├── onlypasswords1.md │ │ ├── onlypasswords2.de.md │ │ ├── onlypasswords2.md │ │ ├── onlypasswords3.de.md │ │ ├── onlypasswords3.md │ │ ├── search.md │ │ ├── share.de.md │ │ ├── share.md │ │ ├── test1.md │ │ ├── test2.md │ │ ├── test3.md │ │ ├── test4.md │ │ ├── test5.md │ │ ├── userpass1.de.md │ │ ├── userpass1.md │ │ ├── userpass2.de.md │ │ └── userpass2.md │ └── usage.md ├── encryptcontent.cache ├── extra_css │ ├── stackoverflow-dark.min.css │ └── stackoverflow-light.min.css ├── hooks.py ├── img │ └── howitworks.odg ├── mkdocs.yml ├── mkdocs_material.yml ├── mkdocs_mkdocs.yml ├── passwords.yml ├── sharelinks.txt └── theme_override │ └── main.html ├── encryptcontent ├── __init__.py ├── canary.tpl.py ├── contrib │ └── templates │ │ └── search │ │ ├── lunr.js │ │ ├── main.js │ │ └── worker.js ├── decrypt-contents.tpl.js ├── decrypt-form.tpl.html └── plugin.py ├── patches ├── material_browser_request9.patch ├── material_browser_request9_4p.patch └── material_search_worker8.patch └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | build/ 3 | mkdocs_encryptcontent_plugin.egg-info/ 4 | install.cmd 5 | *.bak 6 | documentation/site/ 7 | deploy.cmd 8 | documentation/encryptcontent.key 9 | documentation/canary.py 10 | documentation/theme_override/assets/ 11 | documentation/__pycache__/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Thank you for considering to contribute to this project. These guidelines will help you get going with development and outline the most important rules to follow when submitting pull requests for this project. 4 | 5 |
6 | 7 | ## Development 8 | 9 | #### Setup 10 | 11 | ##### Prerequisites 12 | 13 | - [Python] 14 | - [virtualenv] 15 | 16 | ##### Steps 17 | 18 | 1. Clone the (forked) repository 19 | 1. Create a virtualenv with `virtualenv env` 20 | 1. Activate virtualenv `source env/bin/activate` or `env/Scripts/activate` on Windows 21 | 1. Run `pip install -r requirements.txt` in the project directory 22 | 23 | #### Running Tests 24 | 25 | ```bash 26 | pytest 27 | ``` 28 | 29 |
30 | 31 | 32 | ## Submitting Changes 33 | 34 | To get changes merged, create a pull request. Here are a few things to pay attention to when doing so: 35 | 36 | #### Commit Messages 37 | 38 | The summary of a commit should be concise and worded in an imperative mood. 39 | ...a *what* mood? This should clear things up: *[How to Write a Git Commit Message][git-commit-message]* 40 | 41 | #### Code Style 42 | 43 | Make sure your code follows [PEP-8](https://www.python.org/dev/peps/pep-0008/) and keeps things consistent with the rest of the code. 44 | 45 | #### Tests 46 | 47 | If it makes sense, writing tests for your PRs is always appreciated and will help get them merged. 48 | 49 | [Python]: https://www.python.org/ 50 | [virtualenv]: https://virtualenv.pypa.io/ 51 | [git-commit-message]: https://chris.beams.io/posts/git-commit/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2018 Lukas Geiter 4 | Copyright (c) 2019 CoinK0in 5 | Copyright (c) 2022 René Rüthlein 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. -------------------------------------------------------------------------------- /documentation/additional_storage.yaml: -------------------------------------------------------------------------------- 1 | userpass: 2 | alice: 3 | username: Alice McAliceface 4 | userid: 1 5 | token: uCZDqa2vzuSPFX-o9TebinUAnD9sePJqpPYhavMkCH7gGo7lhjWRS17-HgBys9UKnFR37zXO4Q_f1_ywZJqBlA== 6 | bob: 7 | username: Bob McBobface 8 | userid: 2 9 | token: uCZDqa2vzuSPFX-o9TebinUAnD9sePJqpPYhavMkCH7gGo7lhjWRS17-HgBys9UKnFR37zXO4Q_f1_ywZJqBlA== 10 | carlos: 11 | username: Carlos McCarlosface 12 | userid: 3 13 | token: uCZDqa2vzuSPFX-o9TebinUAnD9sePJqpPYhavMkCH7gGo7lhjWRS17-HgBys9UKnFR37zXO4Q_f1_ywZJqBlA== 14 | carol: 15 | username: Carol McCarolface 16 | charlie: 17 | username: Charlie McCharlieface 18 | dan: 19 | username: Dan McDanface 20 | token: uCZDqa2vzuSPFX-o9TebinUAnD9sePJqpPYhavMkCH7gGo7lhjWRS17-HgBys9UKnFR37zXO4Q_f1_ywZJqBlA== 21 | dave: 22 | username: Dave McDaveface 23 | token: uCZDqa2vzuSPFX-o9TebinUAnD9sePJqpPYhavMkCH7gGo7lhjWRS17-HgBys9UKnFR37zXO4Q_f1_ywZJqBlA== 24 | david: 25 | username: David McDavidface 26 | token: uCZDqa2vzuSPFX-o9TebinUAnD9sePJqpPYhavMkCH7gGo7lhjWRS17-HgBys9UKnFR37zXO4Q_f1_ywZJqBlA== 27 | 28 | password: 29 | C4bbage Profile blinking: 30 | username: Cabbage McPassword 31 | userid: 90 32 | token: NM-pdQyiJnLXSzY1e3d13GuekqLkClfWDLHtWQIu0l-geAkrygFvjJa3eux6ZJVAiSMtM8jphQCSSl9ru7TvRA== 33 | Clique.Shampoo.Ve55el: 34 | username: Clique McPassword 35 | userid: 91 36 | token: NM-pdQyiJnLXSzY1e3d13GuekqLkClfWDLHtWQIu0l-geAkrygFvjJa3eux6ZJVAiSMtM8jphQCSSl9ru7TvRA== 37 | Hatless,hertz,C4lzone: 38 | username: Hatless McPassword 39 | userid: 92 40 | Head32_Sculpture_bovine_: 41 | username: Head McPassword 42 | Negotiator-leftover-567: 43 | username: Negotiator McPassword 44 | token: NM-pdQyiJnLXSzY1e3d13GuekqLkClfWDLHtWQIu0l-geAkrygFvjJa3eux6ZJVAiSMtM8jphQCSSl9ru7TvRA== 45 | SpotChestOilCycle22: 46 | username: Spot McPassword 47 | token: NM-pdQyiJnLXSzY1e3d13GuekqLkClfWDLHtWQIu0l-geAkrygFvjJa3eux6ZJVAiSMtM8jphQCSSl9ru7TvRA== 48 | m00dy#augmented#Arsonist: 49 | username: Moody McPassword 50 | token: NM-pdQyiJnLXSzY1e3d13GuekqLkClfWDLHtWQIu0l-geAkrygFvjJa3eux6ZJVAiSMtM8jphQCSSl9ru7TvRA== 51 | moist:W00l:kept:royal: 52 | username: Moist McPassword 53 | token: NM-pdQyiJnLXSzY1e3d13GuekqLkClfWDLHtWQIu0l-geAkrygFvjJa3eux6ZJVAiSMtM8jphQCSSl9ru7TvRA== 54 | -------------------------------------------------------------------------------- /documentation/decrypt-form.tpl.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

{{ summary }}

5 | {% if encryption_info_message %}

{{ encryption_info_message }}

{% endif %} 6 |
7 | {%- if obfuscate %} 8 | 9 | {%- else %} 10 | {%- if uname %} 11 |
12 | 13 |
14 | {%- endif %} 15 |
16 | 17 |
18 | {%- endif %} 19 | {%- if password_button %} 20 |
21 | {{ password_button_text }} 22 |
23 | {% endif -%} 24 |
25 |

26 |
27 |
28 |
29 | 38 | {%- if esm %} 39 | 53 | {%- else %} 54 | {%- for library in js_libraries %} 55 | 56 | {%- endfor %} 57 | 58 | {%- endif %} 59 | 63 | -------------------------------------------------------------------------------- /documentation/docs/explanations.md: -------------------------------------------------------------------------------- 1 | # How does this work? 2 | 3 | For every `password` and for every `level` we generate a random 256 bit key. 4 | This key will be used for AES-256 encryption on every page with the same `password` or same `level`. 5 | Optionally search entries and [encrypt something](#encrypt-something) on that page are also encrypted with the same key. 6 | 7 | This random secret key (needed for deciphering the pages content) is then encrypted to a keystore with another key that is derived from 8 | the defined credentials (a password or a username/password pair). 9 | If the credential is reused on another `level`, then its random key is also encrypted in the same keystore. 10 | The function to derive the key to the keystore (PBKDF2) can be adjusted in calculation cycles 11 | to hopefully throttle the number of passwords a brute force attacker is able to try per second. 12 | 13 | ![](img/howitworks.svg) 14 | 15 | #### AES 16 | 17 | Is a symmetric encryption algorithm. Symmetric means it uses the same secret key for encryption and decryption. 18 | The size of the secret keys used in this plugin is 256 Bit (or 32 Bytes).\ 19 | Additionally a random (16 Bytes) initialization vector (called IV) is used (and added to the cyphertext) 20 | to make sure the same plaintext will always result in a different cyphertext even if the same secret key is used 21 | for encryption. 22 | 23 | #### KDF 24 | 25 | A **K**ey **D**erivation **F**unction a one-way key generation algorithm, 26 | so it is not possible to reverse the function to retrieve a lost password.\ 27 | The password is salted, meaning if two people used the same password it would lead to different keys (similar to IV in AES).\ 28 | It is equipped with adjustable difficulty `kdf_pow`. The difficulty has significant weight on the build time and also 29 | the time needed to decrypt a page, so it shouldn't be increased to any value.\ 30 | The algorithm used (PBKDF2) is not really state-of-the-art, meaning compared to better alternatives like bcrypt, scrypt or argon2 31 | it is easier to crack with hardware acceleration, however it is supported in both crypto-js and webcrypto and 32 | is significantly better than MD5 (which was used on all versions prior to 3.x) for key derivation.\ 33 | The secret key derived from PBKDF2 is used to decrypt the keystore containing different keys to decrypt the content. 34 | 35 | # A word on password strength 36 | 37 | The strength of a password can be measured in entropy or "possibilities to try" (for a brute force attacker). 38 | 39 | \[ 40 | S = C^{L} * T 41 | \] 42 | 43 | **S** is the time it takes to try all possibilities (on average a password is found after trying half the possibilities), 44 | **C** being the number of different characters the password is made of, **L** being the length of the password 45 | and **T** the time it takes to try one password. 46 | 47 | For example take a tree character password with just lower case letters like "abc". 48 | The number of lower case letters is 26, so a three character password leads to 26 * 26 * 26 = 17 576 possibilities to try. 49 | 50 | Now take a three character password which also includes upper case letters like "aBc". 51 | The number of possibilities per character doubles to 52, so the three character password leads to 52 * 52 * 52 = 140 608 possibilities. 52 | So compared to "abc" we got **eight times** more entropy in this case. 53 | 54 | So what happens if we add one character and still only use lower case letters, like "abcd"? 55 | It's 26^4 = 456 976 with a four character password, that's **26 times** more entropy compared to only using three lower case characters. 56 | 57 | It's easier to get higher entropy by increasing password size, than with adding more different characters or symbols. 58 | An attacker could also have watched (or heard) you type the password (paying attention to the use of the shift key, 59 | space bar or numeric keypad) and this way cross out character that you couldn't possibly have used. 60 | 61 | So, to put it mildly: Every web page that forces you to use at least lower/upper case AND a number AND a symbol, 62 | BUT only forces you to use eight characters of password size is not steering you to the right measures to gain entropy. 63 | 64 | But, to be fair: A web page can take measures to seriously throttle the passwords try-able per second on the server side 65 | or f.ex. use captchas after the third failed try. Although there were and most likely will be bad or failed examples of those measures. 66 | 67 | This MkDocs plugin can currently only take additional counter-measures to brute force attacks in form of PBKDF2. 68 | PBKDF2 itself is more or less obsolete, because it got no defense against being run in parallel, so we should 69 | consider it to not having a big effect on **T**. 70 | Other options like bcrypt, scrypt od argon2 exist, but pbkdf2 is the only option 71 | currently available in crypto-js and webcrypto. However there may be limitations that render the other option impractical, 72 | like longer build times and high computing or memory requirements on mobile devices. 73 | So you should really be interested in choosing a **long** password or pass phrases 74 | (read the [Diceware article on Wikipedia](https://en.wikipedia.org/wiki/Diceware), [xkcd webcomic on password strength](https://xkcd.com/936/) 75 | and [this blogpost](https://blog.benpri.me/blog/2019/01/13/why-you-shouldnt-be-using-bcrypt-and-scrypt/)). 76 | 77 | 78 | -------------------------------------------------------------------------------- /documentation/docs/features/index.md: -------------------------------------------------------------------------------- 1 | # Features 2 | 3 | ## Override default templates 4 | 5 | Related to [issue #32](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/32) 6 | 7 | You can override the default templates with your own templates by providing an actual replacement 8 | path in the `html_template_path` *(HTML)* and `js_template_path` *(JS)* directives. 9 | Overridden templates **completely** replace the default templates. You **must** therefore copy the 10 | default templates as a starting point to keep this plugin working. 11 | 12 | ```yaml 13 | plugins: 14 | - encryptcontent: 15 | html_template_path: "/root/real/path/mkdocs_poc/my_html_template.html" 16 | js_template_path: "/root/real/path/mkdocs_poc/my_js_template.js" 17 | form_class: 'md-content__inner md-typeset' 18 | input_class: 'md-input' 19 | button_class: 'md-button md-button--primary' 20 | ``` 21 | 22 | Use `form_class`, `input_class` and `button_class` to optionally set a CSS class for the password input field and the button. 23 | 24 | When overriding the default templates, you can add and use your own Jinja variables 25 | and enrich your template, by defining `html_extra_vars` and `js_extra_vars` directives in key/value format. 26 | Added values can be used in your Jinja templates via the variable `extra`. 27 | 28 | ```yaml 29 | plugins: 30 | - encryptcontent: 31 | html_extra_vars: 32 | my_extra: "extra value" 33 | : 34 | js_extra_vars: 35 | my_extra: "extra value" 36 | : 37 | ``` 38 | 39 | For example, you can modify your HTML template, to add a new title with your own text variable. 40 | 41 | ```jinja 42 | [ ... ] 43 |

{{ extra.my_extra }}

44 | [ ... ] 45 | ``` 46 | 47 | > **NOTE** Issues related to template override will not be addressed. 48 | 49 | ## Add button 50 | 51 | Add `password_button: True` in plugin configuration variable, to add a button to the right of the password field. 52 | 53 | When enabled, it allows to decrypt the content just like the classic keypress ENTER. 54 | 55 | Optionally, you can add `password_button_text: 'custom_text_button'` to customize the button text. 56 | 57 | ```yaml 58 | plugins: 59 | - encryptcontent: 60 | password_button: True 61 | password_button_text: 'custom_text_button' 62 | ``` 63 | 64 | ## Tag encrypted page 65 | 66 | > **Enable by default** 67 | 68 | Related to [issue #7](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/7) 69 | 70 | This feature adds an additional attribute `encrypted` with value `True` to the mkdocs type `mkdocs.nav.page` object. 71 | 72 | You can add `tag_encrypted_page: False` in plugin configuration, to disable tagging of encrypted pages. 73 | 74 | When enabled, it is possible to use the `encrypted` attribute in the jinja template of your theme, as a condition to perform custom modification. 75 | 76 | ```jinja 77 | {%- for nav_item in nav %} 78 | {% if nav_item.encrypted %} 79 | 80 | {% endif %} 81 | {%- endfor %} 82 | ``` 83 | 84 | For example, you can use conditional check to add a custom class: 85 | 86 | ```jinja 87 | {{ nav_item.title }} 88 | ``` 89 | 90 | ## Remember password 91 | 92 | Related to [issue #6](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/6) 93 | 94 | By default the plugin will save the decrypted AES keys to session storage of the browser (can be disabled by setting `remember_keys: False`). 95 | This is enabled for convenience, so you are able to browse between multiple encrypted pages without having to re-enter the password. 96 | 97 | Additionally it is possible to save the entered user/password in session storage (setting `remember_password: True`). Use this for 98 | additional convenience during `mkdocs serve`, because the AES key are regenerated every time MkDocs starts 99 | (rendering the old ones invalid and requiring to re-enter a valid credential again). 100 | 101 | To avoid problems when multiple sites are hosted within the same domain, it is possible to customize the name of 102 | the keys saved to storage with `remember_prefix`. 103 | 104 | > **This feature is not really secure !** decryption keys are store in clear text inside session storage. 105 | > 106 | > Instead of using these features, I recommend to use a password manager with its browser plugin. 107 | > For example **KeepassXC** allows you to detect the password field 108 | > `mkdocs-content-password` and fill it automatically in a much more secure way. 109 | 110 | It is also possible to save the used credentials permanently to local storage (setting `session_storage: False`), but 111 | this should only be done for testing purposes. The local storage of a browser is most likely readable 112 | for every other process that can access the file system. 113 | 114 | The session storage however should only be located in memory and be forgotten after the browser tab is closed. 115 | 116 | ```yaml 117 | plugins: 118 | - encryptcontent: 119 | remember_keys : True 120 | remember_password: False 121 | remember_prefix: secretsite_ 122 | ``` 123 | 124 | ## Share link generation 125 | 126 | It is possible to share valid credentials by adding them to the hash part of the URL. 127 | The plugin can also generate share links for certain pages if the meta tag `sharelink: true` 128 | is defined in markdown. 129 | It will use the first credential for the pages level or the pages password. 130 | The credentials for auto-generated links are base64url encoded. 131 | 132 | ```yaml 133 | plugins: 134 | - encryptcontent: 135 | sharelinks: True 136 | sharelinks_output: 'sharelinks.txt' # generated share links are saved here 137 | ``` 138 | > One condition applies: The user name must not contain the ":" character (Passwords may use that character). 139 | 140 | However if `sharelinks: True` is enabled in the plugin configuration you can generate share links yourself:\ 141 | `https://your-domain.com/your-site/protected-page/#!username:password` for user/password or\ 142 | `https://your-domain.com/your-site/protected-page/#!password` for only password. 143 | 144 | > Then another condition applies: If non-aphanumeric characters are used in user/password, 145 | > they need to be URLencoded (f.ex. %20 = space character). Some browsers may do that automatically (Do a copy/paste from the browsers address bar then). 146 | 147 | ### Incomplete Share links 148 | 149 | Since version 3.0.3 it is possible to leave out one part of the password when share links are generated via meta tag. 150 | To do this use the ":" character in a password to divide the part that is incorporated to the share link and the part that remains secret, 151 | like "PartThatIsEncodedToTheShareLink:PartThatRemainsSecret". 152 | The feature is enabled by setting the option `sharelinks_incomplete: true`. 153 | If the password that is read from the share link ends with the ":" character, then an additional password input field is displayed for entering the secret part. 154 | 155 | > If the feature is used, then passwords must not end with the ":" character. 156 | 157 | 158 | ## Storage of additional variables in keystore 159 | 160 | Since version 3.0.3 it is possible to set arbitrary session store variables after decryption. 161 | These can be used by javascript functions f. ex. to read API tokens or show the user name or set visibility of menu entries. 162 | The variables are encrypted together with the content keys in the keystore. 163 | 164 | ```yaml 165 | plugins: 166 | - encryptcontent: 167 | additional_storage_file: 'additional_storage.yaml' 168 | ``` 169 | 170 | The file may contain a `userpass:` dictionary, wich refers to user names 171 | and/or a `password:` dictionary, that refers to password-only credentials. 172 | It may contain a arbitrary number of key/value pairs, 173 | but keep in mind to check if the key name is reasonable and not already used by other parts of the page 174 | (as it will be overwritten after decryption). 175 | 176 | ```yaml 177 | userpass: 178 | alice: 179 | username: Alice McAliceface 180 | userid: 1 181 | token: uCZDqa2vzuSPFX-o9TebinUAnD9sePJqpPYhavMkCH7gGo7lhjWRS17-HgBys9UKnFR37zXO4Q_f1_ywZJqBlA== 182 | 183 | password: 184 | Head32_Sculpture_bovine_: 185 | username: Head McPassword 186 | ``` -------------------------------------------------------------------------------- /documentation/docs/features/jsext.md: -------------------------------------------------------------------------------- 1 | ## Javascript extensions 2 | 3 | ### Reload user-defined scripts 4 | 5 | Related to [issue #14](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/14) 6 | 7 | You can set `reload_scripts:` in your `mkdocs.yml` with list of script sources 8 | or script ids, to reload and execute some js lib after decryption process. 9 | 10 | ```yaml 11 | plugins: 12 | - encryptcontent: 13 | reload_scripts: 14 | - 'js/example.js' 15 | - '#autoexec' 16 | ``` 17 | 18 | It is also possible to reload a script id like `` 19 | that was encrypted within the page 20 | (related to [issue #30](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/30)). 21 | 22 | 23 | ### HighlightJS support 24 | 25 | > **Enable by default** 26 | 27 | If HighlightJS module is detected in your theme to improve code color rendering, reload renderer after 28 | decryption process. 29 | If HighlightJS module is not correctly detected, you can force the detection by adding `hljs: True` 30 | on the plugin configuration 31 | or set `hljs: False` to disable this feature. 32 | 33 | When enabled the following part of the template is added to force reloading decrypted content. 34 | 35 | ```jinja 36 | {% if hljs %} 37 | document.getElementById("mkdocs-decrypted-content").querySelectorAll('pre code').forEach((block) => { 38 | hljs.highlightElement(block); 39 | }); 40 | {% endif %} 41 | ``` 42 | 43 | 44 | ### Arithmatex support 45 | 46 | > **Enable by default** 47 | 48 | Related to [issue #12](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/12) 49 | 50 | If Arithmatex markdown extension is detected in your markdown extensions to improve math equations rendering, 51 | reload renderer after decryption process. 52 | If the Arithmatex markdown extension is not correctly detected, you can force the detection by adding 53 | `arithmatex: True` on the plugin configuration 54 | or set `arithmatex: False` to disable this feature. 55 | 56 | When enabled, the following part of the template is added to force math equations rendering on decrypted content. 57 | 58 | ```jinja 59 | {% if arithmatex %} 60 | MathJax.typesetPromise() 61 | {% endif %} 62 | ``` 63 | 64 | > **NOTE** It has been tested in Arithmatex `generic` mode only. 65 | 66 | 67 | ### Mermaid.js support 68 | 69 | #### mkdocs-mermaid2-plugin 70 | 71 | > **Enable by default** 72 | 73 | Related to [issue #22](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/22). 74 | 75 | If mermaid2 plugin is detected in your configuration to generate graph from text, reload renderer after 76 | decryption process. 77 | If the Mermaid2 plugin is not correctly detected, you can force the detection by adding `mermaid2: True` 78 | on the plugin configuration 79 | or set `mermaid2: False` to disable this feature. 80 | 81 | When enabled, the following part of the template is added to force graph rendering on decrypted content. 82 | 83 | ```jinja 84 | {% if mermaid2 %} 85 | mermaid.contentLoaded(); 86 | {% endif %} 87 | ``` 88 | 89 | > **NOTE** it currently only works with mermaid version < 10. Also encryptcontent needs to be injected, 90 | > because the mermaid2 plugin otherwise won't detect the page content correctly. 91 | 92 | activate the plugin like this: 93 | 94 | ```yaml 95 | plugins: 96 | - mermaid2: 97 | version: 9.4.3 98 | 99 | markdown_extensions: 100 | - pymdownx.blocks.html 101 | ``` 102 | 103 | Example usage: 104 | 105 | ```` 106 | password: 1234 107 | inject_id: inject 108 | 109 | 110 | /// html | div#inject 111 | 112 | ```mermaid 113 | graph LR 114 | hello --> world 115 | world --> again 116 | again --> hello 117 | ``` 118 | 119 | /// 120 | ```` 121 | 122 | #### mkdocs-material 123 | 124 | > **Enable by default** 125 | 126 | Add support for mermaid graphs by adding the `pymdownx.superfences` to `markdown_extensions` as 127 | described [here]( https://squidfunk.github.io/mkdocs-material/reference/diagrams/). 128 | 129 | After successful decryption all subscriptions of the document are recalled to render the marmaid graph, 130 | see [here](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/pull/81). 131 | 132 | ```jinja 133 | {%- if material %} 134 | document$.next(document); 135 | {%- endif %} 136 | ``` 137 | 138 | 139 | ### mkdocs-glightbox 140 | 141 | Related to [issue #62](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/62). 142 | 143 | The plugin would add click events to all image of a page, but it can't do that if the page was encrypted. 144 | That's why we need to add it to `reload_scripts` section to call it after successful decryption. 145 | 146 | ```yaml 147 | plugins: 148 | - glightbox: 149 | zoomable: true 150 | draggable: true 151 | skip_classes: 152 | - skip-lightbox 153 | - encryptcontent: 154 | reload_scripts: 155 | - '#init-glightbox' 156 | ``` -------------------------------------------------------------------------------- /documentation/docs/features/modifypages.md: -------------------------------------------------------------------------------- 1 | ## Modify generated pages 2 | 3 | ### Encrypt something 4 | 5 | Related to [issue #9](https://github.com/unverbuggt/mkdocs-encryptcontent-plugin/issues/9) 6 | 7 | Add `encrypted_something: {}` in the plugin configuration variable, to encrypt something else on the page. 8 | 9 | The syntax of this new variable **MUST** follow the yaml format of a dictionary. 10 | Child elements of `encrypted_something` are build with a key `` in string format and a list as value. 11 | The list has to be constructed with the name of an HTML tag `` as first item 12 | and `id` or `class` as the second item. 13 | 14 | ```yaml 15 | plugins: 16 | - encryptcontent: 17 | encrypted_something: 18 | : [, <'class' or 'id'>] 19 | ``` 20 | 21 | The `` key identifies the name of a specific element of the page that will be 22 | searched by Beautiful Soup. 23 | The first value of the list (``) identifies the type of HTML tag in which the name is present. 24 | The second value of the list (`'id'` or `'class'`) specifies the type of the attribute which contains 25 | the unique name in the html tag. 26 | 27 | Prefer to use an `'id'`, however depending on the template of your theme, it is not always possible to use the id. 28 | So we can use the class attribute to define your unique name inside the html tag. 29 | Beautiful Soup will encrypt all HTML elements discovered with the class. 30 | 31 | When the feature is enabled every element is decrypted upon successfull content decryption on the page. 32 | 33 | > Use this to hide the table of contents on the page or sub pages in the menu 34 | 35 | By default **every child item** are encrypted and the encrypted elements have set 36 | `style="display:none;"` to hide their content. 37 | 38 | #### How to use it?! Examples 39 | 40 | You can use the `page.encrypted` tag to add attributes to html tags in the HTML templates of your theme 41 | or identify usable tag ids or classes that are already in the theme. 42 | 43 | Then add these elements in the format of a yaml dictionary under the variable `encrypted_something`. 44 | 45 | 1. For example, encrypt ToC in a theme where ToC is under 'div' element like this : 46 | 47 | ```jinja 48 |
49 | 53 |
54 | ``` 55 | 56 | Set your configuration like this : 57 | 58 | ```yaml 59 | plugins: 60 | - encryptcontent: 61 | encrypted_something: 62 | mkdocs-encrypted-toc: [div, id] 63 | ``` 64 | 65 | 2. Other example, with multiple targets. You are using a custom version of Material theme and 66 | want to encrypt ToC content and Footer. 67 | 68 | Material generates 2 `