Skip to content

Commit

Permalink
Merge pull request #2626 from MTES-MCT/feature/2609-technique-csp
Browse files Browse the repository at this point in the history
[Technique] Améliorer la CSP
  • Loading branch information
emilschn committed Jun 14, 2024
2 parents e99edff + 6df1f74 commit 9570b18
Show file tree
Hide file tree
Showing 104 changed files with 337 additions and 3,221 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ FEATURE_ASK_VISITE_ENABLE=1
FEATURE_OILHI_ENABLE=1
CRON_ENABLE=1
MAIL_ENABLE=1
CSP_ENABLE=1
ESABORA_CRON_CLOCK_SLEEP_INTERVAL=60 #second
ESABORA_CRON_SCHEDULE_SYNC_SISH='*/2 * * * *'
ESABORA_CRON_SCHEDULE_SYNC_SISH_INTERVENTION='*/3 * * * *'
Expand All @@ -47,7 +48,6 @@ MATOMO_SITE_ID=1
ZAPIER_OILHI_TOKEN=
ZAPIER_OILHI_USER_ID=
ZAPIER_OILHI_CREATE_AIRTABLE_RECORD_ZAP_ID=
SECURITY_CSP_HEADER_VALUE="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.matomo.cloud https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: blob: https://voxusagers.numerique.gouv.fr https://*.tile.openstreetmap.org https://cdn.jsdelivr.net https://jedonnemonavis.numerique.gouv.fr; connect-src 'self' https://api-adresse.data.gouv.fr https://cdn.matomo.cloud https://histologe.matomo.cloud https://koumoul.com https://sentry.incubateur.net; font-src 'self'; frame-src 'none'; object-src 'none';"
CHATBOT_ENABLE=0
MAINTENANCE_ENABLE=0
MAINTENANCE_BANNER_ENABLE=0
Expand Down
2 changes: 1 addition & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ FEATURE_OILHI_ENABLE=1
FEATURE_ASK_VISITE_ENABLE=1
CRON_ENABLE=1
MAIL_ENABLE=1
CSP_ENABLE=1
ESABORA_CRON_CLOCK_SLEEP_INTERVAL=60 #second
ESABORA_CRON_SCHEDULE_SYNC_SISH='*/2 * * * *'
ESABORA_CRON_SCHEDULE_SYNC_SISH_INTERVENTION='*/3 * * * *'
Expand All @@ -35,7 +36,6 @@ MATOMO_SITE_ID=1
ZAPIER_OILHI_TOKEN=
ZAPIER_OILHI_ID=
ZAPIER_OILHI_CREATE_AIRTABLE_RECORD_ZAP_ID=
SECURITY_CSP_HEADER_VALUE="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.matomo.cloud https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: blob: https://voxusagers.numerique.gouv.fr https://*.tile.openstreetmap.org https://cdn.jsdelivr.net https://jedonnemonavis.numerique.gouv.fr; connect-src 'self' https://api-adresse.data.gouv.fr https://cdn.matomo.cloud https://histologe.matomo.cloud https://koumoul.com https://sentry.incubateur.net; font-src 'self'; frame-src 'none'; object-src 'none';"
CHATBOT_ENABLE=0
MAINTENANCE_ENABLE=0
MAINTENANCE_BANNER_ENABLE=0
Expand Down
8 changes: 5 additions & 3 deletions assets/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ import './controllers/cookie_banner';
import './controllers/maintenance_banner';
import './controllers/activate_account/activate_account';
import './controllers/back_signalement_view/form_edit_modal';
import './controllers/back_signalement_edit_file/back_signalement_edit_file';
import './controllers/back_signalement_delete_file/back_signalement_delete_file';
import './controllers/back_signalement_view/form_upload_documents';
import './controllers/front_demande_lien_signalement/front_demande_lien_signalement';
import './controllers/back_signalement_view/input_autocomplete_bailleur';
import './controllers/back_signalement_view/form_cloture_modal';
import './controllers/back_signalement_view/form_acceptation_refus';
import './controllers/back_signalement_edit_file/back_signalement_edit_file';
import './controllers/back_signalement_delete_file/back_signalement_delete_file';
import './controllers/front_demande_lien_signalement/front_demande_lien_signalement';
import './controllers/front_suivi_signalement/front_suivi_signalement';
import './controllers/search_filter_form'
50 changes: 50 additions & 0 deletions assets/controllers/back_partner_view/form_partner.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,53 @@ if (document.querySelector('#partner_type')) {
histoUpdateFieldsVisibility()
})
}

const deletePartnerForm = document.querySelectorAll('form[name="deletePartner"]');
deletePartnerForm.forEach(form => {
form.addEventListener('submit', function(event) {
if (!confirm('Êtes-vous sûr de vouloir supprimer ce partenaire ?')) {
event.preventDefault();
}
});
});

