diff --git a/backend/core/forms.py b/backend/core/forms.py index 6108ae4..ad26651 100644 --- a/backend/core/forms.py +++ b/backend/core/forms.py @@ -10,11 +10,40 @@ class OrganizationForm(forms.ModelForm): 'network_infrastructure', 'remote_workforce_percentage', 'third_party_vendor_access', 'internal_software_development', 'geographic_scope', 'customer_base', 'customer_type', 'product_portfolio', 'supplier_base', 'it_infrastructure', 'intellectual_property', - 'sensitive_data', 'integration_level' + 'sensitive_data','sensitive_data_types', 'integration_level', 'ip_value', 'change_rate', 'threat_actors' ] widgets = { 'compliance_frameworks': forms.CheckboxSelectMultiple(), 'it_infrastructure': forms.CheckboxSelectMultiple(), 'intellectual_property': forms.CheckboxSelectMultiple(), 'sensitive_data': forms.CheckboxSelectMultiple(), + 'threat_actors': forms.CheckboxSelectMultiple(), + 'sensitive_data_types': forms.CheckboxSelectMultiple(), } + + def clean(self): + cleaned_data = super().clean() + + # Handle compliance_frameworks "Other" + frameworks = cleaned_data.get('compliance_frameworks', []) + other_framework = self.data.get('compliance_frameworks_other', '').strip() + if 'other' in frameworks and other_framework: + frameworks = [fw for fw in frameworks if fw != 'other'] + frameworks.append(other_framework) + cleaned_data['compliance_frameworks'] = frameworks + + # Handle industry_sector "Other" + sector = cleaned_data.get('industry_sector') + sector_other = self.data.get('industry_sector_other', '').strip() + if sector == 'other' and sector_other: + cleaned_data['industry_sector'] = sector_other + + # Handle sensitive_data_types + types = cleaned_data.get('sensitive_data_types') or [] + other_type = self.data.get('sensitive_data_types_other', '').strip() + if 'other' in types and other_type: + types = [t for t in types if t != 'other'] + types.append(other_type) + cleaned_data['sensitive_data_types'] = types + + return cleaned_data diff --git a/backend/core/migrations/0010_organization_change_rate_organization_ip_value_and_more.py b/backend/core/migrations/0010_organization_change_rate_organization_ip_value_and_more.py new file mode 100644 index 0000000..1a22c73 --- /dev/null +++ b/backend/core/migrations/0010_organization_change_rate_organization_ip_value_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 5.1.3 on 2025-04-23 15:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0009_documentriskcontrol_likelihood_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='organization', + name='change_rate', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AddField( + model_name='organization', + name='ip_value', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AddField( + model_name='organization', + name='threat_actors', + field=models.JSONField(blank=True, null=True), + ), + migrations.AlterField( + model_name='organization', + name='it_dependency', + field=models.CharField(help_text='On a scale from 1-10, how dependent is your business operations on technology?', max_length=255), + ), + ] diff --git a/backend/core/migrations/0011_alter_organization_data_sensitivity.py b/backend/core/migrations/0011_alter_organization_data_sensitivity.py new file mode 100644 index 0000000..5aaa257 --- /dev/null +++ b/backend/core/migrations/0011_alter_organization_data_sensitivity.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.3 on 2025-04-23 15:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0010_organization_change_rate_organization_ip_value_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='organization', + name='data_sensitivity', + field=models.CharField(blank=True, help_text='...', max_length=20, null=True), + ), + ] diff --git a/backend/core/migrations/0012_organization_sensitive_data_types.py b/backend/core/migrations/0012_organization_sensitive_data_types.py new file mode 100644 index 0000000..be891a0 --- /dev/null +++ b/backend/core/migrations/0012_organization_sensitive_data_types.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.3 on 2025-04-23 15:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0011_alter_organization_data_sensitivity'), + ] + + operations = [ + migrations.AddField( + model_name='organization', + name='sensitive_data_types', + field=models.JSONField(blank=True, help_text='What type of sensitive data does your organization handle?', null=True), + ), + ] diff --git a/backend/core/migrations/0013_alter_organization_change_rate_and_more.py b/backend/core/migrations/0013_alter_organization_change_rate_and_more.py new file mode 100644 index 0000000..a43ce1d --- /dev/null +++ b/backend/core/migrations/0013_alter_organization_change_rate_and_more.py @@ -0,0 +1,40 @@ +# Generated by Django 5.1.3 on 2025-04-23 17:08 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0012_organization_sensitive_data_types'), + ] + + operations = [ + migrations.AlterField( + model_name='organization', + name='change_rate', + field=models.CharField(blank=True, help_text='How frequently does your organization undergo significant technology or business changes?', max_length=20, null=True), + ), + migrations.AlterField( + model_name='organization', + name='data_sensitivity', + field=models.CharField(default=django.utils.timezone.now, help_text='Overall Sensitivity Level of Data Processed: Subjective rating of the value and impact of the data your organization processes.', max_length=20), + preserve_default=False, + ), + migrations.AlterField( + model_name='organization', + name='ip_value', + field=models.CharField(blank=True, help_text="Intellectual Property (IP) Value: Select best description of IP's importance to the business model.", max_length=20, null=True), + ), + migrations.AlterField( + model_name='organization', + name='network_infrastructure', + field=models.CharField(blank=True, help_text="What best describes your organization's network infrastructure model?", max_length=20, null=True), + ), + migrations.AlterField( + model_name='organization', + name='threat_actors', + field=models.JSONField(blank=True, help_text='Which types of threat actors are most relevant to your organization (e.g., cybercriminals, insiders, nation-states)?', null=True), + ), + ] diff --git a/backend/core/models.py b/backend/core/models.py index bfdd03f..0a38687 100644 --- a/backend/core/models.py +++ b/backend/core/models.py @@ -51,9 +51,8 @@ class Organization(models.Model): critical_applications = models.CharField(max_length=20, help_text="How many critical business applications do your employees use daily?") compliance_frameworks = models.JSONField(help_text="Which regulatory frameworks is your organization required to comply with?") # Stores selected compliance frameworks as a list industry_sector = models.CharField(max_length=255,help_text="What is your primary industry sector?") - it_dependency = models.IntegerField(help_text="On a scale from 1-10, how dependent is your business operations on technology?") - data_sensitivity = models.CharField(max_length=20, help_text="What level of sensitive data does your organization process?") - network_infrastructure = models.CharField(max_length=20, help_text="What best describes your organization's network infrastructure model?") + it_dependency = models.CharField(max_length=255, help_text="On a scale from 1-10, how dependent is your business operations on technology?") + data_sensitivity = models.CharField(max_length=20, help_text="Overall Sensitivity Level of Data Processed: Subjective rating of the value and impact of the data your organization processes.") remote_workforce_percentage = models.CharField(max_length=20, help_text="What percentage of your workforce operates remotely?") third_party_vendor_access = models.CharField(max_length=20, help_text="How many third-party vendors have access to your systems?") internal_software_development = models.CharField(max_length=20, help_text="What is the extent of your internal software development activities?") @@ -66,7 +65,11 @@ class Organization(models.Model): intellectual_property = models.JSONField(null=True, blank=True, help_text="How does your organization protect and manage intellectual property?") # Stores selected IP protection types as a list sensitive_data = models.JSONField(null=True, blank=True, help_text="What type of sensitive data does your organization handle?") # Stores selected sensitive data types as a list integration_level = models.CharField(max_length=20, null=True, blank=True, help_text="How integrated are your critical business systems?") - + network_infrastructure = models.CharField(max_length=20, null=True, blank=True, help_text="What best describes your organization's network infrastructure model?") + ip_value = models.CharField(max_length=20, null=True, blank=True, help_text="Intellectual Property (IP) Value: Select best description of IP's importance to the business model.") + change_rate = models.CharField(max_length=20, null=True, blank=True, help_text="How frequently does your organization undergo significant technology or business changes?") + threat_actors = models.JSONField(null=True, blank=True, help_text="Which types of threat actors are most relevant to your organization (e.g., cybercriminals, insiders, nation-states)?") + sensitive_data_types = models.JSONField(null=True, blank=True, help_text="What type of sensitive data does your organization handle?") risks = models.ManyToManyField('Risk', related_name='organizations', blank=True) def __str__(self): diff --git a/backend/core/static/js/formHandling.js b/backend/core/static/js/formHandling.js index 1adef60..05d8c47 100644 --- a/backend/core/static/js/formHandling.js +++ b/backend/core/static/js/formHandling.js @@ -2,6 +2,18 @@ document.addEventListener('DOMContentLoaded', (event) => { const form = document.querySelector('form'); const formElements = form.elements; + const instructionsModal = new bootstrap.Modal(document.getElementById('instructionsModal')); + instructionsModal.show(); + + document.getElementById('startModalBtn').addEventListener('click', function() { + hideNavElementsAndQuestions(); + document.currentQuestion = 0; + showQuestion('q0'); + setButtonVisiblity('next', true); + setButtonVisiblity('back', true); + setNextButtonAvailability(); + }); + // Load saved form state /* loadFormState(formElements); @@ -76,24 +88,32 @@ function setNextButtonAvailability() { const submitButton = document.getElementById('submit'); // check if any input in the current question is checked, or filled in case it is a text input let nextEnabled = false; - const inputs = currentQuestion.querySelectorAll('input, select, textarea'); - for (let input of inputs) { - // if the input is not visible, skip it - if (input.checkVisibility() === false) { - continue; + if (document.currentQuestion === 0) { + const name = document.getElementById('name'); + const email = document.getElementById('email'); + if (name && email && name.value.trim() && email.value.trim()) { + nextEnabled = true; } - if (input.type === 'checkbox' || input.type === 'radio') { - if (input.checked) { - nextEnabled = true; - break; + } else { + const inputs = currentQuestion.querySelectorAll('input, select, textarea'); + for (let input of inputs) { + if (input.checkVisibility() === false){ + continue; } - } else { - if (input.value) { - nextEnabled = true; - break; + if (input.type === 'checkbox' || input.type === 'radio') { + if (input.checked) { + nextEnabled = true; + break; + } + } else { + if (input.value) { + nextEnabled = true; + break; + } } } } + nextButton.disabled = !nextEnabled; submitButton.disabled = !nextEnabled; } diff --git a/backend/core/templates/signup.html b/backend/core/templates/signup.html index 946d712..5a5b334 100644 --- a/backend/core/templates/signup.html +++ b/backend/core/templates/signup.html @@ -9,55 +9,57 @@

