Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/vjeantet/hugo-theme-docport.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvjeantet <valere.jeantet@gmail.com>2020-09-23 23:39:42 +0300
committervjeantet <valere.jeantet@gmail.com>2020-09-23 23:39:42 +0300
commitd1f32ddaf9f51b037f8221460cfba10bdcd2e141 (patch)
tree03e27aedc0caedccb2b679d49fb4d5ab92da5fd4
parentee1a0501f9841ea3719dbde8dd542f25982cc826 (diff)
add checklist kind of pages
-rw-r--r--assets/sass/checklist.scss70
-rw-r--r--assets/sass/layout.scss4
-rw-r--r--assets/sass/main.scss16
-rw-r--r--assets/sass/shortcodes/notice.scss66
-rw-r--r--exampleSite/content/_layout/article-sidebar-after/_index.md3
-rw-r--r--exampleSite/content/checklist/01_appmetadata.md16
-rw-r--r--exampleSite/content/checklist/02_vulnerabilityreporting.md25
-rw-r--r--exampleSite/content/checklist/03_https.md135
-rw-r--r--exampleSite/content/checklist/04_authz.md119
-rw-r--r--exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md104
-rw-r--r--exampleSite/content/checklist/04_authz_Authorization.md44
-rw-r--r--exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md123
-rw-r--r--exampleSite/content/checklist/04_authz_OAuth2Login.md31
-rw-r--r--exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md142
-rw-r--r--exampleSite/content/checklist/05_commonvuln.md81
-rw-r--r--exampleSite/content/checklist/05_commonvuln_BrowserPlugins.md49
-rw-r--r--exampleSite/content/checklist/05_commonvuln_CrossSiteScripting.md136
-rw-r--r--exampleSite/content/checklist/05_commonvuln_FileUploads.md109
-rw-r--r--exampleSite/content/checklist/05_commonvuln_PersistenceBackEndsandQuerying.md67
-rw-r--r--exampleSite/content/checklist/05_commonvuln_UseofCryptography.md11
-rw-r--r--exampleSite/content/checklist/06_testing.md111
-rw-r--r--exampleSite/content/checklist/__article-sidebar-after.md12
-rw-r--r--exampleSite/content/checklist/_index.md267
-rw-r--r--exampleSite/content/content-and-customization/00-adding-content/page-checklist/_index.md34
-rw-r--r--exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.content42
-rw-r--r--exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.json1
-rw-r--r--exampleSite/resources/_gen/assets/scss/sass/layout.scss_f300667da4f5b5f84e1a9e0702b2fdde.content4
-rw-r--r--exampleSite/resources/_gen/assets/scss/sass/main.scss_97a9b8e6852415b29a37632934745b8b.content15
-rw-r--r--exampleSite/resources/_gen/assets/scss/sass/shortcodes/notice.scss_f300667da4f5b5f84e1a9e0702b2fdde.content19
-rw-r--r--i18n/en.toml11
-rw-r--r--i18n/fr.toml11
-rw-r--r--layouts/index.json2
-rw-r--r--layouts/partials/_checklist-footer.html8
-rw-r--r--layouts/partials/_checklist-header.html16
-rw-r--r--layouts/partials/_mdinclude.html18
-rw-r--r--layouts/partials/body-article-content.html16
-rw-r--r--layouts/partials/body-article-sidepage.html5
-rw-r--r--layouts/partials/body-footer.html2
-rw-r--r--layouts/partials/body-header.html2
-rw-r--r--layouts/partials/body-sidebar.html4
-rw-r--r--layouts/partials/html-head.html11
-rw-r--r--layouts/shortcodes/alert.html2
-rw-r--r--layouts/shortcodes/attachments.html2
-rw-r--r--layouts/shortcodes/c/check.html29
-rw-r--r--layouts/shortcodes/c/choices.html31
-rw-r--r--layouts/shortcodes/c/list.html34
-rw-r--r--layouts/shortcodes/c/show.html12
-rw-r--r--layouts/shortcodes/c/switch.html8
-rw-r--r--layouts/shortcodes/c/text.html19
-rw-r--r--layouts/shortcodes/children.html2
-rw-r--r--layouts/shortcodes/columns.html2
-rw-r--r--layouts/shortcodes/include.html9
-rw-r--r--layouts/shortcodes/notice.html2
-rw-r--r--layouts/shortcodes/panel.html2
-rw-r--r--layouts/shortcodes/tabs.html2
-rw-r--r--static/js/checklist.js276
56 files changed, 2330 insertions, 64 deletions
diff --git a/assets/sass/checklist.scss b/assets/sass/checklist.scss
new file mode 100644
index 0000000..a2eb688
--- /dev/null
+++ b/assets/sass/checklist.scss
@@ -0,0 +1,70 @@
+body {
+ article section.page div.content {
+ div.checklist-header {
+ .form-control-file {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 6em;
+ outline: none;
+ visibility: hidden;
+ cursor: pointer;
+ background-color: #c61c23;
+ box-shadow: 0 0 5px solid currentColor;
+
+ &:before {
+ content: attr(data-title);
+ position: absolute;
+ top: 0.5em;
+ left: 0;
+ width: 100%;
+ min-height: 4em;
+ line-height: 0.5em;
+ padding-top: 1.5em;
+ opacity: 1;
+ visibility: visible;
+ text-align: center;
+ border: 0.25em dashed currentColor;
+ transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
+ overflow: hidden;
+ }
+
+ &:hover {
+ &:before {
+ border-style: solid;
+ box-shadow: inset 0px 0px 0px 0.25em currentColor;
+ }
+ }
+ }
+ }
+
+
+
+ div.checklist-footer {
+ margin-top: 2em;
+ margin-bottom: 2em;
+ text-align: center;
+ }
+ }
+
+
+
+ #TableOfContents > ul li {
+ input {
+ margin-right: 0.3em;
+ }
+
+ &:not(.cl-ready):not(.cl-done):not(.cl-doing) {
+ input{
+ visibility: hidden;
+ }
+ }
+
+ &.cl-ready,&.cl-doing,&.cl-done {
+ input {
+ visibility: visible;
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss
index 20d01ba..eb1c611 100644
--- a/assets/sass/layout.scss
+++ b/assets/sass/layout.scss
@@ -108,7 +108,7 @@ body:not(.render_raw) {
margin-top: 0.5em;
margin-left: 0.2em;
ul{
- padding-left: 20px;
+ padding-left: 10px;
}
nav{
@@ -116,7 +116,7 @@ body:not(.render_raw) {
position: absolute;
z-index: 5;
border: 1px solid ;
- padding: 3px 30px;
+ padding: 1em 30px;
border-radius: 3px;
min-width: 25%;
max-width: 50%;
diff --git a/assets/sass/main.scss b/assets/sass/main.scss
index e237708..40b2b75 100644
--- a/assets/sass/main.scss
+++ b/assets/sass/main.scss
@@ -299,6 +299,8 @@ article section.page {
font-size: smaller;
color:$c_dark2;
ul{
+ padding-left-left: 0px;
+ list-style-type: none;
li a{
color:$c_saturate3;
}
@@ -306,6 +308,7 @@ article section.page {
nav{
background-color: white;
+ opacity: 0.95;
}
}
@@ -399,6 +402,11 @@ article section.page div.content{
text-decoration: underline;
}
+ p {
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+ }
+
h1 {
color:$c_dark1;
@@ -414,7 +422,13 @@ article section.page div.content{
font-weight:700;
letter-spacing:-0.95px;
- } // TABLE
+ }
+
+ h3,h4 {
+ margin-top: 0.5em;
+ }
+
+ // TABLE
table {
width: 100%;
margin-bottom: 2em;
diff --git a/assets/sass/shortcodes/notice.scss b/assets/sass/shortcodes/notice.scss
index e6291c5..eb2dff9 100644
--- a/assets/sass/shortcodes/notice.scss
+++ b/assets/sass/shortcodes/notice.scss
@@ -9,38 +9,48 @@ $color_dark : #343a40 ;
$color_white : #fff ;
$color_transparent : transparent ;
+div.notices {
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+}
- div.notices p {
- /*box-shadow: inset 4px 0 0 black;*/
- /*border-radius: .2rem;*/
- background: white;
- padding: .5rem 1rem .5rem 1rem;
- margin-top: 0px;
- box-sizing: border-box;
- box-shadow: inset 4px 0 0 black;
- background-color: lighten(black,90%);
- font-size: smaller;
- }
+div.notices > * {
+ background: white;
+ margin-top: 0px!important;
+ margin-bottom: 0px!important;
+ box-sizing: border-box;
+ box-shadow: inset 4px 0 0 black;
+ background-color: lighten(black,90%);
+ font-size: smaller;
+}
+div.notices > *:not(ul) {
+ /*box-shadow: inset 4px 0 0 black;*/
+ /*border-radius: .2rem;*/
+ padding: .5rem 1rem .5rem 1rem;
+}
+div.notices > ul {
+
+}
- div.notices label{
- font-size: 0.5em;
- position: absolute;
- margin-left: 0em;
- margin-top: -1.8em;
- font-weight: bold;
- font-variant: small-caps;
- letter-spacing: 0.6em;
- }
+div.notices label{
+ font-size: 0.5em;
+ position: absolute;
+ margin-left: 0em;
+ margin-top: -1.8em;
+ font-weight: bold;
+ font-variant: small-caps;
+ letter-spacing: 0.6em;
+}
- div.notices.note {
- p {
- box-shadow: inset 4px 0 0 $color_primary;
- background: transparentize($color_primary, 0.95);
- color: darken($color_primary,20%) !important;
- }
- label{color: $color_primary;}
+div.notices.note {
+ p {
+ box-shadow: inset 4px 0 0 $color_primary;
+ background: transparentize($color_primary, 0.95);
+ color: darken($color_primary,20%) !important;
}
+ label{color: $color_primary;}
+}
div.notices.primary {
p {
@@ -79,7 +89,7 @@ div.notices.danger {
}
div.notices.warning {
- p {
+ >* {
box-shadow: inset 4px 0 0 $color_warning;
background: transparentize($color_warning, 0.95);
color: darken($color_warning,20%) !important;
diff --git a/exampleSite/content/_layout/article-sidebar-after/_index.md b/exampleSite/content/_layout/article-sidebar-after/_index.md
new file mode 100644
index 0000000..ec380ec
--- /dev/null
+++ b/exampleSite/content/_layout/article-sidebar-after/_index.md
@@ -0,0 +1,3 @@
+---
+---
+
diff --git a/exampleSite/content/checklist/01_appmetadata.md b/exampleSite/content/checklist/01_appmetadata.md
new file mode 100644
index 0000000..d0fadee
--- /dev/null
+++ b/exampleSite/content/checklist/01_appmetadata.md
@@ -0,0 +1,16 @@
+---
+title: App Metadata
+hidden: true
+---
+
+The name of the application: {{<c/text "app_name*" />}}
+
+
+A brief description:
+{{<c/text "app_description*" multi >}}
+Lorem placeholder
+{{</c/text>}}
+
+
+What frameworks (if any) does this application require?
+{{<c/text "app_frameworks*" />}} \ No newline at end of file
diff --git a/exampleSite/content/checklist/02_vulnerabilityreporting.md b/exampleSite/content/checklist/02_vulnerabilityreporting.md
new file mode 100644
index 0000000..1c2e997
--- /dev/null
+++ b/exampleSite/content/checklist/02_vulnerabilityreporting.md
@@ -0,0 +1,25 @@
+---
+hidden: true
+---
+Because no system is entirely free of security issues, it's important to provide ways for external users to offer input and report vulnerabilities.
+
+**Do you have an easily discoverable way for external researchers to report security vulnerabilities in your systems?**
+{{<c/choices app_vuln_report_way >}}
+ * (yes) Yes, we have a published security email contact, or we provide another way for users to report security issues. Incoming reports are timely reviewed and triaged.
+ * (no) No, we do not currently offer a way to report security vulnerabilities for priority handling.
+{{</c/choices>}}
+
+
+{{<c/show `{app_vuln_report_way} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Make it easy for others to let you know about security issues in your products. That way you'll learn about vulnerabilities earlier and can respond to them quickly. Also, without an easy way to report issues directly to you, external researchers might publish issues widely instead.
+\
+\
+If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:
+{{<c/text "app_vuln_report_way_countermeasures*" multi >}}
+Lorem placeholder
+{{</c/text>}}
+{{%/notice%}}
+{{</c/show>}} \ No newline at end of file
diff --git a/exampleSite/content/checklist/03_https.md b/exampleSite/content/checklist/03_https.md
new file mode 100644
index 0000000..98d0141
--- /dev/null
+++ b/exampleSite/content/checklist/03_https.md
@@ -0,0 +1,135 @@
+---
+hidden: true
+---
+
+
+**Select the option that best describes your web application:**
+{{<c/choices https_exposition >}}
+* (https) The web application is reachable exclusively over HTTPS. Even if the user manually edits the URL to start with `http://`, it won't work or it will redirect to `https://`.
+* (http_https) The web application is flexible — users can reach it over HTTP or over HTTPS.
+* (http_only) The web application supports HTTP only, and can't be reached over HTTPS even if you edit the URL.
+{{</c/choices>}}
+
+{{<c/show `{https_exposition} == 'http_https' or {https_exposition} == 'http_only'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+It's often extremely easy for attackers to eavesdrop on packets transmitted between users and web applications (for example, on public Wi-Fi networks). To avoid exposing sensitive data in transit, any application that allows users to log in — or contains anything but public data — should be available solely over HTTPS. It's also fine to use a web server that listens on port 80 (plain HTTP) and redirects users to the SSL version; this method can make it easier for users to access the application.
+\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below.**
+{{<c/text "https_exposition_countermeasures*" multi />}}
+
+{{%/notice%}}
+{{</c/show>}}
+
+{{<c/show `{https_exposition} == 'https' or {https_exposition} == 'http_https'` >}}
+
+### Configuring SSL/TLS
+
+**Have you recently reviewed your SSL configuration to ensure that only secure protocols and ciphers are offered to clients?**
+
+{{<c/choices https_conf >}}
+* (yes) Yes, we regularly review the cipher suite advertised by the server and the protocols it uses.
+* (not_sure) We're not sure whether our SSL/TLS configuration is secure.
+{{</c/choices>}}
+
+{{<c/show `{https_conf} == 'not_sure'` >}}
+{{%notice%}}
+**Tip**\
+\
+Detailed guidance on SSL/TLS and cipher suites is beyond the scope of this questionnaire. A very good and well-maintained resource is [Mozilla's SSL/TLS configuration wiki page](https://wiki.mozilla.org/Security/Server_Side_TLS), which gives up-to-date recommendations for the most common use cases. Another good resource for reviewing the security of your SSL/TLS server is [SSL Labs' server test](https://www.ssllabs.com/ssltest/).
+{{%/notice%}}
+{{</c/show>}}
+
+
+**Does your server offer [forward secrecy](https://en.wikipedia.org/wiki/Forward_secrecy) for clients that support it?**
+
+{{<c/choices https_forward_secrecy >}}
+* (yes) Yes, the server supports ECDHE and DHE ciphers that offer forward secrecy.
+* (no) No, no ciphers providing forward secrecy are enabled.
+{{</c/choices>}}
+{{<c/show `{https_forward_secrecy} == 'no'` >}}
+{{%notice%}}
+**Tip**\
+\
+In ciphers that support forward secrecy, an ephemeral key is negotiated for each connection, using the Diffie-Hellman algorithm. This key is used for a limited period of time, after which it is "forgotten." Even if the private SSL key is later compromised, an attacker who recorded conversations between the server and clients won't be able to decrypt those conversations without also breaking the associated ephemeral keys. Enabling ciphers that offer forward secrecy can protect your users against future disclosure of the information transmitted between them and your server.
+{{%/notice%}}
+{{</c/show>}}
+
+
+**Are your SSL/TLS private keys appropriately protected on your web servers?**
+{{<c/choices https_private_keys >}}
+* (yes) Yes, we have taken all necessary steps to protect our private keys.
+* (no) I'm not sure how well protected they are.
+{{</c/choices>}}
+{{<c/show `{https_private_keys} == 'no'` >}}
+{{%notice%}}
+**Tip**\
+\
+Make sure private SSL/TLS keys are, at a minimum, protected through file system permissions. It's important to make sure the user account that's used to serve web pages does not have access; otherwise, a vulnerability in the web app could easily lead to a compromise of the keys. If you are using an SSL certificate with a wildcard CN (e.g., *.example.net), ensure that the private key is well protected on all the servers it resides on (not just your most important server).
+{{%/notice%}}
+{{</c/show>}}
+
+
+**Where is the SSL connection between the user and your application terminated?**
+{{<c/choices https_termination >}}
+* (appserver) At the application server
+* (loadbalancer) At the load balancer
+* (somewhere) Somewhere else
+{{</c/choices>}}
+
+{{<c/show `{https_termination} == 'somewhere'` >}}
+**Provide more details on the termination point:**
+{{<c/text "https_termination_somewhere_details" multi />}}
+{{</c/show>}}
+
+
+{{<c/show `{https_termination} == 'loadbalancer'` >}}
+**How is traffic between the load balancer and the application servers protected?**
+{{<c/choices https_termination_lb_traffic >}}
+* (encrypted) Traffic is encrypted and certificates between load balancer and application servers are validated.
+* (unencrypted-trusted) Traffic is unencrypted, but all networks transited between load balancers and application servers are owned and exclusively used by us.
+* (unencrypted-untrusted) Traffic is unencrypted, and traffic has to transit through networks not owned and exclusively used by us.
+* (other) Through other means.
+{{</c/choices>}}
+{{</c/show>}}
+
+{{<c/show `{https_termination_lb_traffic} == 'unencrypted-untrusted'` >}}
+{{%notice%}}
+**Tip**\
+\
+Because user traffic appears to transit networks behind your load balancer that are not fully owned and operated by you, we strongly recommend that you establish another SSL/TLS connection between the load balancer and the servers that actually serve the application. Otherwise, an attacker who can listen in on the traffic behind your load balancers will be able to see unencrypted user data.
+{{%/notice%}}
+{{</c/show>}}
+
+{{<c/show `{https_termination_lb_traffic} == 'other'` >}}
+**Describe how the traffic is protected:**
+{{<c/text "https_termination_lb_traffic_details" multi />}}
+{{</c/show>}}
+
+
+
+**Applications served over SSL may still be vulnerable to attacks if resources (often JavaScript, style sheets, or other active content) are included over plain HTTP. This defeats the purpose of SSL, because the active content loaded through plain HTTP will have access to the DOM of content protected by SSL. Make sure no resources are included from plain HTTP sites. Typically, browsers will help identify cases where resources from non-SSL sites are included, by displaying [mixed content](https://developer.mozilla.org/en-US/docs/Security/MixedContent) warnings.**
+
+**To avoid these issues, do you have checks in place to ensure that all references to resources either point to SSL or are protocol-relative?**
+{{<c/choices https_mixedcontent >}}
+* (yes) Yes, we are very careful and have specific controls in place to prevent mixed-content issues.
+* (no) It wouldn't be too difficult for something to fall through the cracks and introduce mixed-content bugs.
+{{</c/choices>}}
+
+{{<c/show `{https_mixedcontent} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Mixed content is a big deal, and it's becoming more problematic as an increasing number of users roam on public Wi-Fi and other insecure networks. We recommend cleaning up your codebase to avoid this kind of issue, and establishing procedures to help guard against new instances.
+\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below.**
+{{<c/text "https_mixedcontent_details*" multi />}}
+{{%/notice%}}
+{{</c/show>}}
+
+
+
+{{</c/show>}} <!-- {https_exposition} == 'https' or {https_exposition} == 'http_https -->
diff --git a/exampleSite/content/checklist/04_authz.md b/exampleSite/content/checklist/04_authz.md
new file mode 100644
index 0000000..bf9b5d6
--- /dev/null
+++ b/exampleSite/content/checklist/04_authz.md
@@ -0,0 +1,119 @@
+---
+hidden: true
+---
+
+**To get started, tell us a little about your application so we can ask you the right questions.**
+{{<c/choices Auths_basic_infos multi >}}
+* (login_required) Our application requires regular users to log in. Most features aren't available without logging in.
+* (isolated_admin_ui) In addition to an interface for regular users, our application provides an administration interface.
+* (rbac_model) Our application features complex user management. Various roles can be assigned to user accounts.
+{{</c/choices >}}
+
+{{<c/show `{Auths_basic_infos} has 'rbac_model'` >}}
+**Briefly describe the different roles your application provides. If your application also offers custom role definitions, be sure to mention that.**
+{{<c/text "Auths_rbac_details" multi />}}
+{{</c/show >}}
+
+
+
+
+{{<c/show `{Auths_basic_infos} has 'login_required' or {Auths_basic_infos} has 'isolated_admin_ui'` >}}
+**Is your application integrated with any of the following single sign-on (SSO) mechanisms?**
+{{<c/choices Auths_sso_mechanisms multi >}}
+* (SAML2) SAML 2.0
+* (OpenIDConnectOAuth2) OpenID Connect / OAuth2 Login
+* (OpenID2) OpenID 2.0
+* (LDAP) LDAP / Active Directory
+* (other) Other
+* (none) None of the above
+{{</c/choices >}}
+
+{{<c/show `{Auths_sso_mechanisms} has 'other'` >}}
+**What other SSO mechanisms does the application support?**
+{{<c/text "Auths_sso_other_details" multi />}}
+{{</c/show >}}
+
+{{<c/show `{Auths_sso_mechanisms} has 'OpenID2' and !({Auths_sso_mechanisms} has 'OpenIDConnectOAuth2')` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+OpenID 2.0 has been replaced by OpenID Connect (also called OAuth2 Login). We recommend updating your application's SSO integration to support OpenID Connect.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{Auths_sso_mechanisms} has 'LDAP'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Integrating with LDAP and/or Active Directory has a significant downside: any application that integrates with it has to receive the user's SSO password. As a result, a vulnerability in any integrated application puts the password at risk for all other applications. We recommend using an SSO mechanism that does not require the password to be sent anywhere other than a central authentication system.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{Auths_sso_mechanisms} has 'OpenIDConnectOAuth2'` >}}
+### OAuth2 Login
+{{%include 04_authz_OAuth2Login.md%}}
+{{</c/show >}}
+
+
+
+
+
+**Does any part of the application employ username/password-based authentication?**
+{{<c/choices Auths_handle_password >}}
+* (yes) Yes
+* (no) No, all authentication is based on single sign-on (SSO).
+{{</c/choices >}}
+
+{{<c/show `{Auths_handle_password} == 'yes'` >}}
+### Username/Password Authentication
+{{%include 04_authz_UsernamePasswordAuthentication.md%}}
+{{</c/show >}} <!-- `{Auths_handle_password} == 'yes'`s -->
+
+{{</c/show >}} <!-- `{Auths_basic_infos} has 'login_required' or {Auths_basic_infos} has 'isolated_admin_ui'` -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{<c/show `{Auths_basic_infos} has 'login_required' or {Auths_basic_infos} has 'isolated_admin_ui' ` >}}
+### Authentication Cookies and Sessions
+{{%include 04_authz_AuthenticationCookiesandSessions.md%}}
+{{</c/show >}}
+
+
+
+
+{{<c/show `{Auths_basic_infos} has 'login_required' or {Auths_basic_infos} has 'isolated_admin_ui' ` >}}
+### Authorization
+{{%include 04_authz_Authorization.md%}}
+{{</c/show >}}
+
+
+
+
+
+
+{{<c/show `{Auths_basic_infos} has 'login_required' or {Auths_basic_infos} has 'isolated_admin_ui' ` >}}
+### Authorization-Related Web Vulnerabilities
+{{%include 04_authz_AuthorizationRelatedWebVulnerabilities.md %}}
+{{</c/show >}} <!-- Authorization-Related Web Vulnerabilities -->
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md b/exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md
new file mode 100644
index 0000000..38c07b6
--- /dev/null
+++ b/exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md
@@ -0,0 +1,104 @@
+---
+hidden: true
+---
+**Cookies can be decorated with a special keyword, `HttpOnly`. If this keyword is set, the browser will not allow JavaScript to access the cookie. Even if the application has a cross-site scripting vulnerability, this keyword makes it much harder for an attacker to steal the session cookie.**
+
+{{<c/choices auths_cookies_sessions_httponly >}}
+* (handled) The `HttpOnly` keyword is set for all our authentication cookies.
+* (no) Our application does not make use of this defense-in-depth mechanism.
+{{</c/choices >}}
+
+{{<c/show `{auths_cookies_sessions_httponly} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Setting the `HttpOnly` attribute is a very simple defense-in-depth mechanism. We highly recommended making use of it.
+\
+**If there are specific reasons why this is not possible in your case please explain below**
+{{<c/text "auths_cookies_sessions_httponly_why" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+**Session IDs can be constructed in many ways. Select the methods used in your application:**
+{{<c/choices auths_cookies_sessions_id multi >}}
+* (framework) The web application framework we use has a built-in session ID mechanism.
+* (randomalphanum) Our session IDs are randomly generated strings or numbers.
+* (signedcookie) We store a signed token as a cookie to indicate that the user is successfully logged in.
+* (other) We use some other mechanism.
+{{</c/choices >}}
+
+{{<c/show `{auths_cookies_sessions_id} has 'other'` >}}
+**Describe the mechanism you're using**
+{{<c/text "auths_cookies_sessions_id_no_details" multi />}}
+{{</c/show >}}
+
+{{<c/show `{auths_cookies_sessions_id} has 'framework'` >}}
+**What's the name of the framework that generates your session IDs**
+{{<c/text "auths_cookies_sessions_id_framework_name" />}}
+{{</c/show >}}
+
+{{<c/show `{auths_cookies_sessions_id} has 'randomalphanum' or {auths_cookies_sessions_id} has 'signedcookie'` >}}
+**Do sessions automatically time out after a specified period of inactivity**
+{{<c/choices auths_cookies_sessions_timeout >}}
+* (yes) Yes
+* (no) No
+{{</c/choices >}}
+
+{{<c/show `{auths_cookies_sessions_timeout} == 'yes' or {auths_cookies_sessions_id} has 'framework'` >}}
+**How long is the session timeout?**
+{{<c/text "application_auth_cookies_timeout_length" />}}
+{{</c/show >}}
+
+{{</c/show >}}
+
+{{<c/show `{auths_cookies_sessions_timeout} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+If you don't specify a session timeout, an attacker who has stolen a session ID once will have a permanent back door to the application. Be sure to implement a timeout — even if it's fairly long, it's still better than no timeout at all).
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "auths_cookies_sessions_timeout_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+{{<c/show `{auths_cookies_sessions_id} has 'randomalphanum'` >}}
+**Does the application use a secure [cryptographic pseudo random number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator#Cryptographically_secure_pseudorandom_number_generators) (PRNG) to generate session IDs? The PRNG should not allow the state of the generator to be recalculated from its output, and the entropy of the session ID should be sufficient to make brute-forcing infeasible.**
+{{<c/choices auths_cookies_sessions_prng >}}
+* (yes) Yes, we use a PRNG that meets these criteria
+* (no) No, we don't use a PRNG, or our PRNG doesn't meet these criteria.
+{{</c/choices >}}
+
+{{<c/show `{auths_cookies_sessions_prng} == 'no'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+If you're not using a cryptographic PRNG, an attacker can recalculate the state of the generator in order to guess subsequent session IDs and steal those users' sessions. Many programming languages already have a secure PRNG built in (e.g., Java has `java.security.SecureRandom`; C# has `System.Security.Cryptography.RNGCryptoServiceProvider`; Python has `os.urandom`), and in most cases it is as easy to use as a less secure option.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "auths_cookies_sessions_prng_no_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+{{</c/show >}}
+
+
+**Does your application offer a "log out" button or link that, when clicked, not only terminates the session (deletes cookies from the client) but also invalidates the entire session ID?**
+{{<c/choices auths_cookies_sessions_logoutexists >}}
+* (yes) Yes
+* (no) No
+{{</c/choices >}}
+
+{{<c/show `{auths_cookies_sessions_logoutexists} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Unless sessions are invalidated on logout, an attacker who has stolen a session ID will have access to the user's data until the session expires. Make sure all logout actions invalidate the session ID.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "auths_cookies_sessions_logoutexists_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}} \ No newline at end of file
diff --git a/exampleSite/content/checklist/04_authz_Authorization.md b/exampleSite/content/checklist/04_authz_Authorization.md
new file mode 100644
index 0000000..13df6ae
--- /dev/null
+++ b/exampleSite/content/checklist/04_authz_Authorization.md
@@ -0,0 +1,44 @@
+---
+hidden: true
+---
+In most applications, certain information should only be accessible to certain users. For example, in most applications that require authentication, only the currently logged-in user should be able to change master data (such as the username, the associated email address, or the account password). When an application has data that should not be available to other users or should be restricted to certain roles, authorization must be enforced on the server side.
+
+
+**Horizontal Access Control: Horizontal access control refers to isolation between users of the same role. For example, consider an application that allows users to access their payroll statements. The application must ensure that a user cannot access another user's statements; i.e., if the user's statement for the month of May is found at `statement.html?id=8372&month=5`, it shouldn't be possible to see someone else's pay stub simply by loading `statement.html?id=8373&month=5`.**
+{{<c/choices auths_authorization_isolation_data >}}
+* (handled) Our application enforces these restrictions on the server side. We have processes in place to make sure nothing slips through the cracks.
+* (no) It's possible that we missed checks like this in a few places.
+{{</c/choices >}}
+
+{{<c/show `{auths_authorization_isolation_data} == 'no'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Applications must have controls in place that help protect all data from unauthorized access. We recommend that you thoroughly audit your code for vulnerabilities resulting from inadequate access control.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "auths_authorization_isolation_data_no_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+
+**Vertical Access Control: When an application supports multiple roles, users should not be able to gain privileges or perform unauthorized actions by loading pages or features that should only be available to users in a different role. Throughout your application, have you ensured that users can perform only those actions that are appropriate for their roles?**
+{{<c/choices auths_authorization_isolation_features >}}
+* (handled) Our application enforces these restrictions on the server side. We have processes in place to make sure nothing slips through the cracks.
+* (no) It's possible that we missed checks like this in a few places.
+{{</c/choices >}}
+
+{{<c/show `{auths_authorization_isolation_features} == 'no'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Applications must have controls in place that protect all functionality from unauthorized access. We recommend that you thoroughly audit your code for vulnerabilities resulting from inadequate access control.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "auths_authorization_isolation_features_no_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
diff --git a/exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md b/exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md
new file mode 100644
index 0000000..c0c4512
--- /dev/null
+++ b/exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md
@@ -0,0 +1,123 @@
+---
+hidden: true
+---
+#### Cross Site Request Forgery
+Applications must protect all state-changing actions against cross-site request forgery (XSRF). In this attack, a malicious user forces the victim to send a request to the application, for example by luring the user to a page under the attacker's control. Because the browser automatically attaches available authentication cookies, the request will appear to be authorized if the user is logged in to the application.
+
+For example, consider an online banking application that allows users to transfer money to another account. The URL for transfers might look something like this:
+
+`https://www.example.com/bank-transfer.html?dest_account=123456&amount=99.90&submit=true`
+
+If an attacker manages to lure the victim to a malicious site, the site could include HTML that causes such a request to be sent:
+
+`<img src="https://www.example.com/bank-transfer.html?dest_account=666&amount=99.90& submit=true">`
+
+If the user is logged in to the online banking portal, the application will receive that request and check for authentication cookies — which will be present, since the request was sent from the authorized user's browser.
+
+**Does your application protect all state-changing actions against XSRF?**
+{{<c/choices auths_authorization_XSRF >}}
+* (yes) Yes, all state-changing actions are protected. We have a way to ensure that no actions are missed (such as enforcing XSRF-token checks in a central place).
+* (no) Some actions might not be protected against XSRF.
+{{</c/choices >}}
+
+{{<c/show `{auths_authorization_XSRF} == 'no'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Web applications used to process private or confidential information should protect against XSRF. We recommend that you thoroughly audit your code for XSRF vulnerabilities, and put procedures in place so that future code is also protected.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "auths_authorization_XSRF_no_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{auths_authorization_XSRF} == 'yes'` >}}
+**What strategy do you use to protect against XSRF?**
+{{<c/choices auths_authorization_XSRF_strategy >}}
+* (token) We protect requests that change the state with tokens that are bound to the user they were generated for, and that expire after a certain amount of time.
+* (header) We use a custom fixed header that we add to requests.
+* (post) The application does one of the following: verifies the referrer header; requires all state-changing actions to be POST requests; employs another mechanism to protect against XSRF
+{{</c/choices >}}
+{{</c/show >}}
+
+{{<c/show `{auths_authorization_XSRF_strategy} == 'header'` >}}
+{{%notice%}}
+**Tip**\
+\
+Various browser plugins (such as Flash and Java) have had security vulnerabilities that allowed an attacker to set arbitrary custom headers on cross-domain requests. We highly recommend the use of tokens instead of headers.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{auths_authorization_XSRF_strategy} == 'post'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Unfortunately, using POST requests does not protect against XSRF. Attackers can perform cross-domain POST requests by submitting a form with the appropriate `action` parameter, via JavaScript. Referrer checks are similarly ineffective because attackers can get around them through open redirects.\
+\
+**If you are using an alternative, effective method to protect against XSRF, describe it:**
+{{<c/text "auths_authorization_XSRF_no_alternative" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+
+
+
+
+#### Cross-Site Script Inclusion
+**Many web applications use AJAX to exchange data in the background, using a syntax that can be automatically interpreted as JavaScript by the user's browser. Unfortunately, this leads to [cross-site script inclusion](http://capec.mitre.org/data/definitions/111.html) (XSSI) vulnerabilities: the JavaScript can be included from a different origin, and any variables set at the other origin can be read.**
+
+For example, consider a contact management application that transmits the user's contacts in a JSON file (contacts.js):
+
+`var contacts = {"name": "John Doe", "address": "jdoe@example.com", ... }`
+
+An attacker can include the following script from their own site, so that when the user visits the attacker's site while logged in to the contact management application, the attacker can read the variable contacts and get access to all of the victim's contact information.
+
+`<script src="http://www.example.com/contacts.js"></script>`
+
+**Do either of the following statements describe your application?**
+{{<c/choices auths_authorization_XSSI multi >}}
+* (jsonp) Our application makes use of [JSONP](http://en.wikipedia.org/wiki/JSONP).
+* (no) Our application uses another format that sets variables or calls functions with non-public information.
+{{</c/choices >}}
+
+{{<c/show `{auths_authorization_XSSI} has 'no'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Web applications that transmit private information must be protected against XSSI, to prevent attackers from stealing the private data.\
+\
+**If you are using an alternative, effective method to protect against XSSI, describe it:**
+{{<c/text "auths_authorization_XSSI_no_alternative" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+
+
+#### Clickjacking
+**Depending on the nature of your application and the actions that can be taken in it, you may need to protect against [clickjacking](https://www.owasp.org/index.php/Clickjacking).**
+
+**If you don't typically need to frame web pages, your application should use the [X-Frame-Options response header](https://developer.mozilla.org/en/the_x-frame-options_response_header) to tell the browser not to render any page that's framed from a different origin:**
+
+`X-Frame-Options: SAMEORIGIN`
+
+{{<c/choices auths_authorization_clickjacking >}}
+* (handled) Our application employs protections against clickjacking (such as using the `X-Frame-Options` header).
+* (no) Our application does not have such protections.
+{{</c/choices >}}
+
+{{<c/show `{auths_authorization_clickjacking} has 'no'` >}}
+{{%notice%}}
+**Tip**\
+\
+Clickjacking is difficult to address. But in high-risk applications, clickjacking protection is essential.\
+\
+**Explain why you consider clickjacking protection unnecessary**
+{{<c/text "auths_authorization_clickjacking_no_details" multi />}}
+{{%/notice%}}
+{{</c/show >}} \ No newline at end of file
diff --git a/exampleSite/content/checklist/04_authz_OAuth2Login.md b/exampleSite/content/checklist/04_authz_OAuth2Login.md
new file mode 100644
index 0000000..850e23e
--- /dev/null
+++ b/exampleSite/content/checklist/04_authz_OAuth2Login.md
@@ -0,0 +1,31 @@
+---
+hidden: true
+---
+
+**Implementing OAuth2 Login / OpenID Connect from scratch is fairly complex and error-prone, and mistakes can result in security vulnerabilities. Select the option that best describes your implementation:**
+{{<c/choices Auths_oauth2_impl >}}
+* (very_secure) Very secure: We're using a standard OAuth2 library, and we update it when security fixes are released.
+* (secure) Secure: We implemented OAuth2 on our own, but our employees are experts and we're convinced that it is implemented securely.
+* (own_impl) Not sure: We implemented OAuth2 on our own, and it seemed simple at the time. I'm not sure about the security of our implementation
+{{</c/choices >}}
+
+
+{{<c/show `{Auths_oauth2_impl} == 'secure'` >}}
+{{%notice%}}
+**Tip**\
+\
+If your employees really are OAuth2 experts, you're probably fine. But note that even standard libraries have had vulnerabilities due to the intricacies of the standard. Be sure to ask your penetration testing provider to take a look at the OAuth2 implementation.
+{{%/notice%}}
+{{</c/show>}}
+
+
+{{<c/show `{Auths_oauth2_impl} == 'own_impl'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Implementing OAuth2 on your own is extremely dangerous. Even the experts on the OAuth2 standards panel concluded that the only way to securely implement it is through a well-known and well-tested library. Some of these libraries are very easy to use (e.g., the [Google Identity Toolkit](https://developers.google.com/identity/toolkit/)), so replacing your custom implementation should be feasible.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "Auths_oauth2_impl_compensatingcontrols" multi />}}
+{{%/notice%}}
+{{</c/show >}} \ No newline at end of file
diff --git a/exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md b/exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md
new file mode 100644
index 0000000..74f5679
--- /dev/null
+++ b/exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md
@@ -0,0 +1,142 @@
+---
+hidden: true
+---
+**What username/password-based logins does the application use? For example, if there's a separate administrator authentication, mention that.**
+{{<c/text "Auths_handle_password_details" multi />}}
+
+**Does your application allow users to change their passwords?**
+{{<c/choices Auths_handle_password_allowusechange >}}
+* (yes) Yes
+* (no) No
+{{</c/choices >}}
+{{<c/show `{Auths_handle_password_allowusechange} == 'no'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Allowing users to change their passwords is important. A user might be recovering from a compromise, or might have accidentally typed the password elsewhere.
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "Auths_handle_password_allowusechange_compensatingcontrols" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+**Does the application enforce minimum password security requirements (e.g., a certain length, character classes, etc.)?**
+{{<c/choices Auths_handle_password_policyenforced >}}
+* (yes) Yes
+* (no) No
+{{</c/choices >}}
+{{<c/show `{Auths_handle_password_policyenforced} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Please help protect users from themselves by enforcing certain minimum password requirements. It's up to you to determine the details of these requirements, but they should account for the sensitivity of the information and should conform to industry standards.
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "Auths_handle_password_policyenforced_compensatingcontrols" multi />}}
+{{%/notice%}}
+{{</c/show>}}
+
+
+
+
+#### Password Storage
+**How does the application store passwords?**
+{{<c/choices Auths_handle_password_storage >}}
+* (plaintext) In plain text (unencrypted)
+* (reversible) Using reversible encryption (e.g., DES, 3DES, AES, etc.).
+* (hashnosalted) Using a secure cryptographic one-way hash function (such as SHA-256) of the password, without the use of a salt
+* (hashsalted) Using a secure cryptographic one-way hash function (such as SHA-256) of the salted password
+* (keyderivationcypher) Using a dedicated password-based key derivation function, such as bcrypt, PBKDF2 or scrypt
+* (none) None of the above
+{{</c/choices >}}
+
+{{<c/show `{Auths_handle_password_storage} == 'none'` >}}
+**Explain how your application stores passwords:**
+{{<c/text "Auths_handle_password_storage_details" multi />}}
+{{</c/show>}}
+
+{{<c/show `{Auths_handle_password_storage} == 'plaintext' or {Auths_handle_password_storage} == 'reversible' or {Auths_handle_password_storage} == 'hashnosalted'` >}}
+{{%alert danger%}}**Warning — possible critical-risk issue**{{%/alert%}}
+{{%notice danger%}}
+Passwords should be stored in such a way that the original passwords cannot be easily recovered, even if an attacker manages to get access to the storage location (e.g., through a SQL injection vulnerability). At a minimum, passwords should be secured using a cryptographic one-way hash function and a salt. We strongly recommended using password-based key derivation function like bcrypt PBKDF2 or scrypt instead; they were specifically designed for this use case and make it significantly harder for attackers to crack password hashes.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "Auths_handle_password_allowusechange_compensatingcontrols" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+
+
+
+#### Setting an Initial Password
+**How do users get their initial passwords?**
+{{<c/choices Auths_handle_password_init_process >}}
+* (selfset) Users self-register and set their passwords online directly within the application.
+* (linktoset) The initial password or a link to set the initial password is sent to users by email.
+* (physical) The initial password is provided in a (physical) letter sent to a verified address.
+* (none) None of the above.
+{{</c/choices >}}
+
+{{<c/show `{Auths_handle_password_init_process} == 'none'` >}}
+**Explain how users get their initial passwords:**
+{{<c/text "Auths_handle_password_init_process_details" multi />}}
+{{</c/show>}}
+
+{{<c/show `{Auths_handle_password_init_process} == 'linktoset'` >}}
+{{%notice%}}
+**Tip**\
+\
+If passwords are sent by email, make sure users are required to change their initial passwords when they first log in.
+{{%/notice%}}
+{{</c/show>}}
+
+
+**When the user gets their initial password, will their account be prepopulated with any confidential information? For example, in an online payroll portal, a user can typically access previous pay statements even when the account is brand new.**
+{{<c/choices Auths_handle_password_init_dataavailable >}}
+* (yes) Yes, when users log in for the first time, confidential information will already be present.
+* (no) No, at the initial login, no confidential information will be available to the user.
+{{</c/choices >}}
+
+
+
+
+#### Account Recovery
+**When the user gets their initial password, will their account be prepopulated with any confidential information? For example, in an online payroll portal, a user can typically access previous pay statements even when the account is brand new.**
+{{<c/choices Auths_handle_password_recovery multi >}}
+* (questions) The user is asked questions that were set up when the account was created.
+* (resetlink) A password reset link is sent via email to the user's registered email address.
+* (newpassbymail) A new password is sent via email to the user's registered email address.
+* (none) None of the above.
+{{</c/choices >}}
+
+{{<c/show `{Auths_handle_password_recovery} has 'none'` >}}
+**Describe your password recovery mechanism:**
+{{<c/text "Auths_handle_password_recovery_details" multi />}}
+{{</c/show>}}
+
+{{<c/show `{Auths_handle_password_recovery} has 'questions' and !({Auths_handle_password_recovery} has 'resetlink') and !({Auths_handle_password_recovery} has 'newpassbymail') ` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Recovery questions alone should not be sufficient for resetting a password. The answers to these questions are often not as secret as they might seem; in particular, friends and family can often easily guess the answers.
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+\
+{{<c/text "Auths_handle_password_recovery_questions_compensatingcontrols" multi />}}
+{{%/notice%}}
+{{</c/show>}}
+
+{{<c/show `{Auths_handle_password_recovery} has 'newpassbymail'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Sending passwords by email is rarely a good idea. Email is generally unencrypted, so it should not be used for sensitive information. Instead, we recommend sending a token that can be used to set the actual password. Although an attacker with the token could still reset the password, the user would at least become aware of the reset when they later attempted to log in.
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "Auths_handle_password_recovery_email_compensatingcontrols" multi />}}
+{{%/notice%}}
+{{</c/show>}}
+
diff --git a/exampleSite/content/checklist/05_commonvuln.md b/exampleSite/content/checklist/05_commonvuln.md
new file mode 100644
index 0000000..9073924
--- /dev/null
+++ b/exampleSite/content/checklist/05_commonvuln.md
@@ -0,0 +1,81 @@
+---
+hidden: true
+---
+
+**Certain features can result in security issues, if used incorrectly. To help us identify potential issues, select the statements that describe your application:**
+{{<c/choices webvuln multi >}}
+* (db) The application uses a database back end, or any other persistence back end that can be queried with SQL or a related language (e.g., GQL, FQL, SOQL, etc.).
+* (plugin) The application requires a plugin, such as Java, Flash, Silverlight, etc.
+* (upload) The application has a file upload feature.
+* (3rdpartycontent) The application loads active content, such as scripts, applets, or style sheets, from third-party servers (i.e., any server that is not under your direct control).
+* (xml) The application processes or manipulates user-provided XML.
+* (crypto) The application uses cryptography to encrypt data or protect its integrity.
+{{</c/choices >}}
+
+{{<c/show `{webvuln} has '3rdpartycontent'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Loading content from other sites is dangerous under certain circumstances; security issues in the other sites might also affect the security of your application. Scripts, for example, have full access to the DOM of the site on which they're included — so if one of the servers that hosts your third-party JavaScript gets compromised, the attacker also gains access to all of your users' data, simply by injecting a bit of code.\
+\
+Unless you trust the third party completely (not only to not do something malicious, but also to be secure enough to adequately protect their infrastructure against attackers), it's best not to load scripts or style sheets (e.g., via `<script src=...>` or `<style src=...>`) from third-party sites.\
+\
+Similarly (although to a lesser extent), directly embedding videos, frames, or images (including advertisements, tracking pixels, etc.) from third-party sources can be dangerous. Loading such a resource can leak information to the site it's loaded from (e.g., through the referrer). This can be a privacy issue as well as a security issue.\
+\
+\
+\
+**If your application loads third-party content, describe your threat model:**
+{{<c/text "webvuln_3rdpartycontent_details" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln} has 'xml'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Dealing with user-provided and untrusted XML may make your application vulnerable to attacks. For example, the expat XML parser (written in C) has been found vulnerable to buffer overflow attacks. Even if you use a secure parser (or run it in a sandbox), things that can go wrong.\
+\
+Various attacks rely on the attacker's ability to specify XML entities. Entities are "codes" (such as `&quot;`) that are translated into defined strings by the parser. HTML has a predefined set of entities, but in XML, entities can be specified arbitrarily. An entity specification usually looks like this:\
+\
+`<!ENTITY ent "Hello!">`\
+\
+With this definition, whenever the parser comes across `&ent;`, it will replace it with `Hello!`. Entities are usually defined in the document type, which can be provided in a separate file or in the `<!DOCTYPE>` section at the beginning of an XML document.Entities are used in a variety of XML-related attacks. For example, they can be used for something called the [billion laughs attack](http://www.ibm.com/developerworks/xml/library/x-tipcfsx/index.html), where an entity resolves to other entities, which resolve to other entities, etc., causing high memory usage and essentially resulting in a denial-of-service attack.\
+\
+Even more serious is an attack using [external entities](http://www.securiteam.com/securitynews/6D0100A5PU.html). Definitions of external entities look similar to regular entity definitions, but they reference local files or URLs. Unless the XML parser has been specifically instructed not to expand external entities, a definition like `<!ENTITY etc SYSTEM "file:///etc/passwd">` would include the /etc/passwd file where the entity `&etc;` occurs in the XML document, leading to the disclosure of files as well as internal URLs.It's very important to restrict entity specification in user-provided or untrusted XML. Make sure your parser is adequately configured.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "webvuln_xml_compensating_controles" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+
+### Cross-Site Scripting
+{{%include 05_commonvuln_CrossSiteScripting.md%}}
+
+{{<c/show `{webvuln} has 'db'` >}}
+### Persistence Back Ends and Querying
+{{%include 05_commonvuln_PersistenceBackEndsandQuerying.md%}}
+{{</c/show >}}
+
+
+{{<c/show `{webvuln} has 'plugin'` >}}
+### Browser Plugins
+{{%include 05_commonvuln_BrowserPlugins.md%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln} has 'upload'` >}}
+### File Uploads
+{{%include 05_commonvuln_FileUploads.md%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln} has 'crypto'` >}}
+### Use of Cryptography
+{{%include 05_commonvuln_UseofCryptography.md%}}
+{{</c/show >}}
+
+
+
+
diff --git a/exampleSite/content/checklist/05_commonvuln_BrowserPlugins.md b/exampleSite/content/checklist/05_commonvuln_BrowserPlugins.md
new file mode 100644
index 0000000..a313e63
--- /dev/null
+++ b/exampleSite/content/checklist/05_commonvuln_BrowserPlugins.md
@@ -0,0 +1,49 @@
+---
+hidden: true
+---
+**You mentioned that your application requires certain browser plugins to work correctly. Which of the following plugins are required?**
+{{<c/choices webvuln_plugin multi >}}
+* (java) Java
+* (flash) Flash
+* (silverlight) Silverlight
+* (other) Other
+{{</c/choices >}}
+
+{{<c/show `{webvuln_plugin} has 'other'` >}}
+**What other plugins are required by your application?**
+{{<c/text "webvuln_plugin_other" />}}
+{{</c/show >}}
+
+
+{{<c/show `{webvuln_plugin} has 'other'` >}}
+**Explain what the plugin is used for, what technology it uses (e.g., ActiveX, NPAPI, Chrome plugin, etc.), how it is usually deployed to your users, and what privileges it requires:**
+{{<c/text "webvuln_plugin_other_details" multi />}}
+{{</c/show >}}
+
+
+{{<c/show `{webvuln_plugin} has 'java'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Enabling Java in the browser exposes users to a variety of security issues. We strongly discourage requiring Java.\
+\
+**Is Java absolutely necessary for your application to function correctly? Are there any workarounds ?**
+{{<c/text "webvuln_plugin_java_workarounds" multi />}}
+{{%/notice%}}
+
+
+{{</c/show >}}
+
+
+{{<c/show `{webvuln_plugin} has 'other'` >}}
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+In most cases, custom plugins are considered a security risk. Plugins can operate outside of the usual constraints (such as a same-origin policy, sandboxing, etc.) and can introduce security vulnerabilities that affect the entire browser. It's also often difficult to deploy and centrally manage them. We strongly discourage using custom plugins.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "webvuln_plugin_other_conpensating_controls" multi />}}
+{{%/notice%}}
+
+{{</c/show >}}
+
diff --git a/exampleSite/content/checklist/05_commonvuln_CrossSiteScripting.md b/exampleSite/content/checklist/05_commonvuln_CrossSiteScripting.md
new file mode 100644
index 0000000..14c26b7
--- /dev/null
+++ b/exampleSite/content/checklist/05_commonvuln_CrossSiteScripting.md
@@ -0,0 +1,136 @@
+---
+hidden: true
+---
+
+
+[Cross-site scripting](https://www.owasp.org/index.php/XSS) (or XSS for short) occurs when an application redisplays insufficiently sanitized user input in the context of the application's origin (as defined by the [same-origin policy](http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy)).
+If the user input contains certain kinds of scripting code, it may read or alter the DOM of the current page when redisplayed.\
+In many cases, XSS is used to steal users' cookies or other application-related data, but it may also be used for phishing attacks, or even to deface the web page. \
+Unfortunately, XSS is one of the most common security issues in web applications, and due to browser quirks and other factors, quite hard to protect against.
+
+**Select the statements that describe your strategy:**
+{{<c/choices webvuln_xss_strategies multi >}}
+* (templating) We use a templating system that automatically escapes all user input before redisplaying it.
+* (chokepoint) Our application has a central choke point where all user input is validated and escaped, depending on the context in which it will be interpreted.
+* (perpage) Some of the pages (or all of them) escape user input.
+* (other) We are using some other technique to protect against XSS.
+* (sanitization) Part of the application deals with user-provided HTML that is sanitized and re-displayed to the user.
+{{</c/choices >}}
+
+{{<c/show `!({webvuln_xss_strategies} has 'templating') and !({webvuln_xss_strategies} has 'chokepoint') and !({webvuln_xss_strategies} has 'perpage') and !({webvuln_xss_strategies} has 'other') and !({webvuln_xss_strategies} has 'sanitization')` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+You didn't select a strategy for protecting against cross-site scripting.\
+\
+**Explain why:**
+{{<c/text "webvuln_xss_strategies_no_details" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_xss_strategies} has 'templating'` >}}
+{{%notice%}}
+**Tip**\
+\
+Using a templating system to escape user input is a good way to protect against XSS. But be careful with directives that disable automatic escaping, and watch for the direct display of user input (for example, in error messages). Additionally, be aware of the context in which user input is used in templates. Not all templating systems automatically understand that different escaping may be required, depending on where in the application the user input is displayed. For example, many templating systems would not correctly escape a construct such as `&gt;a href=\"{{ user_input }}\"&lt;`, where a user could supply `javascript:alert(/xss/)` as user_input. We recommend using a context-sensitive templating system.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_xss_strategies} has 'chokepoint'` >}}
+{{%notice%}}
+**Tip**\
+\
+A central choke point for validating and escaping user input is generally a good way to protect against XSS. But make sure your application identifies the context in which the user input is being used; otherwise, it might still be possible to smuggle in JavaScript through user input. You might also want to consider using a context-sensitive templating system, to address this issue automatically.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_xss_strategies} has 'perpage' and !({webvuln_xss_strategies} has 'templating') and !({webvuln_xss_strategies} has 'chokepoint')` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Escaping user input on each page individually is a fairly dangerous strategy: it's very easy to miss something. We recommend using a templating system that automatically escapes user input, ideally in a context-sensitive fashion. Some examples are listed below. Note that not all of these are context-sensitive, so you may still need to do manual escaping (or explicitly tag a variable in the template) when the context is something other than HTML.\
+* [Django](https://www.djangoproject.com/) (Python)
+* [Google](http://code.google.com/p/ctemplate/?redir=1) CTemplates (C++)
+* [Jsilver](http://code.google.com/p/jsilver/) (Java)
+* [Closure/Soy](https://developers.google.com/closure/templates/) (Javascript, Java)
+* [JQuery](http://jquery.com/) (JavaScript)
+* [Smarty](http://www.smarty.net/) (PHP)
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_xss_strategies} has 'other'` >}}
+**Describe your strategy for protecting against XSS vulnerabilities:**
+{{<c/text "webvuln_xss_strategies_other_details" multi />}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_xss_strategies} has 'sanitization'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Unfortunately, due to error-correcting behavior and browser quirks, getting HTML sanitization right is very difficult. The sanitization code has to build an in-memory representation of the DOM, and then serialize that to a known-safe format. Some libraries do this correctly, so we highly recommended using a well-tested library.\
+\
+**Describe how your application deals with HTML sanitization:**
+{{<c/text "webvuln_xss_strategies_sanitization_details" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+**In addition to applying the strategies you've identified, does the application set a valid and appropriate content type and character set for each page (in the `Content-Type` HTTP header)?**
+{{<c/choices webvuln_xss_content_type >}}
+* (handled) Yes, we take great care to set this, knowing that otherwise we might be introducing XSS vulnerabilities.
+* (no) I'm not sure all pages set an appropriate content type.
+{{</c/choices >}}
+
+{{<c/show `{webvuln_xss_content_type} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Not setting both a content type and a character set often leads to cross-site scripting vulnerabilities. For example, if the application outputs JSON but sets the content type to text/html, this might result in XSS because JavaScript/JSON escaping is different from HTML escaping. We recommend that you thoroughly audit your code for pages that don't set the content type correctly.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "webvuln_xss_content_type_no_details" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln} has 'upload'` >}}
+**Earlier, you noted that the application has a file upload feature. Does the application allow other users (or administrators) to access the files that are uploaded?**
+{{<c/choices webvuln_xss_fileupload >}}
+* (yes) Yes, this is a feature of our application.
+* (no) No, uploaded files are processed but can't be downloaded again.
+{{</c/choices >}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_xss_fileupload} == 'yes'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Hosting and serving user-provided content is almost guaranteed to introduce XSS vulnerabilities. Because of various browser quirks, countermeasures (such as setting a `Content-Disposition: attachment` header) do not provide full protection. We recommend serving user-provided content on a domain separate from all domains that have authentication cookies. However, this approach introduces another problem, if access to the content is intended to be authenticated. You can solve this by using short-lived random tokens, or by serving each document from a separate domain. If you use the latter approach, each domain should have a unique set of authentication cookies, valid only for the one document that's served from the domain.\
+\
+**Describe your strategy for protecting against XSS vulnerabilities introduced by serving user-provided content:**
+{{<c/text "webvuln_xss_fileupload_yes_details" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+
+**Some XSS vulnerabilities work exclusively on the client side, in an application's scripting code. This kind of XSS is commonly referred to as [DOM-based XSS](https://www.owasp.org/index.php/DOM_Based_XSS). Because server-side escaping of user input does not protect against DOM-based XSS, you need a strategy for dealing with client-side scripting code that handles user input, as well as parts of the DOM that may contain user input (such as document.location).**
+{{<c/choices webvuln_xss_dombased >}}
+* (handled) We know about DOM-based XSS, and we take specific steps to protect against this kind of vulnerability.
+* (no) It may be possible that something slipped through the cracks and our application has DOM-based XSS vulnerabilities.
+{{</c/choices >}}
+
+{{<c/show `{webvuln_xss_dombased} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+We recommend that you thoroughly audit your code for DOM-based XSS vulnerabilities, and put procedures in place so that future code is also protected.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "webvuln_xss_dombased_no_details" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
diff --git a/exampleSite/content/checklist/05_commonvuln_FileUploads.md b/exampleSite/content/checklist/05_commonvuln_FileUploads.md
new file mode 100644
index 0000000..521cb29
--- /dev/null
+++ b/exampleSite/content/checklist/05_commonvuln_FileUploads.md
@@ -0,0 +1,109 @@
+---
+hidden: true
+---
+
+**You mentioned previously that your application allows users to upload files. Where does the application store those files?**
+
+{{<c/choices webvuln_upload_storage >}}
+* (fs) On the file system
+* (db) In a database
+* (other) Somewhere else
+{{</c/choices >}}
+
+{{<c/show `{webvuln_upload_storage} == 'other'` >}}
+**Explain where the uploaded files are stored:**
+{{<c/text "webvuln_upload_storage_other_details" multi />}}
+{{</c/show >}}
+
+
+{{<c/show `{webvuln_upload_storage} == 'fs'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Storing uploaded files on the file system can be dangerous. Here are a few issues that can occur:\
+\
+* Path traversal: The names of uploaded files must be carefully sanitized to prevent attackers from uploading files with paths in the name, such as `../../../../some_existing_file.html`. Files like these can end up in the wrong directory.
+* Null bytes: The names of uploaded files must be examined for null bytes, which can cause file names to be truncated (e.g., a file called `evilfile.exe[0x00].gif` might become `evilfile.exe` when stored on disk).
+* Interpretation: Files on the file system are much more likely to end up being interpreted. For example, if an attacker manages to store an uploaded file somewhere underneath the web root and names it `evilfile.php`, it might be executed as PHP code by the web server.
+\
+To prevent issues like these, store user-uploaded content in a database instead. If your application stores files on the file system, be sure to implement careful handling, validation, and sanitization of uploaded files.
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+**In most cases, file type restrictions should be in place for uploads. What types of files does your application white-list?**
+{{<c/text "webvuln_upload_storage_types" />}}
+
+**How does the application enforce these file type restrictions?**
+{{<c/choices webvuln_upload_storage_type multi >}}
+* (extension) We verify the file type by checking the file extension on the server side.
+* (contenttype) We look at the content type that is sent by the user.
+* (reencoding) We decode and re-encode the file, storing only the result.
+* (other) We employ another method to verify the file type.
+{{</c/choices >}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{{<c/show `{webvuln_upload_storage} == 'other'` >}}
+**Explain how you verify the file type and enforce the whitelist:**
+{{<c/text "webvuln_upload_storage_type_other_details" multi />}}
+{{</c/show >}}
+
+
+
+
+
+
+{{<c/show `{webvuln_upload_storage_type} has 'extension' and {webvuln_upload_storage} == 'fs'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Some web servers are configured by default to allow double file extensions. For example, if a user uploads a file called `malicious.php.gif`, it might actually be executed as PHP code upon retrieval. Because you store uploaded files on the file system, this issue may affect your application. Make sure your web server uses only the last extension (i.e., the part after the right-most dot in the file name) when determining how to process the file.\
+
+{{%/notice%}}
+{{</c/show >}}
+
+
+
+
+{{<c/show `{webvuln_upload_storage_type} has 'reencoding'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Re-encoding files uploaded by users is usually a very good approach. However, note that because the decoding and re-encoding works on untrusted user input (and because parsing is difficult and error-prone), it's best to perform these operations in a sandbox. That way, even if an attacker successfully exploits a vulnerability in the parser, the effects would be constrained to the sandboxed environment. Various sandboxing APIs are available, such as the [Seccomp library](http://sourceforge.net/projects/libseccomp/) for Linux.\
+You could also run the decoder/encoder on an isolated virtual machine that's regularly reset to a predefined state. Note, however, that a successful attacker would still be able to observe all incoming and outgoing files, unless the reset happens after each individual file operation\
+Even with a sandboxed encoder, some attacker-provided content may survive the re-encoding. For example, in images, the EXIF metadata may be left intact. If this occurs and the content type is incorrectly set (or browser content-sniffing behavior kicks in), cross-site scripting vulnerabilities can result.\
+\
+**Describe the steps you're taking to protect against vulnerabilities in the decoding and parsing code:**
+{{<c/text "webvuln_upload_storage_type_reencoding_details" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+{{<c/show `{webvuln_upload_storage_type} has 'contenttype' and !({webvuln_upload_storage_type} has 'reencoding') and !({webvuln_upload_storage_type} has 'extension')` >}}
+
+{{%notice danger%}}
+**Warning — possible high-risk issue**\
+\
+Unfortunately, verifying the content type of uploaded files is generally not sufficient for enforcing a whitelist. Because the content type is a field in the HTTP request sent by the user, it can be arbitrarily set by an attacker (for example, by using an interception proxy). At a minimum, the application should also verify the extension at the very end of the file name and check it against the whitelist.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "webvuln_upload_storage_type_contentypeonly_conpensating_controls" multi />}}
+{{%/notice%}}
+
+
+
+
+{{</c/show >}}
diff --git a/exampleSite/content/checklist/05_commonvuln_PersistenceBackEndsandQuerying.md b/exampleSite/content/checklist/05_commonvuln_PersistenceBackEndsandQuerying.md
new file mode 100644
index 0000000..56e39ee
--- /dev/null
+++ b/exampleSite/content/checklist/05_commonvuln_PersistenceBackEndsandQuerying.md
@@ -0,0 +1,67 @@
+---
+hidden: true
+---
+
+Because your application uses a database or a similar back end to persist data, we need to make sure it's not vulnerable to injection attacks, such as [SQL injection](http://en.wikipedia.org/wiki/SQL_injection)
+
+An application is vulnerable to SQL injection when some portion of user input is interpreted by the database as part of a query. When this occurs, an attacker may be able to read or even write data directly from or to the database.
+
+{{<c/choices webvuln_db_sql multi >}}
+* (orm) Our application uses an object-relational mapping (ORM) framework. When we need to manually construct queries or conditions, we use one of the mechanisms selected below:
+* (prepared) We use prepared statements and let the framework take care of correctly escaping the user input.
+* (stored) We pass user input to the database via stored procedures.
+* (manual) We manually escape user input whenever we need to use it in a database query.
+* (other) We do something else.
+{{</c/choices >}}
+
+
+{{<c/show `{webvuln_db_sql} has 'other'` >}}
+**Describe the other mechanism you're using to protect against SQL injection:**
+{{<c/text "webvuln_db_sql_other_details" multi />}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_db_sql} has 'orm'` >}}
+{{%notice%}}
+**Tip**\
+\
+Using an ORM layer is generally a good way to protect against SQL injection. However, in most ORM frameworks, it's possible to directly specify parts of the SQL query. Some ORM frameworks also have a special querying language that makes it possible to set the `WHERE` part of the statement. In these cases, you still need to be sure to guard against injection vulnerabilities.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_db_sql} has 'orm'` >}}
+**What ORM framework are you using ?**
+{{<c/text "webvuln_sql_orm" multi />}}
+{{</c/show >}}
+
+
+
+{{<c/show `{webvuln_db_sql} has 'stored'` >}}
+{{%notice%}}
+**Tip**\
+\
+Using stored procedures is generally a good way to protect against SQL injection. But this strategy must be used consistently. Make sure neither the stored procedures themselves nor the calls of the stored procedures are vulnerable to injection attacks.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{webvuln_db_sql} has 'prepared' && !({webvuln_db_sql} has 'manual')` >}}
+**Do you take special steps (policies, code reviews, audits, etc.) to ensure that prepared statements are used consistently, and that string concatenation is never used to construct database queries?**
+{{<c/choices webvuln_db_sql_prepared >}}
+* (yes) Yes, we have all or most of these measures in place, and we're very confident that there are no SQL injection vulnerabilities in our code.
+* (no) We try to make our developers use prepared statements, but it may be possible for some string concatenation to slip through.
+{{</c/choices >}}
+{{</c/show >}}
+
+
+{{<c/show `{webvuln_db_sql} has 'manual' or {webvuln_db_sql_prepared} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Manually escaping SQL (or related) queries is error-prone and very difficult to do consistently. Here are a couple of examples:\
+* PHP provides the function `mysql_escape_string` for escaping user input that will be used in a database query. Unfortunately, that function does not take into account the character set of the connection, so it may still be possible to smuggle in user input that will be interpreted as part of the SQL query. Applications should use `mysql_real_escape_string` instead.
+* In SQL, numbers do not need to be surrounded with quotation marks when used in a statement. For example, `SELECT username WHERE id=123` is perfectly valid. But if user-provided input that will be used as a number is not confirmed to be actually numeric, the resulting code will be vulnerable to SQL injection (even if the input is escaped).
+We highly recommend using something like prepared statements, or using an ORM layer consistently throughout the application. Make sure you have procedures in place to enforce your approach (such as static tests when code is checked into the repository).\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "webvuln_db_sql_prepared_no_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
diff --git a/exampleSite/content/checklist/05_commonvuln_UseofCryptography.md b/exampleSite/content/checklist/05_commonvuln_UseofCryptography.md
new file mode 100644
index 0000000..305d081
--- /dev/null
+++ b/exampleSite/content/checklist/05_commonvuln_UseofCryptography.md
@@ -0,0 +1,11 @@
+---
+hidden: true
+---
+
+
+You previously mentioned that your application uses cryptography to ensure the confidentiality and/or integrity of information. That's great! But we want to make sure you're using cryptography correctly.
+
+Note: when using cryptography, make sure algorithms are used in the right context and within appropriate constraints. For example, encrypting a session ID does not prevent an attacker from manipulating it. Similarly, a signature does not protect a message's confidentiality.
+
+**Describe your use of cryptography (what information is encrypted/signed, how, why, what algorithms are used, etc.). Be as specific and precise as possible:**
+{{<c/text "webvuln_crypto_details" multi />}}
diff --git a/exampleSite/content/checklist/06_testing.md b/exampleSite/content/checklist/06_testing.md
new file mode 100644
index 0000000..a2cd97d
--- /dev/null
+++ b/exampleSite/content/checklist/06_testing.md
@@ -0,0 +1,111 @@
+---
+hidden: true
+---
+Security testing can be part of standard application tests. Here are some examples:
+
+* **Simple unit tests**: Unit tests are typically used to confirm that the basic building blocks of the application work as expected. Unit tests are easy to repeat — they can run whenever new code is checked into the repository, to confirm that the code still behaves as expected. Unit tests can also check for security features. For example, they can be used to confirm that requests fail without XSRF tokens; that authentication is required to access user data; or that unexpected HTML tags can't get through input filters or escaping routines.
+* **Release testing**: Before a new version of a product is released, human testers typically go through the application, try the new features, and make sure previous features still work correctly (regression testing). Security testing should be included in this process as well. For example, release testing is a great time to verify that user A cannot access the data of user B.
+* **Monitoring**: Once the application is deployed, the focus usually shifts from testing to monitoring. Watch out for unexpected spikes in error rates, sandbox violations, and other flaky or inexplicable behavior (including intermittent test failures) — and before you dismiss an anomaly, check with your security team. Crashes and flakiness can indicate a race condition or a memory corruption bug.
+
+
+The next few questions assess the testing and monitoring of your application.
+
+**Are you using unit tests or similar methods?**
+{{<c/choices application_testing_unit >}}
+* (yes) Yes
+* (no) No
+{{</c/choices >}}
+
+{{<c/show `{application_testing_unit} == 'yes'` >}}
+### Unit Testing
+**How would you describe the code coverage of your unit tests?**
+{{<c/choices application_testing_unit_coverage >}}
+* (large) Robust - The vast majority of our code is tested through unit tests; code coverage is at least &gt;80%.
+* (med) Weak - We have some unit testing, but much of the code is not tested.
+* (small) Nonexistent - We have no (or almost no) unit tests.
+{{</c/choices >}}
+{{<c/show `{application_testing_unit_coverage} == 'med' or {application_testing_unit_coverage} == 'small'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Unit tests have become quasi-standard for testing the functionality of software at a low level. Although this questionnaire focuses on security, the functional correctness of the application is also important. Particularly for web applications, where it is difficult (often impossible) to fall back to a previous version, functional bugs can cause problems with both integrity and availability. Consider implementing unit tests.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "application_testing_unit_coverage_low_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{application_testing_unit_coverage} == 'med' or {application_testing_unit_coverage} == 'large'` >}}
+**Do you have special unit tests in place for testing the security of your code? For example, unit tests can be used to do the following:**
+* Verify that XSRF tokens are required for all state-changing actions
+* Confirm that user input is correctly escaped and/or sanitized
+* Check that the application enforces access control (e.g., user A doesn't have access to user B's data)
+{{<c/choices application_testing_unit_security >}}
+* (yes) Yes
+* (no) No
+{{</c/choices >}}
+{{<c/show `{application_testing_unit_security} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Scalable security depends on engineers doing their part — and common-sense, low-overhead unit tests are one of the most cost-efficient defenses available. Unit tests can help validate security parameters and avoid regressions that reintroduce security bugs. We strongly recommend including security checks in your unit tests.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "application_testing_unit_security_no_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+{{</c/show >}} <!-- Do you have special unit tests in place for testing -->
+
+
+
+
+{{</c/show >}} <!-- Unit Testing -->
+
+
+**Do your engineers and your QA team look for potential security issues during release testing, and have they been trained to do so?**
+{{<c/choices application_testing_qa_security >}}
+* (yes) Yes, our QA process explicitly includes testing for security issues that might have been introduced in the new version.
+* (no) This is an area where we have some room for improvement.
+{{</c/choices >}}
+{{<c/show `{application_testing_qa_security} == 'no'` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Your engineering and QA teams are in the best position to understand how all parts of the application work, what has changed since the previous iteration, and how the changes might introduce security vulnerabilities. Release testing is typically done under considerable time pressure, but it's the last chance to catch security vulnerabilities internally. When your teams are already focused on testing, adding a few security tests won't increase the effort by much.\
+\
+Engineers and testers who have been trained to look for security issues can make all the difference between a secure product and a serious vulnerability.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "application_testing_qa_security_no_conpensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
+
+
+### Post-Launch Monitoring
+
+**How would you describe your post-launch monitoring?**
+{{<c/choices application_monitoring >}}
+* (robust) Robust - We have procedures in place to log and monitor for unexpected crashes, exceptions, and other error conditions. If something looks suspicious, a security-conscious engineer evaluates it.
+* (weak) Weak - If something goes terribly wrong, such as massive spikes in crash rates or other large-scale anomalies, we will probably notice. But our monitoring is fairly coarse, and there is room for improvement.
+* (none) Nonexistent - At the moment, we are not doing any kind of post-release monitoring that looks for signs of exploitation or increases in crashes/exceptions.
+{{</c/choices >}}
+{{<c/show `{application_monitoring} == 'robust'` >}}
+{{%notice%}}
+**Tip**\
+\
+Thank you for putting effort into post-launch monitoring. Exceptions often indicate an underlying security problem, and close monitoring goes a long way toward quickly identifying and subsequently fixing vulnerabilities.
+{{%/notice%}}
+{{</c/show >}}
+
+{{<c/show `{application_monitoring} == 'weak' or {application_monitoring} == 'none' ` >}}
+{{%notice warning%}}
+**Warning — possible medium-risk issue**\
+\
+Exceptions and crashes often indicate an underlying security problem. Monitoring the deployed application can go a long way toward quickly identifying and subsequently fixing vulnerabilities. In carefully designed software products, exceptions should be a fairly rare occurrence; it therefore usually does not introduce significant overhead to monitor for them.\
+\
+**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:**
+{{<c/text "application_monitoring_weak_compensating_controls" multi />}}
+{{%/notice%}}
+{{</c/show >}}
diff --git a/exampleSite/content/checklist/__article-sidebar-after.md b/exampleSite/content/checklist/__article-sidebar-after.md
new file mode 100644
index 0000000..5be235b
--- /dev/null
+++ b/exampleSite/content/checklist/__article-sidebar-after.md
@@ -0,0 +1,12 @@
+---
+---
+<div class="checklist-footer">
+ <button type="button"
+ onclick="downloadFile('6d2ab01b-fad4-4e70-83a8-b910ca848fec');"
+ class="btn btn-success"><i class="fas fa-download"></i>&nbsp;Download Answers</button>
+</div>
+
+{{%notice info%}}
+This checklist was made from the VSAQ Vendor Security Assessment Questionnaire, licensed with Apache License 2.0 -- More info here : https://github.com/google/vsaq
+{{%/notice %}}
+
diff --git a/exampleSite/content/checklist/_index.md b/exampleSite/content/checklist/_index.md
new file mode 100644
index 0000000..36e6fce
--- /dev/null
+++ b/exampleSite/content/checklist/_index.md
@@ -0,0 +1,267 @@
+---
+hide:
+- nextpage
+- navs
+
+
+title: WebApp Security Assessment
+weight: 99
+
+checklist: true
+---
+
+{{%notice success%}}
+This is a demo of a [checklist page]({{%ref "content-and-customization/00-adding-content/page-checklist"%}})
+{{%/notice %}}
+
+## Application Metadata
+{{%include "01_appmetadata.md"%}}
+
+
+## Vulnerability Reporting and Management
+{{%include "02_vulnerabilityreporting.md"%}}
+
+
+## HTTPS and Mixed-Content Risks
+{{%include "03_https.md"%}}
+
+
+## Authentication and Authorization
+{{%include "04_authz.md"%}}
+
+
+## Common Web Vulnerabilities
+{{%include "05_commonvuln.md"%}}
+
+
+## Testing, QA, and Monitoring
+{{%include "06_testing.md"%}}
+
+## Additional Notes
+Provide any additional information about the security of your application:
+{{<c/text additional_notes multi />}}
+
+## Security Contacts
+List the email addresses of people we should contact about any security issues in the application:
+{{<c/text security_contacts />}}
+
+## Feedback
+Congratulations! You've made it to the end of this questionnaire. If you can spare another minute, please let us know how we can improve it. Your feedback is highly appreciated.
+{{<c/text feedback multi />}}
+
+---
+
+{{%notice info%}}
+**Licence Info :** this checklist was made from the VSAQ Vendor Security Assessment Questionnaire, licensed with Apache License 2.0 -- More info here : https://github.com/google/vsaq
+{{%/notice %}}
+
+{{<c/show `false` >}}
+## Show
+{{<c/choices mychoices >}}
+* (aa) Show a block.
+* (no) Another block
+* (foo) No Block
+* (two) Show the two blocks
+{{</c/choices>}}
+
+### show 1
+
+{{<c/show `{mychoices} == 'aa' or {mychoices} == 'two'` >}}
+{{%notice%}}
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+{{%/notice%}}
+{{</c/show>}}
+
+{{<c/show `{mychoices} == 'no' or {mychoices} == 'two' ` >}}
+{{%alert%}}No Alert selected !{{%/alert%}}
+{{</c/show>}}
+
+
+
+## text
+
+Quel est le code du projet ?
+
+
+
+{{<columns>}}
+**Simple**
+{{<c/text "app_name*" />}}
+<--->
+**Multiple**
+{{<c/text "app_name_multi*" multi >}}
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua.
+{{</c/text>}}
+{{</columns>}}
+
+## Choices
+
+Les enjeux de sécurité ont été identifiés par la SSI ?
+
+{{<columns>}}
+**Simple**
+
+{{<c/choices app_vulnerability >}}
+ * (yes) Yes, we have a published security email contact, or we provide another way for users to report security issues. Incoming reports are timely reviewed and triaged.
+ * (no) No, we do not currently offer a way to report security vulnerabilities for priority handling
+ * i don't know
+{{</c/choices>}}
+
+<--->
+
+**Multiple**
+
+
+{{<c/choices app_vulnerabilitymulti multi >}}
+ * (yes) Yes, we have a published security email contact, or we provide another way for users to report security issues. Incoming reports are timely reviewed and triaged.
+ * (no) No, we do not currently offer a way to report security vulnerabilities for priority handling
+ * i don't know
+{{</c/choices>}}
+{{</columns>}}
+
+{{<c/show `{app_vulnerability} == 'no' and {app_vulnerabilitymulti} has 'no' ` >}}
+{{%alert danger%}}OK !{{%/alert%}}
+{{</c/show>}}
+
+
+## List
+{{<columns>}}
+**Simple**
+{{<c/list select_from_list >}}
+ * (czero) C0
+ * (cun) C1
+ * (cdeux) C2
+{{</c/list >}}
+
+<--->
+
+**Multiple**
+{{<c/list multiselect multi >}}
+ * All
+ * (czero) C0
+ * (cun) C1
+ * (cdeux) C2
+{{</c/list >}}
+{{</columns>}}
+
+## Checkbox
+
+{{%c/check mycheck %}}J'ai tout compris 1{{%/c/check %}}
+
+## switch
+
+{{%c/switch myswitch %}}Activer le truc{{%/c/switch %}}
+
+
+
+
+
+
+## Code
+{{%expand%}}
+Change on any element form
+```js
+ var form = document.querySelector('form');
+ form.addEventListener('change', function(e,v) {
+ console.log("element changed", e.target,v)
+ });
+
+````
+
+Get all data
+```js
+ $("form[name=myform]").serializeArray()
+```
+
+Download file :
+* date
+* ref
+* url
+* data
+* hash or signature
+```js
+function downloadFile() {
+ var obj = {a: 123, b: "4 5 6"};
+ var filename = "download.json";
+ var blob = new Blob([JSON.stringify(obj)], {type: 'text/plain'});
+ if (window.navigator && window.navigator.msSaveOrOpenBlob) {
+ window.navigator.msSaveOrOpenBlob(blob, filename);
+ } else{
+ var e = document.createEvent('MouseEvents'),
+ a = document.createElement('a');
+ a.download = filename;
+ a.href = window.URL.createObjectURL(blob);
+ a.dataset.downloadurl = ['text/plain', a.download, a.href].join(':');
+ e.initEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ a.dispatchEvent(e);
+ }
+}
+````
+
+load file 1 :
+```js
+input.addEventListener('change', () => {
+ let files = input.files;
+
+ if (files.length == 0) return;
+
+ /* If any further modifications have to be made on the
+ Extracted text. The text can be accessed using the
+ file variable. But since this is const, it is a read
+ only variable, hence immutable. To make any changes,
+ changing const to var, here and In the reader.onload
+ function would be advisible */
+ const file = files[0];
+
+ let reader = new FileReader();
+
+ reader.onload = (e) => {
+ const file = e.target.result;
+
+ // This is a regular expression to identify carriage
+ // Returns and line breaks
+ const lines = file.split(/\r\n|\n/);
+ textarea.value = lines.join('\n');
+
+ };
+
+ reader.onerror = (e) => alert(e.target.error.name);
+
+ reader.readAsText(file);
+});
+````
+
+load file 2 :
+```js
+function onFileLoad(elementId, event) {
+ document.getElementById(elementId).innerText = event.target.result;
+}
+
+function onChooseFile(event, onLoadFileHandler) {
+ if (typeof window.FileReader !== 'function')
+ throw ("The file API isn't supported on this browser.");
+ let input = event.target;
+ if (!input)
+ throw ("The browser does not properly implement the event object");
+ if (!input.files)
+ throw ("This browser does not support the `files` property of the file input.");
+ if (!input.files[0])
+ return undefined;
+ let file = input.files[0];
+ let fr = new FileReader();
+ fr.onload = onLoadFileHandler;
+ fr.readAsText(file);
+}
+```
+```html
+<input type='file' onchange='onChooseFile(event, onFileLoad.bind(this, "contents"))' />
+<p id="contents"></p>
+```
+{{%/expand%}}
+{{</c/show>}}
diff --git a/exampleSite/content/content-and-customization/00-adding-content/page-checklist/_index.md b/exampleSite/content/content-and-customization/00-adding-content/page-checklist/_index.md
new file mode 100644
index 0000000..a2d0187
--- /dev/null
+++ b/exampleSite/content/content-and-customization/00-adding-content/page-checklist/_index.md
@@ -0,0 +1,34 @@
+---
+date: "2017-04-24T18:36:24+02:00"
+description: ""
+title: As a Checklist
+weight: 190
+---
+
+A basic .md file can be rendered as a form/checklist/questionnaire.
+
+{{% notice %}}
+**A page rendered as a Checklist** is a page with a special rendered TOC, and a LOAD/DOWNLAOD form results buttons.
+\
+[{{%icon aspect_ratio%}} click here to view an example]({{%ref "checklist/_index.md"%}})
+
+{{%/notice%}}
+
+To tell Hugo to consider a page as a checklist, just add a `checklist: true` in the frontmatter of your page.
+
+```yaml
+---
+checklist: true
+---
+```
+
+## Demo
+[{{%icon aspect_ratio%}} click here to view an example]({{%ref "checklist/_index.md"%}})
+
+## Dedicated shortcodes
+* c/text - a line or box input type
+* c/choices - a radiogroup or a checkboxgroup
+* c/list - a select or a multiselect
+* c/check - a checkbox
+* c/switch - a switch
+* c/show - display a part with a condition using user inputs
diff --git a/exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.content b/exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.content
new file mode 100644
index 0000000..3e1b0f4
--- /dev/null
+++ b/exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.content
@@ -0,0 +1,42 @@
+body article section.page div.content div.checklist-header .form-control-file {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 6em;
+ outline: none;
+ visibility: hidden;
+ cursor: pointer;
+ background-color: #c61c23;
+ box-shadow: 0 0 5px solid currentColor; }
+ body article section.page div.content div.checklist-header .form-control-file:before {
+ content: attr(data-title);
+ position: absolute;
+ top: 0.5em;
+ left: 0;
+ width: 100%;
+ min-height: 4em;
+ line-height: 0.5em;
+ padding-top: 1.5em;
+ opacity: 1;
+ visibility: visible;
+ text-align: center;
+ border: 0.25em dashed currentColor;
+ transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+ overflow: hidden; }
+ body article section.page div.content div.checklist-header .form-control-file:hover:before {
+ border-style: solid;
+ box-shadow: inset 0px 0px 0px 0.25em currentColor; }
+
+body article section.page div.content div.checklist-footer {
+ margin-top: 2em;
+ margin-bottom: 2em;
+ text-align: center; }
+
+body #TableOfContents > ul li input {
+ margin-right: 0.3em; }
+
+body #TableOfContents > ul li:not(.cl-ready):not(.cl-done):not(.cl-doing) input {
+ visibility: hidden; }
+
+body #TableOfContents > ul li.cl-ready input, body #TableOfContents > ul li.cl-doing input, body #TableOfContents > ul li.cl-done input {
+ visibility: visible; }
diff --git a/exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.json b/exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.json
new file mode 100644
index 0000000..39a473f
--- /dev/null
+++ b/exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.json
@@ -0,0 +1 @@
+{"Target":"css/checklist.main.css","MediaType":"text/css","Data":{}} \ No newline at end of file
diff --git a/exampleSite/resources/_gen/assets/scss/sass/layout.scss_f300667da4f5b5f84e1a9e0702b2fdde.content b/exampleSite/resources/_gen/assets/scss/sass/layout.scss_f300667da4f5b5f84e1a9e0702b2fdde.content
index 70945cc..1fb45dc 100644
--- a/exampleSite/resources/_gen/assets/scss/sass/layout.scss_f300667da4f5b5f84e1a9e0702b2fdde.content
+++ b/exampleSite/resources/_gen/assets/scss/sass/layout.scss_f300667da4f5b5f84e1a9e0702b2fdde.content
@@ -81,13 +81,13 @@ body:not(.render_raw) {
margin-top: 0.5em;
margin-left: 0.2em; }
body:not(.render_raw) article section.page .jump-to-section ul {
- padding-left: 20px; }
+ padding-left: 10px; }
body:not(.render_raw) article section.page .jump-to-section nav {
display: none;
position: absolute;
z-index: 5;
border: 1px solid;
- padding: 3px 30px;
+ padding: 1em 30px;
border-radius: 3px;
min-width: 25%;
max-width: 50%;
diff --git a/exampleSite/resources/_gen/assets/scss/sass/main.scss_97a9b8e6852415b29a37632934745b8b.content b/exampleSite/resources/_gen/assets/scss/sass/main.scss_97a9b8e6852415b29a37632934745b8b.content
index fa46bc4..6534a4c 100644
--- a/exampleSite/resources/_gen/assets/scss/sass/main.scss_97a9b8e6852415b29a37632934745b8b.content
+++ b/exampleSite/resources/_gen/assets/scss/sass/main.scss_97a9b8e6852415b29a37632934745b8b.content
@@ -167,10 +167,14 @@ article section.page {
article section.page div.jump-to-section {
font-size: smaller;
color: #333333; }
- article section.page div.jump-to-section ul li a {
- color: #a14545; }
+ article section.page div.jump-to-section ul {
+ padding-left-left: 0px;
+ list-style-type: none; }
+ article section.page div.jump-to-section ul li a {
+ color: #a14545; }
article section.page div.jump-to-section nav {
- background-color: white; }
+ background-color: white;
+ opacity: 0.95; }
article section.page div.chevrons {
margin-top: 3rem;
border-top: 1px solid #e6e6e6;
@@ -234,6 +238,9 @@ article section.page div.content {
color: #db0c0c;
font-weight: 500;
text-decoration: underline; }
+ article section.page div.content p {
+ margin-top: 1rem;
+ margin-bottom: 1rem; }
article section.page div.content h1 {
color: #4d4d4d;
font-variant-ligatures: none;
@@ -244,6 +251,8 @@ article section.page div.content {
margin-top: 0.5em;
font-weight: 700;
letter-spacing: -0.95px; }
+ article section.page div.content h3, article section.page div.content h4 {
+ margin-top: 0.5em; }
article section.page div.content table {
width: 100%;
margin-bottom: 2em;
diff --git a/exampleSite/resources/_gen/assets/scss/sass/shortcodes/notice.scss_f300667da4f5b5f84e1a9e0702b2fdde.content b/exampleSite/resources/_gen/assets/scss/sass/shortcodes/notice.scss_f300667da4f5b5f84e1a9e0702b2fdde.content
index 8afa11a..e8ecd85 100644
--- a/exampleSite/resources/_gen/assets/scss/sass/shortcodes/notice.scss_f300667da4f5b5f84e1a9e0702b2fdde.content
+++ b/exampleSite/resources/_gen/assets/scss/sass/shortcodes/notice.scss_f300667da4f5b5f84e1a9e0702b2fdde.content
@@ -1,14 +1,21 @@
-div.notices p {
- /*box-shadow: inset 4px 0 0 black;*/
- /*border-radius: .2rem;*/
+div.notices {
+ margin-top: 1rem;
+ margin-bottom: 1rem; }
+
+div.notices > * {
background: white;
- padding: .5rem 1rem .5rem 1rem;
- margin-top: 0px;
+ margin-top: 0px !important;
+ margin-bottom: 0px !important;
box-sizing: border-box;
box-shadow: inset 4px 0 0 black;
background-color: #e6e6e6;
font-size: smaller; }
+div.notices > *:not(ul) {
+ /*box-shadow: inset 4px 0 0 black;*/
+ /*border-radius: .2rem;*/
+ padding: .5rem 1rem .5rem 1rem; }
+
div.notices label {
font-size: 0.5em;
position: absolute;
@@ -58,7 +65,7 @@ div.notices.danger p {
div.notices.danger label {
color: #dc3545; }
-div.notices.warning p {
+div.notices.warning > * {
box-shadow: inset 4px 0 0 #ffc107;
background: rgba(255, 193, 7, 0.05);
color: #a07800 !important; }
diff --git a/i18n/en.toml b/i18n/en.toml
index 158d97a..b527071 100644
--- a/i18n/en.toml
+++ b/i18n/en.toml
@@ -51,4 +51,13 @@ other= "Next page"
other= "What's on this page"
[last-update-by]
-other = "Last update by" \ No newline at end of file
+other = "Last update by"
+
+[checklist-load-answers]
+other = "Load answers from file"
+
+[checklist-download-answers]
+other = "Download Answers"
+
+[checklist-post-answers]
+other = "Post Answers" \ No newline at end of file
diff --git a/i18n/fr.toml b/i18n/fr.toml
index cc78183..c37a8f4 100644
--- a/i18n/fr.toml
+++ b/i18n/fr.toml
@@ -51,4 +51,13 @@ other= "Contenu suivant"
other= "Contenu de la page"
[last-update-by]
-other = "Dernière modification par " \ No newline at end of file
+other = "Dernière modification par "
+
+[checklist-load-answers]
+other = "Charger un fichier de réponse"
+
+[checklist-download-answers]
+other = "Télécharger les réponses"
+
+[checklist-post-answers]
+other = "Envoyer les réponses" \ No newline at end of file
diff --git a/layouts/index.json b/layouts/index.json
index 984aaa7..c0152f3 100644
--- a/layouts/index.json
+++ b/layouts/index.json
@@ -1,5 +1,6 @@
[{{ range $index, $page := .Site.Pages }}
{{- if not (hasPrefix $page.Section "_") -}}
+{{- if not (hasPrefix $page.File.BaseFileName "__") -}}
{{- if ne $page.Type "json" -}}
{{- if and $index (gt $index 0) -}},{{- end }}
{
@@ -11,4 +12,5 @@
}
{{- end -}}
{{- end -}}
+{{- end -}}
{{- end -}}] \ No newline at end of file
diff --git a/layouts/partials/_checklist-footer.html b/layouts/partials/_checklist-footer.html
new file mode 100644
index 0000000..009e6fc
--- /dev/null
+++ b/layouts/partials/_checklist-footer.html
@@ -0,0 +1,8 @@
+{{if .Params.checklist}}
+ </form>
+ <div class="checklist-footer">
+ <button type="button"
+ onclick="downloadFile('6d2ab01b-fad4-4e70-83a8-b910ca848fec');"
+ class="btn btn-success"><i class="fas fa-download"></i>&nbsp;{{T "checklist-download-answers"}}</button>
+ </div>
+{{end}}
diff --git a/layouts/partials/_checklist-header.html b/layouts/partials/_checklist-header.html
new file mode 100644
index 0000000..4426680
--- /dev/null
+++ b/layouts/partials/_checklist-header.html
@@ -0,0 +1,16 @@
+{{if .Params.checklist}}
+ {{ $formID := .File.UniqueID }}
+ <link rel="stylesheet" href='{{ (resources.Get "sass/checklist.scss" | resources.ExecuteAsTemplate "css/checklist.main.scss" . | toCSS).Permalink }}'>
+ <form name="{{$formID}}" id="6d2ab01b-fad4-4e70-83a8-b910ca848fec" ref="{{with $.Params.Ref}}{{.}}{{else}}{{printf "%s-%s" $.CurrentSection.Title $formID}}{{end}}">
+ <script src='{{"js/checklist.js" | relURL}}'></script>
+ <script type="text/javascript">
+ $( document ).ready(function() {
+ listenFormChange('6d2ab01b-fad4-4e70-83a8-b910ca848fec')
+ });
+ </script>
+
+ <div class="form-group checklist-header">
+ <label class="sr-only" for="inputFile">File Upload</label>
+ <input type="file" class="form-control-file text-primary font-weight-bold" id="inputFile" accept="application/json" onchange="onChooseFile(event,fillForm('6d2ab01b-fad4-4e70-83a8-b910ca848fec'))" data-title="{{T "checklist-load-answers"}}">
+ </div>
+{{end}} \ No newline at end of file
diff --git a/layouts/partials/_mdinclude.html b/layouts/partials/_mdinclude.html
index 820a5e3..812b8c9 100644
--- a/layouts/partials/_mdinclude.html
+++ b/layouts/partials/_mdinclude.html
@@ -1,9 +1,12 @@
-{{- template "extrapage" dict "name" .name "page" .context "tip" .tip -}}
-{{- define "extrapage" -}}
- {{ $header := print .name "." .page.Lang }}
- {{ range where .page.Site.Pages "File.BaseFileName" $header }}
+{{- template "pageBlock" dict "name" .name "page" .context -}}
+{{- template "siteBlock" dict "name" .name "page" .context "tip" .tip -}}
+
+{{- define "siteBlock" -}}
+ {{ $path := printf "_layout/%s/_index.%s.md" .name .page.Lang}}
+ {{ range where .page.Site.Pages "File.BaseFileName" $path }}
{{ .Content }}
{{else}}
+ {{ $path = printf "_layout/%s/_index.md" .name }}
{{ if .page.Site.GetPage "page" (print .name ".md") }}
{{(.page.Site.GetPage "page" (print .name ".md")).Content}}
{{else}}
@@ -11,3 +14,10 @@
{{end}}
{{end}}
{{- end -}}
+
+{{- define "pageBlock" -}}
+{{ $path := printf "%s__%s.md" .page.Dir .name}}
+ {{ with .page.Site.GetPage $path }}
+ {{ .Content }}
+ {{end}}
+{{- end -}}
diff --git a/layouts/partials/body-article-content.html b/layouts/partials/body-article-content.html
index 0eedee2..f4d9698 100644
--- a/layouts/partials/body-article-content.html
+++ b/layouts/partials/body-article-content.html
@@ -20,6 +20,7 @@
{{ $isSubPage := .Params.subpage }}
{{ $subpages := (where (where (where .Sections.ByWeight "Params.subpage" true) "Params.hidden" "ne" true ) "Kind" "section")}}
{{ $pages := (where (where .CurrentSection.Pages.ByWeight "Kind" "page") "Params.hidden" "ne" true ) }}
+
{{if $isSubPage }}
<h1>{{.Parent.Title}}<span>{{$pagetitle}}</span></h1>
@@ -40,7 +41,7 @@
{{ if gt (len $elements) 0}}
<nav class="subpages">
{{- range $elements}}
- {{- if not .Params.hidden }}
+ {{- if and (not .Params.hidden) ( not (hasPrefix .File.BaseFileName "__")) }}
{{$pagetitle := .Title}}
{{if eq $pagetitle ""}}{{$pagetitle = .File.BaseFileName}}{{end}}
<li {{if eq . $cPage}}class="active"{{- end}}>
@@ -65,9 +66,16 @@
{{end}}
<!-- / JUMP TO SECTION -->
+
+
+
+
+
<div class="content">
{{- with .Content -}}
- {{ . | replaceRE "(<h[1-9]) id=\"([^\"]+)\"(.+)(</h[1-9]+>)" `${1}${3}${4}<a class="anchor" id="${2}"></a>` | safeHTML }}
+ {{ partial "_checklist-header.html" $ }}
+ {{ . | replaceRE "(<h[1-9]) id=\"([^\"]+)\"(.+)(</h[1-9]+>)" `${1} ref="${2}" ${3}${4}<a class="anchor" id="${2}"></a>` | safeHTML }}
+ {{ partial "_checklist-footer.html" $ }}
{{- else -}}
{{with index .Pages 0}}
<meta http-equiv = "refresh" content = "0; url = {{.RelPermalink}}"/>
@@ -78,6 +86,10 @@
</div>
+
+
+
+
{{if not (in .Params.hide "nextpage")}}
<div class="chevrons">
{{ partial "_next-prev-page.html" .CurrentSection }}
diff --git a/layouts/partials/body-article-sidepage.html b/layouts/partials/body-article-sidepage.html
index 4d8a8c5..0a4417b 100644
--- a/layouts/partials/body-article-sidepage.html
+++ b/layouts/partials/body-article-sidepage.html
@@ -1,6 +1,5 @@
-{{- partial "_mdinclude.html" (dict "name" "_layout/article-sidebar-before/_index" "context" .) -}}
+{{- partial "_mdinclude.html" (dict "name" "article-sidebar-before" "context" .) -}}
<div class="TableOfContents">
-
<label><i class="fas fa-align-right"></i>&nbsp;&nbsp;{{T "table-of-contents"}}</label>
<nav>
<ul >
@@ -9,7 +8,7 @@
</nav>
{{ .TableOfContents }}
</div>
-{{- partial "_mdinclude.html" (dict "name" "_layout/article-sidebar-after/_index" "context" .) -}}
+{{- partial "_mdinclude.html" (dict "name" "article-sidebar-after" "context" .) -}}
<div class="Actions">
diff --git a/layouts/partials/body-footer.html b/layouts/partials/body-footer.html
index 157e877..96eef5b 100644
--- a/layouts/partials/body-footer.html
+++ b/layouts/partials/body-footer.html
@@ -1,4 +1,4 @@
-{{- partial "_mdinclude.html" (dict "name" "_layout/footer/_index" "context" . "tip" (T "create-footer-md") ) -}}
+{{- partial "_mdinclude.html" (dict "name" "footer" "context" . "tip" (T "create-footer-md") ) -}}
diff --git a/layouts/partials/body-header.html b/layouts/partials/body-header.html
index 1b32e30..56a1af1 100644
--- a/layouts/partials/body-header.html
+++ b/layouts/partials/body-header.html
@@ -7,7 +7,7 @@
<div>
{{- $defaultheader := printf "<a class='baselink' href='%s'>%s</a>" .Site.BaseURL .Site.Title -}}
- {{- partial "_mdinclude.html" (dict "name" "_layout/header/_index" "context" . "tip" $defaultheader ) -}}
+ {{- partial "_mdinclude.html" (dict "name" "header" "context" . "tip" $defaultheader ) -}}
</div>
{{- with .Site.Menus.shortcuts}}
diff --git a/layouts/partials/body-sidebar.html b/layouts/partials/body-sidebar.html
index 217d8fb..bcfd4ac 100644
--- a/layouts/partials/body-sidebar.html
+++ b/layouts/partials/body-sidebar.html
@@ -18,7 +18,7 @@
{{- end}}
-{{- partial "_mdinclude.html" (dict "name" "_layout/sidebar-before/_index" "context" .) -}}
+{{- partial "_mdinclude.html" (dict "name" "sidebar-before" "context" .) -}}
<div id="close_menu">
<a href="javascript:void(0);" style="font-size:15px;" onclick="$('article > aside').toggleClass('responsive')">
@@ -30,4 +30,4 @@
{{- partial "_menu.html" . }}
</ul>
-{{- partial "_mdinclude.html" (dict "name" "_layout/sidebar-after/_index" "context" .) -}} \ No newline at end of file
+{{- partial "_mdinclude.html" (dict "name" "sidebar-after" "context" .) -}} \ No newline at end of file
diff --git a/layouts/partials/html-head.html b/layouts/partials/html-head.html
index ff23396..436ed4c 100644
--- a/layouts/partials/html-head.html
+++ b/layouts/partials/html-head.html
@@ -20,6 +20,17 @@
<link href='{{"vendor/bootstrap/bootstrap-4.5.2-dist/css/bootstrap.min.css" | relURL}}' rel="stylesheet">
+
+
+<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/notice.scss" | toCSS).Permalink }}'>
+<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/tabs.scss" | toCSS).Permalink }}'>
+<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/panel.scss" | toCSS).Permalink }}'>
+<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/columns.scss" | toCSS).Permalink }}'>
+<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/children.scss" | toCSS).Permalink }}'>
+<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/attachments.scss" | toCSS).Permalink }}'>
+<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/alert.scss" | toCSS).Permalink }}'>
+
+
<link rel="stylesheet" href='{{"/css/docport.css" | relURL}}'>
diff --git a/layouts/shortcodes/alert.html b/layouts/shortcodes/alert.html
index 5e420ea..0e1c417 100644
--- a/layouts/shortcodes/alert.html
+++ b/layouts/shortcodes/alert.html
@@ -1,5 +1,5 @@
{{ $_hugo_config := `{ "version": 1 }` }}
-<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/alert.scss" | toCSS).Permalink }}'>
+
<div class="alert{{- " " -}}{{- if .IsNamedParams -}}
{{- with .Get "theme" -}}{{.}}{{- else -}}info{{- end -}}
{{- else -}}
diff --git a/layouts/shortcodes/attachments.html b/layouts/shortcodes/attachments.html
index 4b6c3f9..a6d2537 100644
--- a/layouts/shortcodes/attachments.html
+++ b/layouts/shortcodes/attachments.html
@@ -1,5 +1,5 @@
{{ $_hugo_config := `{ "version": 1 }` }}
-<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/attachments.scss" | toCSS).Permalink }}'>
+
<section class="attachments">
<i class="fas fa-paperclip"></i>
diff --git a/layouts/shortcodes/c/check.html b/layouts/shortcodes/c/check.html
new file mode 100644
index 0000000..3420a39
--- /dev/null
+++ b/layouts/shortcodes/c/check.html
@@ -0,0 +1,29 @@
+{{ $name := replace (.Get 0) "*" "" }}
+{{ $required := strings.HasSuffix (.Get 0) "*" }}
+
+{{ range $index, $content := split (strings.Trim .Inner "\n") "*" }}
+ {{if ne $content ""}}
+
+ {{ $id := printf "%s-%d" $name $index }}
+ {{ $value := printf "checked" }}
+
+ {{ $values := split (replaceRE `\s*(\([^\)]+\))*\s*(.*)` "$1#$2" (strings.Trim $content "\n")) "#" }}
+ {{ $text := (index $values 1) }}
+
+ {{ if ne "" (index $values 0)}}
+ {{ $value = strings.Trim (index $values 0) "()" }}
+ {{end}}
+
+<div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ name="{{$name}}"
+ id="{{ $id }}"
+ value="{{$value}}"
+ class="custom-control-input">
+ <label class="custom-control-label" for="{{$id}}">{{ chomp $text }}</label>
+</div>
+
+ {{end}}
+{{ end }}
+
+
diff --git a/layouts/shortcodes/c/choices.html b/layouts/shortcodes/c/choices.html
new file mode 100644
index 0000000..9104fcb
--- /dev/null
+++ b/layouts/shortcodes/c/choices.html
@@ -0,0 +1,31 @@
+{{ $name := replace (.Get 0) "*" "" }}
+{{ $required := strings.HasSuffix (.Get 0) "*" }}
+{{ $option := .Get 1 }}
+{{ $multiple := cond (eq "multi" $option) true false }}
+
+
+{{ range $index, $content := split (chomp .Inner) "*" }}
+{{if ne $index 0}}
+
+
+{{ $id := printf "%s-%d" $name $index }}
+{{ $value := printf "option-%d" $index }}
+
+{{ $values := split (replaceRE `\s*(\([^\)]+\))*\s*(.*)` "$1#$2" (chomp $content)) "#" }}
+{{ $text := (index $values 1) }}
+{{ if ne "" (index $values 0)}}
+ {{ $value = strings.TrimSuffix ")" (strings.TrimPrefix "(" (index $values 0)) }}
+{{end}}
+
+<div class="custom-control custom-{{cond $multiple `checkbox` `radio`}}">
+ <input type="{{cond $multiple `checkbox` `radio`}}"
+ name="{{$name}}"
+ id="{{ $id }}"
+ value="{{$value}}"
+ {{- cond $multiple `multiple` `` | safeHTMLAttr }}
+ class="custom-control-input">
+ <label class="custom-control-label" for="{{ $id }}">{{$text | markdownify}}</label>
+</div>
+
+{{end}}
+{{ end }}
diff --git a/layouts/shortcodes/c/list.html b/layouts/shortcodes/c/list.html
new file mode 100644
index 0000000..9ff6a05
--- /dev/null
+++ b/layouts/shortcodes/c/list.html
@@ -0,0 +1,34 @@
+{{ $name := replace (.Get 0) "*" "" }}
+{{ $required := strings.HasSuffix (.Get 0) "*" }}
+{{ $option := .Get 1 }}
+{{ $multiple := cond (eq "multi" $option) true false }}
+
+<div class="form-group">
+<select
+ name="{{$name}}"
+ required="{{cond $required `true` `false`}}"
+ {{cond $multiple `multiple` ``}}
+ class="form-control">
+{{ if not $multiple }}
+<option value="" selected>Choose....</option>
+{{end}}
+
+{{ range $index, $content := split (chomp .Inner) "*" }}
+{{if ne $index 0}}
+
+ {{ $id := printf "%s-%d" $name $index }}
+ {{ $value := printf "option-%d" $index }}
+
+ {{ $values := split (replaceRE `\s*(\([^\)]+\))*\s*(.*)` "$1#$2" (chomp $content)) "#" }}
+ {{ $text := (index $values 1) }}
+ {{ if ne "" (index $values 0)}}
+ {{ $value = strings.TrimSuffix ")" (strings.TrimPrefix "(" (index $values 0)) }}
+ {{end}}
+
+<option value="{{$value}}">{{$text}}</option>
+
+{{end}}
+{{ end }}
+</select>
+</div>
+
diff --git a/layouts/shortcodes/c/show.html b/layouts/shortcodes/c/show.html
new file mode 100644
index 0000000..8eda479
--- /dev/null
+++ b/layouts/shortcodes/c/show.html
@@ -0,0 +1,12 @@
+{{ $formID := "6d2ab01b-fad4-4e70-83a8-b910ca848fec" }}
+{{ $random := delimit (shuffle (split (md5 $formID) "" )) "" }}
+{{ $id := printf "dp-show-%s" $random}}
+{{ $condition := trim (.Get 0) " "}}
+{{ $regFormValue := printf "formValue('%s','$1')" $formID}}
+{{ $conditionFix := replaceRE `{(\w+)}` $regFormValue $condition }}
+{{ $conditionFix = replace $conditionFix ` and ` ` && ` }}
+{{ $conditionFix = replace $conditionFix ` or ` ` || ` }}
+{{ $conditionFix = replaceRE `[^)]+has\s+('\w+')` ".includes($1)" $conditionFix }}
+
+<div id="{{$id}}" class="baz" style="display:none">{{.Inner | markdownify}}</div>
+<script type="text/javascript">$(registerShowIf('{{$id}}','{{$conditionFix}}'))</script>
diff --git a/layouts/shortcodes/c/switch.html b/layouts/shortcodes/c/switch.html
new file mode 100644
index 0000000..a3cb392
--- /dev/null
+++ b/layouts/shortcodes/c/switch.html
@@ -0,0 +1,8 @@
+{{ $name := replace (.Get 0) "*" "" }}
+{{ $required := strings.HasSuffix (.Get 0) "*" }}
+{{ $id := $name}}
+
+<div class="custom-control custom-switch">
+ <input type="checkbox" name="{{$name}}" id="{{$id}}" class="custom-control-input" value="on">
+ <label class="custom-control-label" for="{{$id}}">{{ chomp .Inner }}</label>
+</div> \ No newline at end of file
diff --git a/layouts/shortcodes/c/text.html b/layouts/shortcodes/c/text.html
new file mode 100644
index 0000000..2a10760
--- /dev/null
+++ b/layouts/shortcodes/c/text.html
@@ -0,0 +1,19 @@
+{{ $name := replace (.Get 0) "*" "" }}
+{{ $required := strings.HasSuffix (.Get 0) "*" }}
+{{ $option := .Get 1 }}
+{{ $multiple := cond (eq "multi" $option) true false }}
+
+{{ if $multiple }}
+<textarea
+ name="{{ $name }}"
+ required="{{cond $required `true` `false`}}"
+ placeholder='{{ trim .Inner "\n"}}'
+ name="paragraph"
+ class="form-control" rows="3"></textarea>
+{{ else }}
+<input
+ name="{{ $name }}"
+ required="{{cond $required `true` `false`}}"
+ placeholder='{{ trim .Inner "\n" }}'
+ type="text" class="form-control form-control-lg">
+{{ end }} \ No newline at end of file
diff --git a/layouts/shortcodes/children.html b/layouts/shortcodes/children.html
index fe2da11..f016e2b 100644
--- a/layouts/shortcodes/children.html
+++ b/layouts/shortcodes/children.html
@@ -15,7 +15,7 @@
{{- $cpage := (.Scratch.Get "current") }}
-<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/children.scss" | toCSS).Permalink }}'>
+
<ul class="children children-{{$style}}">
{{- .Scratch.Set "pages" $cpage.Pages }}
diff --git a/layouts/shortcodes/columns.html b/layouts/shortcodes/columns.html
index 3148ff5..2fde96d 100644
--- a/layouts/shortcodes/columns.html
+++ b/layouts/shortcodes/columns.html
@@ -1,5 +1,5 @@
<!-- https://github.com/alex-shpak/hugo-book/blob/master/layouts/shortcodes/columns.html -->
-<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/columns.scss" | toCSS).Permalink }}'>
+
<div class="columns">
{{ range split .Inner "<--->" }}
<div class="column">
diff --git a/layouts/shortcodes/include.html b/layouts/shortcodes/include.html
new file mode 100644
index 0000000..c099e6e
--- /dev/null
+++ b/layouts/shortcodes/include.html
@@ -0,0 +1,9 @@
+{{$file := .Get 0}}
+{{$path := printf "%s%s" .Page.File.Dir $file}}
+{{ with .Site.GetPage $path }}{{ .Content }}{{else}}
+<span style=" border: 4px dashed white;display: block;background-color: red;padding: 1em;color:white; font-size: large;font-weight: bold;text-transform: capitalize;">
+ Include : File "{{$path}}" not found !
+ <br>
+ <small>param was "{{$file}}"</small>
+</span>
+{{ end }} \ No newline at end of file
diff --git a/layouts/shortcodes/notice.html b/layouts/shortcodes/notice.html
index ea71ace..d2038dd 100644
--- a/layouts/shortcodes/notice.html
+++ b/layouts/shortcodes/notice.html
@@ -1,5 +1,5 @@
{{ $_hugo_config := `{ "version": 1 }` }}
-<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/notice.scss" | toCSS).Permalink }}'>
+
<div class="notices {{ with .Get 0 -}}{{.}}{{else}}primary{{end}}">
{{with .Params}}
{{- if len $.Params | eq 2 -}}
diff --git a/layouts/shortcodes/panel.html b/layouts/shortcodes/panel.html
index 93180c6..7066691 100644
--- a/layouts/shortcodes/panel.html
+++ b/layouts/shortcodes/panel.html
@@ -1,5 +1,5 @@
{{ $_hugo_config := `{ "version": 1 }` }}
-<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/panel.scss" | toCSS).Permalink }}'>
+
<div class="card ">
{{- with .Get "header" -}}
diff --git a/layouts/shortcodes/tabs.html b/layouts/shortcodes/tabs.html
index 61958c8..6f4c943 100644
--- a/layouts/shortcodes/tabs.html
+++ b/layouts/shortcodes/tabs.html
@@ -1,6 +1,6 @@
{{ $_hugo_config := `{ "version": 1 }` }}
<!-- https://github.com/alex-shpak/hugo-book/blob/master/layouts/shortcodes/tabs.html -->
-<link rel="stylesheet" type="text/css" href='{{ (resources.Get "sass/shortcodes/tabs.scss" | toCSS).Permalink }}'>
+
{{ if .Inner }}{{ end }}
{{ $group := printf "tabs-%d" .Ordinal }}
diff --git a/static/js/checklist.js b/static/js/checklist.js
new file mode 100644
index 0000000..efe5b8d
--- /dev/null
+++ b/static/js/checklist.js
@@ -0,0 +1,276 @@
+
+var formConditions = [];
+
+$( document ).ready(function() {
+ $.each($("#TableOfContents ul li a"), function(i) {
+ id = $(this).attr("href")
+ id = id.substring(1);
+ $(this).parent().attr('id','toc-'+id)
+ $(this).before('<input type="checkbox" disabled readonly>');
+ });
+ // $.each(formConditions, function(i) {
+ // console.log(this.id, this.condition)
+ // })
+});
+
+
+function registerShowIf(elmID, condition) {
+ formConditions.unshift({id:elmID, condition:condition});
+}
+
+
+function formValue(formID, fieldName) {
+ var val = ""
+ var field = $("#"+formID +' [name='+fieldName+']')
+ if (field.attr("multiple") !== undefined) {
+ //multiple returns array
+ val = []
+ $.each(field.serializeArray(), function() {
+ if (this.name == fieldName) {
+ val.push(this.value)
+ }
+ });
+ }else{
+ //single return one scalar value
+ $.each($("#"+formID).serializeArray(), function() {
+ if (this.name == fieldName) {
+ val = this.value
+ }
+ });
+ }
+
+ return val
+}
+
+function formChange(id){
+ $.each(formConditions, function(i) {
+ conditionEvaluation = eval(this.condition)
+ var showDiv = $('#'+this.id)
+ var showDivFields = showDiv.find('input, select, textarea')
+ if (conditionEvaluation) {
+ showDiv.show()
+ showDivFields.prop("disabled", false);
+ }else{
+ showDiv.hide()
+ showDivFields.prop("disabled", true);
+ showDivFields.prop("checked",false)
+ }
+ });
+ updateTOC(id)
+}
+
+function updateTOC(formID) {
+ $.each($("#"+formID).children(), function(i) {
+ var zone = $(this).attr("ref")
+ var countNames = 0
+ var started = 0
+ if (zone !== undefined){
+ // Selectionne les input/select/textarea d'une zone
+ var lastName = ""
+ $.each($(this).find('input:not([disabled]), select:not([disabled]), textarea:not([disabled])'), function(j){
+ var name = $(this).attr("name")
+ if ( name != lastName ){
+ lastName = name
+ countNames++
+ if (this.tagName == "INPUT" && ($(this).attr("type") == "radio" || $(this).attr("type") == "checkbox") ){
+ if ($("#"+formID+" input[name="+name+"]:checked").length > 0){
+ started++
+ }
+ return
+ }
+ } else {
+ return
+ }
+
+ var tagName = this.tagName
+ if (tagName == 'INPUT'){
+ var type = $(this).attr("type")
+ if (type == "text"){
+ if ($(this).val() != ''){
+ started++
+ }
+ }else if (type == "radio" || type == "checkbox") {
+ if ($(this).prop("checked")){
+ started++
+ }
+ }
+ }else if (tagName == 'SELECT'){
+ if ($(this).attr("multiple")!==undefined){
+ if ($(this).val().length > 0){
+ started++
+ }
+ }else{
+ if ($(this).val() != ''){
+ started++
+ }
+ }
+ }else if (tagName == 'TEXTAREA'){
+ if ($(this).val() != ''){
+ started++
+ }
+ }else{
+
+ }
+ });
+ if (countNames > 0 ) {
+ var status = "ready"
+ if (started == countNames) {
+ status = "done"
+ $("#TableOfContents #toc-"+zone+" input").attr('checked',true)
+ $("#TableOfContents #toc-"+zone+" input").prop("indeterminate", false)
+ }else if (started >0){
+ status = "doing"
+ $("#TableOfContents #toc-"+zone+" input").attr('checked',false)
+ $("#TableOfContents #toc-"+zone+" input").prop("indeterminate", true)
+ }else{
+ status = "ready"
+ $("#TableOfContents #toc-"+zone+" input").attr('checked',false)
+ $("#TableOfContents #toc-"+zone+" input").prop("indeterminate", false)
+ }
+ $("#TableOfContents #toc-"+zone+"").removeClass('cl-ready cl-doing cl-done').addClass('cl-'+status);
+ }
+ }
+ });
+}
+
+
+function listenFormChange(id){
+ // Wrap each Zone with a div
+ var formChildren = $("#"+id).children()
+ var formChildrenLen = formChildren.length;
+ $.each(formChildren, function(i) {
+ if (this.tagName == "H2" || i+1 == formChildrenLen) {
+ this.parentNode.appendChild(newWrap);
+ // console.log("zone",newWrap)
+ // this.parentNode.appendChild(this); // decommenter si on veut sortir les h1
+ newWrap = wrap(this)
+ }else{
+ newWrap = wrap(this, newWrap)
+ }
+ });
+
+ // on form change update display
+ $("#"+id).bind('change', function(e) {
+ formChange(id)
+ });
+
+ // initial update display
+ formChange(id)
+}
+
+function formData(name){
+ return $("#"+name).serializeArray()
+}
+
+function slugify(a) {
+ return a.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
+}
+
+
+function downloadFile(formID){
+ var fileName = slugify($("#"+formID).attr("ref"))
+ var obj = {
+ at: new Date().toISOString(),
+ ref: "TODO",
+ url: document.location.protocol+"//"+document.location.host+document.location.pathname,
+ data: formData(formID)};
+ var filename = fileName+".checklist.json";
+ var blob = new Blob([JSON.stringify(obj)], {type: 'application/json'});
+ if (window.navigator && window.navigator.msSaveOrOpenBlob) {
+ window.navigator.msSaveOrOpenBlob(blob, filename);
+ } else{
+ var e = document.createEvent('MouseEvents'),
+ a = document.createElement('a');
+ a.download = filename;
+ a.href = window.URL.createObjectURL(blob);
+ a.dataset.downloadurl = ['application/json', a.download, a.href].join(':');
+ e.initEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ a.dispatchEvent(e);
+ }
+}
+
+function onChooseFile(event, onLoadFileHandler) {
+ if (typeof window.FileReader !== 'function')
+ throw ("The file API isn't supported on this browser.");
+ let input = event.target;
+ if (!input)
+ throw ("The browser does not properly implement the event object");
+ if (!input.files)
+ throw ("This browser does not support the `files` property of the file input.");
+ if (!input.files[0])
+ return undefined;
+ let file = input.files[0];
+ let fr = new FileReader();
+ fr.onload = onLoadFileHandler;
+ fr.readAsText(file);
+}
+
+
+
+
+function fillForm(formID){
+ return function (e,o){
+ jsonData = e.target.result
+ let obj = JSON.parse(jsonData)
+
+ currentUrl = document.location.protocol+"//"+document.location.host+document.location.pathname
+ if (obj.url != currentUrl) {
+ alert("Warning : this answer file was saved from a different page")
+ }
+ // check url with
+
+ $("#"+formID).deserialize(obj.data);
+ formChange(formID)
+ }
+}
+
+
+jQuery.fn.deserialize = function (data) {
+ var f = this,
+ map = {},
+ find = function (selector) { return f.is("form") ? f.find(selector) : f.filter(selector); };
+
+ jQuery.each(data, function () {
+ n = this.name
+ v = this.value
+ if (!(n in map)) {
+ map[n] = [];
+ }
+ map[n].push(v);
+ })
+ //Set values for all form elements in the data
+ jQuery.each(map, function (n, v) {
+ find("[name='" + n + "']").val(v);
+ })
+ //Clear all form elements not in form data
+ find("input:text,select,textarea").each(function () {
+ if (!(jQuery(this).attr("name") in map)) {
+ jQuery(this).val("");
+ }
+ })
+ find("input:checkbox:checked,input:radio:checked").each(function () {
+ if (!(jQuery(this).attr("name") in map)) {
+ this.checked = false;
+ }
+ })
+ return this;
+};
+
+
+
+ var wrap = function (toWrap, wrapper) {
+ wrapper = wrapper || document.createElement('div');
+ if (toWrap.tagName==='H2'){
+ $(wrapper).attr("ref",$(toWrap).attr("ref"))
+ $(wrapper).attr("todo","10")
+ $(wrapper).attr("raf","9") // reste à faire
+ $(wrapper).attr("raf_req","2") // reste à faire obligatoire
+ $(wrapper).attr("id","zone-"+$(toWrap).attr("ref"))
+ $(wrapper).attr("class","checklist-zone")
+ }
+
+ wrapper.appendChild(toWrap); // mettre else si on veut sortir les h1
+ return wrapper
+ };
+
+ var newWrap