diff --git a/assets/styles/_base.scss b/assets/styles/_base.scss
index a10ab0d..263cbad 100644
--- a/assets/styles/_base.scss
+++ b/assets/styles/_base.scss
@@ -50,3 +50,9 @@ p {
margin-top: $size-spacer-lg;
}
}
+
+ol {
+ li {
+ margin: 1em 0;
+ }
+}
diff --git a/assets/styles/_form.scss b/assets/styles/_form.scss
index 18b2ca5..b122a26 100644
--- a/assets/styles/_form.scss
+++ b/assets/styles/_form.scss
@@ -4,10 +4,9 @@ form {
display: grid;
gap: $size-spacer-md;
- // Form groups (label + input)
- > div > div {
+ > div {
display: grid;
- gap: $size-spacer-sm;
+ gap: $size-spacer-md;
}
// Used for errors in forms
@@ -40,6 +39,16 @@ form {
font-weight: bolder;
display: block;
}
+
+ .radio {
+
+ input {
+ vertical-align: center;
+ display: inline-block;
+ width: auto;
+ }
+
+ }
}
button, .btn {
diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml
index 42ea0af..ba60fb5 100644
--- a/config/packages/twig.yaml
+++ b/config/packages/twig.yaml
@@ -1,6 +1,6 @@
twig:
default_path: '%kernel.project_dir%/templates'
- form_themes: [ 'foundation_6_layout.html.twig' ]
+ form_themes: [ 'bootstrap_3_layout.html.twig' ]
globals:
report_email: '%env(REPORT_EMAIL)%'
app_name: '%env(APP_NAME)%'
diff --git a/migrations/Version20240609192945.php b/migrations/Version20240609192945.php
new file mode 100644
index 0000000..959ddc1
--- /dev/null
+++ b/migrations/Version20240609192945.php
@@ -0,0 +1,51 @@
+addSql('CREATE TABLE complaint (id UUID NOT NULL, status_id UUID NOT NULL, email VARCHAR(200) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, money_sent DOUBLE PRECISION DEFAULT NULL, country VARCHAR(100) NOT NULL, code VARCHAR(200) NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_5F2732B56BF700BD ON complaint (status_id)');
+ $this->addSql('COMMENT ON COLUMN complaint.id IS \'(DC2Type:uuid)\'');
+ $this->addSql('COMMENT ON COLUMN complaint.status_id IS \'(DC2Type:uuid)\'');
+ $this->addSql('COMMENT ON COLUMN complaint.created_at IS \'(DC2Type:datetime_immutable)\'');
+ $this->addSql('CREATE TABLE complaint_report (id UUID NOT NULL, complaint_id UUID NOT NULL, report_id UUID NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_E66CBA46EDAE188E ON complaint_report (complaint_id)');
+ $this->addSql('CREATE UNIQUE INDEX UNIQ_E66CBA464BD2A4C0 ON complaint_report (report_id)');
+ $this->addSql('COMMENT ON COLUMN complaint_report.id IS \'(DC2Type:uuid)\'');
+ $this->addSql('COMMENT ON COLUMN complaint_report.complaint_id IS \'(DC2Type:uuid)\'');
+ $this->addSql('COMMENT ON COLUMN complaint_report.report_id IS \'(DC2Type:uuid)\'');
+ $this->addSql('CREATE TABLE complaint_status (id UUID NOT NULL, name VARCHAR(100) NOT NULL, has_replied BOOLEAN NOT NULL, has_sent_sensitive_data BOOLEAN NOT NULL, has_sent_money BOOLEAN NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('COMMENT ON COLUMN complaint_status.id IS \'(DC2Type:uuid)\'');
+ $this->addSql('ALTER TABLE complaint ADD CONSTRAINT FK_5F2732B56BF700BD FOREIGN KEY (status_id) REFERENCES complaint_status (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE complaint_report ADD CONSTRAINT FK_E66CBA46EDAE188E FOREIGN KEY (complaint_id) REFERENCES complaint (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE complaint_report ADD CONSTRAINT FK_E66CBA464BD2A4C0 FOREIGN KEY (report_id) REFERENCES report (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->addSql('ALTER TABLE complaint DROP CONSTRAINT FK_5F2732B56BF700BD');
+ $this->addSql('ALTER TABLE complaint_report DROP CONSTRAINT FK_E66CBA46EDAE188E');
+ $this->addSql('ALTER TABLE complaint_report DROP CONSTRAINT FK_E66CBA464BD2A4C0');
+ $this->addSql('DROP TABLE complaint');
+ $this->addSql('DROP TABLE complaint_report');
+ $this->addSql('DROP TABLE complaint_status');
+ }
+}
diff --git a/src/Controller/ComplaintController.php b/src/Controller/ComplaintController.php
new file mode 100644
index 0000000..ec423c8
--- /dev/null
+++ b/src/Controller/ComplaintController.php
@@ -0,0 +1,67 @@
+createForm(NewComplaintType::class, $complaint);
+ $complaintForm->handleRequest($request);
+
+ if ($complaintForm->isSubmitted() && $complaintForm->isValid()) {
+
+ $element = $complaintForm->get('element');
+ $report = $domainService->getReport($element->getData());
+
+ if($report->isSafe()){
+ $element->addError(new FormError("This is not a fraudulent element."));
+ }else{
+
+ $complaintReport = new ComplaintReport($complaint, $report);
+
+ $em->persist($complaintReport);
+ $em->flush();
+
+ return $this->redirectToRoute('complaint_edit', [
+ 'id' => $complaint->getId(),
+ 'code' => $complaint->getCode()
+ ]);
+
+
+ }
+ }
+
+ return $this->renderForm('complaint/index.html.twig', [
+ 'complaintForm' => $complaintForm,
+ ]);
+ }
+
+
+ #[Route('/{id}/{code}/edit', name: 'edit')]
+ public function edit(Complaint $complaint, $code): Response
+ {
+ if($complaint->getCode() !== $code) {
+ throw $this->createNotFoundException('The code is not valid');
+ }
+
+ return $this->renderForm('complaint/show.html.twig', [
+ 'complaint' => $complaint,
+ ]);
+ }
+}
diff --git a/src/DataFixtures/ComplaintFixtures.php b/src/DataFixtures/ComplaintFixtures.php
new file mode 100644
index 0000000..48c462f
--- /dev/null
+++ b/src/DataFixtures/ComplaintFixtures.php
@@ -0,0 +1,66 @@
+complaintStatusRepository->findAll();
+ $countries = Countries::getCountryCodes();
+ $domains = $this->domainRepository->findAll();
+
+
+ $letters = range("a", "z");
+ foreach ($letters as $letter) {
+
+ $complaint = new Complaint();
+ $complaint->setCountry($countries[array_rand($countries)]);
+
+ $complaint->setEmail("$letter@example.com");
+
+ $complaint->setStatus($statuses[array_rand($statuses)]);
+
+ shuffle($domains);
+ for ($i = 0; $i < rand(1, 5); $i++) {
+
+ $domain = $domains[$i];
+
+ $report = $this->domainService->getReport("http://$domain");
+ $complaintReport = new ComplaintReport($complaint, $report);
+ $manager->persist($complaintReport);
+
+ }
+
+ $manager->persist($complaint);
+ }
+
+ $manager->flush();
+ }
+
+ public function getDependencies()
+ {
+ return [
+ DomainFixtures::class,
+ ComplaintStatusFixtures::class,
+ ];
+ }
+}
diff --git a/src/DataFixtures/ComplaintStatusFixtures.php b/src/DataFixtures/ComplaintStatusFixtures.php
new file mode 100644
index 0000000..e674fed
--- /dev/null
+++ b/src/DataFixtures/ComplaintStatusFixtures.php
@@ -0,0 +1,34 @@
+ "Got contacted",
+ 1 => "Got contacted, replied",
+ 2 => "Got contacted, replied, sent sensitive data",
+ 3 => "Got contacted, replied, sent sensitive data, sent money",
+ ];
+
+ foreach ($statuses as $index => $name) {
+ $status = new ComplaintStatus();
+ $status->setName($name);
+
+ $status->setHasReplied($index > 0);
+ $status->setHasSentSensitiveData($index > 1);
+ $status->setHasSentMoney($index > 2);
+
+ $manager->persist($status);
+ }
+
+ $manager->flush();
+ }
+}
diff --git a/src/Entity/Complaint/Complaint.php b/src/Entity/Complaint/Complaint.php
new file mode 100644
index 0000000..b958cbf
--- /dev/null
+++ b/src/Entity/Complaint/Complaint.php
@@ -0,0 +1,159 @@
+setCreatedAt(new \DateTimeImmutable('now'));
+ $this->resetCode();
+ $this->complaintReports = new ArrayCollection();
+ }
+
+ public function getEmail(): ?string
+ {
+ return $this->email;
+ }
+
+ public function setEmail(string $email): static
+ {
+ $this->email = $email;
+
+ return $this;
+ }
+
+ public function getMoneySent(): ?float
+ {
+ return $this->moneySent;
+ }
+
+ public function setMoneySent(?float $moneySent): static
+ {
+ $this->moneySent = $moneySent;
+
+ return $this;
+ }
+
+ public function getCountry(): ?string
+ {
+ return $this->country;
+ }
+
+ public function setCountry(string $country): static
+ {
+ $this->country = $country;
+
+ return $this;
+ }
+
+ public function getCode(): ?string
+ {
+ return $this->code;
+ }
+
+ public function resetCode(): static
+ {
+
+ $this->code = bin2hex(random_bytes(16));
+
+ return $this;
+ }
+
+ public function getCreatedAt(): ?\DateTimeImmutable
+ {
+ return $this->createdAt;
+ }
+
+ private function setCreatedAt(\DateTimeImmutable $createdAt): static
+ {
+ $this->createdAt = $createdAt;
+
+ return $this;
+ }
+
+ public function getStatus(): ?ComplaintStatus
+ {
+ return $this->status;
+ }
+
+ public function setStatus(?ComplaintStatus $status): static
+ {
+ $this->status = $status;
+
+ return $this;
+ }
+
+ /**
+ * @return Collection
+ {{ app_name }} is an independent platform.
+ In case you are a victim of a scam, you must also contact your local police department.
+
+ This page allows the collection of evidence of fraudulent activities
+ that can be used by law enforcement and organizations in case of an investigation.
+ All data provided here will be stored and may be used for further analysis, including by third parties.
+
+ You can also report an email by forwarding it to {{ report_email }}.
+
+
+
+ If you received a potential scam, fraudulent activity, or any other concerning behavior, please report it immediately by forwarding it to {{ report_email }}.
+ {{ block('title') }}
+
+ {{ block('title') }}
+
+ What to do?
+
+
+
+
+
+
+
+ {% if complaint.status.hasReplied %}
+ Cut all communication with the sender.
+ Do not reply to any email.
+ Do not click on any links or download any attachments.
+ {% else %}
+ Do not reply to the email.
+ {% endif %}
+ Do not click on any links or download any attachments.
+
+ Regarding the money you sent, contact your bank or credit card company immediately.
+ They might be able to cancel the transfer.
+ If you sent money through a service like Western Union, MoneyGram or PayPal, contact them as well.
+ There is a chance that the money has not been picked up yet, but you need to act quickly.
+
+ If you sent your ID, Social Security Number, or any other sensitive information that might expose you to identity theft,
+ contact your local police department. You should also contact your bank and credit card companies regarding that matter.
+
+ Add any other information you have to this report.
+ {% if complaint.status.hasSentSensitiveData or complaint.status.hasSentMoney%}
+ Only take the time to do it once you have taken the necessary steps to protect yourself.
+ {% endif %}
+ Reported
+
+
+ {% for report in complaint.reports %}
+
+
+
+ {% if report_email %}
+
+
+ {% endfor %}
+ {{ report.value }}
+
+
+ {{ report.domain }}
+
+
+ Report your emails
+
- If you received a potential scam, fraudulent activity, or any other concerning behavior, please report it immediately by forwarding it to {{ report_email }}. + If you suspect or have encountered a scam or fraudulent activity involving {{ domain }}, + please report it immediately: +
+ {% endif %} @@ -81,7 +85,7 @@This domain has been checked {{ reports|length }} times. {% if domain.analysis.rating.isDangerous %} - This number can potentially correspond to the number of uncovered fraud schemes commited via {{ domain }}. + This number can potentially correspond to the number of uncovered fraud schemes committed via {{ domain }}. {% endif %}