Risk Assessment Questions


- {% csrf_token %} - -
- -
-
- -
- Name of the Organization that will appear in the - report. + {% if form.errors %} +
+ {{ form.errors }}
+ {% endif %} + {% csrf_token %} + - -
- +
+
- + +
- Email of the person responsible for using Risklet. - Report - and - magic link for login will be sent to this email. + + Enter the organization name and your email address. Both fields are required to continue. +
-
- +
+ + + Select one range - Scale factor for internal user base & potential insider risk +
- - + +
- - + +
- - + +
- - + + +
+
+ + +
+
+ +
Helps determine the scale of IT infrastructure and security @@ -65,29 +67,39 @@
-
- +
+
- - + +
- - + +
- - + +
- - + + +
+
+ + +
+
+ +
Indicates available resources for cybersecurity investments @@ -96,7 +108,7 @@
-
+

@@ -127,55 +139,64 @@
-
- +
+
- +
- + + +
+
+ + +
+
+ + +
+
+
- - + +
- +
- - + +
- - + +
- - + + +
+
+ + +
- - -
-
- - + +
Identifies mandatory security controls and compliance @@ -183,86 +204,166 @@
-
- +
+
- - Determines industry-specific threats, regulations, and - security - best practices applicable to your business. +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +
+
+ + Determines industry-specific threats, regulations, and security best practices applicable to your business. +
-
- +
+
- -
- Not dependent at all - Heavily dependent +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
Measures the potential business impact of IT disruptions and helps prioritize security investments.
- -
- + +
+
- - + +
- - + +
- - + +
- - + +
- - + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
Assesses the potential impact of data breaches and @@ -270,36 +371,86 @@ required security controls.
- -
- + +
+
- - + +
- - + +
- - + +
- - + +
- Helps understand the complexity and vulnerability points in - your - technical environment. + + Subjective rating of the value and impact of the data your organization processes. + +
+ + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + Indicates the strategic importance of intellectual property to your organization. +
@@ -364,195 +515,34 @@
- +
- - + +
- -
-
- - -
-
- - +
Determines the need for secure development practices and application security measures.
- - -
- - - -
-
-
- -
-
- Click Next if you want to provide more details. Each - question is - optional. -
- - - - - -
- - - -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- Determines exposure to different cybersecurity - regulations. -
- - -
- -
-
-
- - -
-
- - -
-
- - -
-
- Assesses potential impact of data breaches. -
- - - -
- -
-
-
- - -
-
- - -
-
- - -
-
- Defines data protection requirements. -
- - - -
- -
-
-
- - -
-
- - -
-
- - -
-
- Indicates the variety of systems requiring - protection. -
- - -
- -
-
-
- - -
-
- - -
-
- - -
-
- Assesses third-party cybersecurity risks. -
- + -
+

@@ -585,8 +575,217 @@ Determines specific cybersecurity controls.
- + + +
+ + + +
+
+
+ +
+
+ Click Next if you want to provide more details. Each + question is + optional. +
+ + + + + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ Helps understand the complexity and vulnerability points in + your + technical environment. +
+ + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ Determines exposure to different cybersecurity + regulations. +
+ + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ Assesses potential impact of data breaches. +
+ + + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ Defines data protection requirements. +
+ + + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ Indicates the variety of systems requiring + protection. +
+ +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ Assesses third-party cybersecurity risks. +
+ + +

@@ -622,37 +821,37 @@
-
+

-
-
-
-
-
-
@@ -661,36 +860,121 @@
-
- +
+
- - + +
- - + +
- - + +
- - + +
Evaluates potential for cascade failures.
+ +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + Higher change rates can increase risk and require more robust change management. + +
+ + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + Helps prioritize security controls and monitoring based on likely threats. + +
+ +
@@ -700,6 +984,32 @@
+ + {% endblock content %} {% block bottom %}