const checkUserMail = (el) => {
let formData = new FormData();
formData.append('email', el.value)
formData.append('_token', el.getAttribute('data-token'))
fetch('/bo/partenaires/checkmail', {
method: 'POST',
body: formData
}).then(r => {
if (!r.ok) {
r.json().then((r) => {
el.classList.add('fr-input--error');
el.parentElement.classList.add('fr-input-group--error');
el.parentElement.querySelector('p.fr-error-text').innerText = r.error;
el.parentElement.querySelector('p.fr-error-text').classList.remove('fr-hidden');
document.querySelector('#user_create_form_submit').disabled = true;
document.querySelector('#user_edit_form_submit').disabled = true;
})
} else {
el.classList.remove('fr-input--error');
el.parentElement.classList.remove('fr-input-group--error');
el.parentElement.querySelector('p.fr-error-text').classList.add('fr-hidden');
document.querySelector('#user_create_form_submit').disabled = false;
document.querySelector('#user_edit_form_submit').disabled = false;
}
})
.catch(function (err) {
console.warn('Something went wrong.', err);
});
};

const emailInputs = document.querySelectorAll('.fr-input-email');
emailInputs.forEach(emailInput => {
emailInput.addEventListener('change', function() {
checkUserMail(this);
});

emailInput.addEventListener('input', function() {
checkUserMail(this);
});
});
32 changes: 32 additions & 0 deletions assets/controllers/back_signalement_view/form_acceptation_refus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const refusAffectationButtons = document.querySelectorAll('button[name="signalement-affectation-response[deny]"]');
refusAffectationButtons.forEach(button => {
button.addEventListener('click', function(event) {
if (!confirm('Êtes-vous certain de vouloir refuser ce signalement ?')) {
event.preventDefault();
}
});
});
const refusValidationButtons = document.querySelectorAll('button[name="signalement-validation-response[deny]"]');
refusValidationButtons.forEach(button => {
button.addEventListener('click', function(event) {
if (!confirm('Êtes-vous certain de vouloir refuser ce signalement ?')) {
event.preventDefault();
}
});
});
const cancelRefusButton = document.querySelectorAll('button[name="signalement-affectation-response[accept]]"]');
cancelRefusButton.forEach(button => {
button.addEventListener('click', function(event) {
if (!confirm('Êtes-vous certain de vouloir accepter ce signalement ?')) {
event.preventDefault();
}
});
});
const validationButton = document.querySelectorAll('button[name="signalement-validation-response[accept]"]');
validationButton.forEach(button => {
button.addEventListener('click', function(event) {
if (!confirm('Êtes-vous certain de vouloir valider ce signalement ?')) {
event.preventDefault();
}
});
});
7 changes: 7 additions & 0 deletions assets/controllers/form_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ document.querySelectorAll('.fr-disable-button-when-submit')?.forEach(element =>
}
})
})

const selects = document.querySelectorAll('.fr-select-submit');
selects.forEach(select => {
select.addEventListener('change', function() {
this.form.submit();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,12 @@ document.addEventListener("DOMContentLoaded", function() {
elmnt = document.getElementById(window.location.hash.substring(1))
elmnt.scrollIntoView({behavior:'instant'})
}
})
})
const closeNoticeButtons = document.querySelectorAll('button[name="closeNotice"]');
closeNoticeButtons.forEach(button => {
button.addEventListener('click', function() {
const notice = this.parentNode.parentNode.parentNode;
notice.parentNode.removeChild(notice);
});
});

56 changes: 56 additions & 0 deletions assets/controllers/search_filter_form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const setBadge = (el) => {
let container = el.parentElement.querySelector('.selected__value');
if (el.value !== '') {
let badge = document.createElement('span');
badge.classList.add('fr-badge', 'fr-badge--success', 'fr-m-1v')
badge.innerText = el.selectedOptions[0].text;
let input = document.createElement('input');
input.type = "hidden";
input.name = `${el.id}[]`;
input.value = el.value;
container.append(input);
badge.setAttribute('data-value', el.value);
container.querySelector('.fr-badge:not([data-value])')?.classList?.add('fr-hidden');
container.append(badge)
el.selectedOptions[0].classList.add('fr-hidden')
badge.addEventListener('click', (event) => {
console.log(badge)
removeBadge(badge);
})
} else {
container.querySelectorAll('.fr-badge[data-value]').forEach(badge => {
removeBadge(badge);
})
}
return false;
}
const removeBadge = (badge) => {
let val = badge.getAttribute('data-value');
let input = badge.parentElement.querySelector(`input[value="${val}"]`);
let select = badge?.parentElement?.parentElement?.querySelector(`select`) ?? badge?.parentElement?.parentElement?.querySelector(`input[type="date"]`);
select.querySelector(`option[value="${val}"]`)?.classList?.remove('fr-hidden');
input?.remove();
let badges = badge.parentElement.querySelectorAll('.fr-badge[data-value]').length !== 1;
console.log(badge.parentElement.querySelectorAll('.fr-badge[data-value]').length)
if (!badges) {
badge?.parentElement?.querySelector('.fr-badge:not([data-value])')?.classList?.remove('fr-hidden');
if (select.tagName === 'SELECT')
select.options[0].selected = true;
}
badge.remove();
}
document?.querySelectorAll('.select-search-filter-form')?.forEach(select => {
select.addEventListener(
"change",
() => {
setBadge(select);
},
false,
);
})

document?.querySelectorAll('[data-removable="true"]')?.forEach(removale => {
removale.addEventListener('click', () => {
removeBadge(removale);
})
})
13 changes: 13 additions & 0 deletions assets/styles/histologe.scss
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@ legend.required::after, label.required::after {
display: block;
}

.fr-display-inline {
display: inline;
}

.fr-display-none {
display: none;
}

.fr-display-inline-flex {
display: inline-flex !important;
Expand Down Expand Up @@ -769,6 +776,12 @@ ul + p {
border-radius: 50%;
}
}
.logo-width {
width: 3.5rem;
}
.logo-height {
height: 5.625rem;
}

#tags_active_container, #tags_inactive_container{
.fr-badge{cursor: pointer;}
Expand Down
15 changes: 15 additions & 0 deletions config/app/csp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
parameters:
csp_parameters:
default-src: "'none'"
script-src: "'self' 'unsafe-inline' 'unsafe-eval' https://cdn.matomo.cloud/histologe.matomo.cloud/matomo.js https://cdn.jsdelivr.net/npm/leaflet@1.7.1/dist/ https://cdn.jsdelivr.net/npm/leaflet.markercluster@1.5.3/dist/ https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/ https://cdn.jsdelivr.net/npm/tippy.js@6/dist/ https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/ https://cdn.jsdelivr.net/npm/tinymce@7.1.2/"
style-src: "'self' 'unsafe-inline' https://cdn.jsdelivr.net/npm/leaflet@1.7.1/dist/ https://cdn.jsdelivr.net/npm/leaflet.markercluster@1.5.3/dist/ https://cdn.jsdelivr.net/npm/leaflet.markercluster@1.5.3/dist/ https://cdn.jsdelivr.net/npm/tippy.js@6/dist/ https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/ https://cdn.jsdelivr.net/npm/tinymce@7.1.2/"
style-src-attr: "'self' 'unsafe-inline'"
img-src: "'self' data: blob: https://voxusagers.numerique.gouv.fr https://*.tile.openstreetmap.org https://cdn.jsdelivr.net https://jedonnemonavis.numerique.gouv.fr"
connect-src: "'self' https://api-adresse.data.gouv.fr https://cdn.matomo.cloud https://histologe.matomo.cloud https://koumoul.com https://sentry.incubateur.net"
font-src: "'self'"
frame-src: "'none'"
object-src: "'none'"
base-uri: "'self'"
form-action: "'self'"
frame-ancestors: "'none'"
media-src: "'self'"
7 changes: 7 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ imports:
- { resource: 'app/suivi_messages.yaml'}
- { resource: 'app/cron_scheduler.yaml'}
- { resource: 'app/export_pdf.yaml'}
- { resource: 'app/csp.yaml'}
parameters:
.container.dumper.inline_factories: true
uploads_dir: '%kernel.project_dir%/uploaded_files/signalement/'
Expand All @@ -30,6 +31,7 @@ parameters:
token_lifetime: '1 day'
cron_enable: '%env(bool:CRON_ENABLE)%'
mail_enable: '%env(bool:MAIL_ENABLE)%'
csp_enable: '%env(bool:CSP_ENABLE)%'
feature_ask_visite: '%env(FEATURE_ASK_VISITE_ENABLE)%'
feature_oilhi_enable: '%env(bool:FEATURE_OILHI_ENABLE)%'
feature_signalement_liste_enable: '%env(bool:FEATURE_LIST_FILTER_ENABLE)%'
Expand Down Expand Up @@ -62,6 +64,11 @@ services:
- '../src/Kernel.php'
- '../src/Tests/'

App\EventListener\ContentSecurityPolicyListener:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }

App\EventListener\LoginListener:
tags:
- { name: 'kernel.event_listener', event: 'security.interactive_login' }
Expand Down
Loading

0 comments on commit 9570b18

Please sign in to comment.