diff --git a/assets/pasted-20251115-222453-fbd77111.jpg b/assets/pasted-20251115-222453-fbd77111.jpg new file mode 100644 index 0000000..2219511 --- /dev/null +++ b/assets/pasted-20251115-222453-fbd77111.jpg @@ -0,0 +1,148 @@ + + + + + Page not found at /assets/vm-shot-2025-11-15T22-23-11-632Z.jpg + + + + +
+

Page not found (404)

+ + + + + + + + + + + +
Request Method:GET
Request URL:http://muhammad-ishraq.dev.flatlogic.app/assets/vm-shot-2025-11-15T22-23-11-632Z.jpg
+
+ +
+ +

+ Using the URLconf defined in config.urls, + Django tried these URL patterns, in this order: +

+
    + +
  1. + + + admin/ + + + +
  2. + +
  3. + + + + + + + + + [name='index'] + + +
  4. + +
  5. + + + + + + + + analyze/ + [name='analyze'] + + +
  6. + +
  7. + + + + + + + + signup/ + [name='signup'] + + +
  8. + +
  9. + + + + + + + + login/ + [name='login'] + + +
  10. + +
  11. + + + + + + + + logout/ + [name='logout'] + + +
  12. + +
+

+ + The current path, assets/vm-shot-2025-11-15T22-23-11-632Z.jpg, + + didn’t match any of these. +

+ +
+ + + + diff --git a/assets/vm-shot-2025-11-15T22-23-11-632Z.jpg b/assets/vm-shot-2025-11-15T22-23-11-632Z.jpg new file mode 100644 index 0000000..311ef1c Binary files /dev/null and b/assets/vm-shot-2025-11-15T22-23-11-632Z.jpg differ diff --git a/browser_extension/icons/icon128.png b/browser_extension/icons/icon128.png new file mode 100644 index 0000000..c730e43 Binary files /dev/null and b/browser_extension/icons/icon128.png differ diff --git a/browser_extension/icons/icon16.png b/browser_extension/icons/icon16.png new file mode 100644 index 0000000..83b0903 Binary files /dev/null and b/browser_extension/icons/icon16.png differ diff --git a/browser_extension/icons/icon48.png b/browser_extension/icons/icon48.png new file mode 100644 index 0000000..b59bc4c Binary files /dev/null and b/browser_extension/icons/icon48.png differ diff --git a/browser_extension/manifest.json b/browser_extension/manifest.json new file mode 100644 index 0000000..fb9f285 --- /dev/null +++ b/browser_extension/manifest.json @@ -0,0 +1,24 @@ +{ + "manifest_version": 3, + "name": "Scam Protector", + "version": "1.0", + "description": "Proactively protects you from scams.", + "permissions": [ + "activeTab", + "storage", + "http://127.0.0.1:8000/*" + ], + "action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } + }, + "icons": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } +} diff --git a/browser_extension/popup.html b/browser_extension/popup.html new file mode 100644 index 0000000..d859e10 --- /dev/null +++ b/browser_extension/popup.html @@ -0,0 +1,23 @@ + + + + Scam Protector + + + +

Scam Protector

+

Enter a URL to analyze:

+ + +
+ + + diff --git a/browser_extension/popup.js b/browser_extension/popup.js new file mode 100644 index 0000000..45c1787 --- /dev/null +++ b/browser_extension/popup.js @@ -0,0 +1,29 @@ +document.getElementById('analyzeBtn').addEventListener('click', () => { + const url = document.getElementById('urlInput').value; + const resultDiv = document.getElementById('result'); + + if (url) { + resultDiv.textContent = 'Analyzing...'; + fetch('http://127.0.0.1:8000/api/analyze/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ content: url }), + }) + .then(response => response.json()) + .then(data => { + if (data.status === 'ok') { + resultDiv.textContent = `Analysis: ${data.message}`; + } else { + resultDiv.textContent = `Error: ${data.message}`; + } + }) + .catch(error => { + console.error('Error:', error); + resultDiv.textContent = 'An error occurred during analysis.'; + }); + } else { + resultDiv.textContent = 'Please enter a URL.'; + } +}); diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index cd6f855..4cfc41f 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000..99bfab0 Binary files /dev/null and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 9aa598b..817be36 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 1f807fa..f867192 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 6867ddf..91bb7e5 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index 8c38f3f..34144bc 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,3 +1,8 @@ from django.contrib import admin +from .models import ScamReport -# Register your models here. +@admin.register(ScamReport) +class ScamReportAdmin(admin.ModelAdmin): + list_display = ('description', 'source', 'reported_at', 'status') + list_filter = ('status', 'reported_at') + search_fields = ('description', 'source') \ No newline at end of file diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..211ac4a --- /dev/null +++ b/core/forms.py @@ -0,0 +1,25 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.models import User +from .models import ScamReport + +class ScamReportForm(forms.ModelForm): + class Meta: + model = ScamReport + fields = ['description', 'source'] + widgets = { + 'description': forms.Textarea(attrs={ + 'class': 'form-control', + 'placeholder': 'Describe the scam in detail...', + 'rows': 4 + }), + 'source': forms.TextInput(attrs={ + 'class': 'form-control', + 'placeholder': 'e.g., suspicious.com or scammer@example.com' + }), + } + +class SignUpForm(UserCreationForm): + class Meta: + model = User + fields = ('username', 'email') diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..57cd77e --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2.7 on 2025-11-15 22:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='ScamReport', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('description', models.TextField(help_text='Describe the suspicious activity.')), + ('source', models.CharField(blank=True, help_text='The source (e.g., URL, email address).', max_length=255, null=True)), + ('reported_at', models.DateTimeField(auto_now_add=True)), + ('status', models.CharField(choices=[('PENDING', 'Pending'), ('VERIFIED', 'Verified'), ('DISMISSED', 'Dismissed')], default='PENDING', max_length=10)), + ], + options={ + 'ordering': ['-reported_at'], + }, + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..6252d13 Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..7d0678b 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,19 @@ from django.db import models -# Create your models here. +class ScamReport(models.Model): + description = models.TextField(help_text="Describe the suspicious activity.") + source = models.CharField(max_length=255, blank=True, null=True, help_text="The source (e.g., URL, email address).") + reported_at = models.DateTimeField(auto_now_add=True) + + STATUS_CHOICES = [ + ('PENDING', 'Pending'), + ('VERIFIED', 'Verified'), + ('DISMISSED', 'Dismissed'), + ] + status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='PENDING') + + class Meta: + ordering = ['-reported_at'] + + def __str__(self): + return f"{self.description[:50]}..." \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 788576e..89d77b1 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,11 +1,52 @@ - + - {% block title %}Knowledge Base{% endblock %} - {% block head %}{% endblock %} - - - {% block content %}{% endblock %} - + + ScamGuard - Community-Powered Scam Prevention + + + + + + + {% load static %} + + + + + +
+ {% block content %} + {% endblock %} +
+ + + diff --git a/core/templates/core/analysis_result.html b/core/templates/core/analysis_result.html new file mode 100644 index 0000000..8e1546e --- /dev/null +++ b/core/templates/core/analysis_result.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} +{% load static %} + +{% block content %} +
+
+
+
+

Analysis Result

+ +
+
+ Your Submission +
+
+

{{ report.description }}

+ {% if report.source %} +
Source: {{ report.source }}
+ {% endif %} +
+
+ +
+
+ AI Risk Assessment +
+
+

Analysis In Progress...

+

Our AI is currently analyzing your submission. This feature is under development and will be available soon.

+

For now, we have recorded this item for future analysis. Thank you for helping us build a safer digital environment.

+
+
+ + +
+
+
+
+{% endblock %} diff --git a/core/templates/core/index.html b/core/templates/core/index.html index 0a3f404..695005e 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,154 +1,36 @@ {% extends "base.html" %} - -{% block title %}{{ project_name }}{% endblock %} - -{% block head %} -{% if project_description %} - - - -{% endif %} -{% if project_image_url %} - - -{% endif %} - - - - -{% endblock %} +{% load static %} {% block content %} -
-
-

Analyzing your requirements and generating your app…

-
- Loading… +
+
+

Your Shield Against Digital Scams

+

Analyze suspicious messages, emails, and websites to protect yourself from digital threats.

+ Check for Scams
-

AppWizzy AI is collecting your requirements and applying the first changes.

-

This page will refresh automatically as the plan is implemented.

-

- Runtime: Django {{ django_version }} · Python {{ python_version }} - — UTC {{ current_time|date:"Y-m-d H:i:s" }} -

-
-
- -{% endblock %} \ No newline at end of file + + +
+
+ +
+
+

Analyze a Potential Scam

+

Enter any text, URL, or message below. Our AI will analyze it for signs of a scam and give you a risk assessment.

+
+ {% csrf_token %} +
+ {{ form.description.label_tag }} + {{ form.description }} +
+
+ {{ form.source.label_tag }} + {{ form.source }} +
+ +
+
+
+
+
+{% endblock %} diff --git a/core/templates/registration/login.html b/core/templates/registration/login.html new file mode 100644 index 0000000..3c201a0 --- /dev/null +++ b/core/templates/registration/login.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block title %}Login{% endblock title %} + +{% block content %} +
+
+
+

Login

+
+ {% csrf_token %} + {{ form.as_p }} + +
+
+
+
+{% endblock content %} diff --git a/core/templates/registration/signup.html b/core/templates/registration/signup.html new file mode 100644 index 0000000..e55db0c --- /dev/null +++ b/core/templates/registration/signup.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block title %}Sign Up{% endblock title %} + +{% block content %} +
+
+
+

Create an Account

+
+ {% csrf_token %} + {{ form.as_p }} + +
+
+
+
+{% endblock content %} diff --git a/core/urls.py b/core/urls.py index 6299e3d..bfc1a4d 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,11 @@ from django.urls import path - -from .views import home +from .views import index, analyze_report, SignupView, CustomLoginView, CustomLogoutView, api_analyze urlpatterns = [ - path("", home, name="home"), + path('', index, name='index'), + path('analyze/', analyze_report, name='analyze'), + path('api/analyze/', api_analyze, name='api_analyze'), + path('signup/', SignupView.as_view(), name='signup'), + path('login/', CustomLoginView.as_view(), name='login'), + path('logout/', CustomLogoutView.as_view(), name='logout'), ] diff --git a/core/views.py b/core/views.py index c9aed12..2148ef2 100644 --- a/core/views.py +++ b/core/views.py @@ -2,24 +2,70 @@ import os import platform from django import get_version as django_version -from django.shortcuts import render -from django.utils import timezone +from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.views import LoginView, LogoutView +from django.shortcuts import render, redirect +from django.urls import reverse_lazy +from django.views.generic import CreateView +from .forms import ScamReportForm, SignUpForm +from .models import ScamReport -def home(request): - """Render the landing screen with loader and environment details.""" - host_name = request.get_host().lower() - agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" - now = timezone.now() +def index(request): + """Render the homepage with a scam submission form.""" + form = ScamReportForm() + return render(request, 'core/index.html', {'form': form}) - context = { - "project_name": "New Style", - "agent_brand": agent_brand, - "django_version": django_version(), - "python_version": platform.python_version(), - "current_time": now, - "host_name": host_name, - "project_description": os.getenv("PROJECT_DESCRIPTION", ""), - "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), - } - return render(request, "core/index.html", context) + +def analyze_report(request): + """Process the scam report submission and display an analysis page.""" + if request.method == 'POST': + form = ScamReportForm(request.POST) + if form.is_valid(): + report = form.save() + return render(request, 'core/analysis_result.html', {'report': report}) + # Redirect to home if not a POST request or form is invalid + return redirect('index') + + + +class SignupView(CreateView): + form_class = SignUpForm + success_url = reverse_lazy('login') + template_name = 'registration/signup.html' + + +class CustomLoginView(LoginView): + template_name = 'registration/login.html' + redirect_authenticated_user = True + + def get_success_url(self): + return reverse_lazy('index') + + +class CustomLogoutView(LogoutView): + next_page = reverse_lazy('index') + + +from django.http import JsonResponse +from django.views.decorators.csrf import csrf_exempt +import json + +@csrf_exempt +def api_analyze(request): + """API endpoint to analyze content for scams.""" + if request.method == 'POST': + try: + data = json.loads(request.body) + content_to_analyze = data.get('content') + + if content_to_analyze: + # In the future, we will add real analysis logic here. + # For now, we'll return a placeholder response. + return JsonResponse({'status': 'ok', 'message': 'Analysis complete.'}) + else: + return JsonResponse({'status': 'error', 'message': 'No content provided.'}, status=400) + except json.JSONDecodeError: + return JsonResponse({'status': 'error', 'message': 'Invalid JSON.'}, status=400) + + return JsonResponse({'status': 'error', 'message': 'Invalid request method.'}, status=405) diff --git a/static/css/custom.css b/static/css/custom.css new file mode 100644 index 0000000..265ec02 --- /dev/null +++ b/static/css/custom.css @@ -0,0 +1,152 @@ +/* + ScamGuard Custom Stylesheet +*/ + +:root { + --primary-dark-blue: #0A192F; + --secondary-slate: #8892B0; + --accent-green: #64FFDA; + --background-light-navy: #0E1F3A; + --text-light-slate: #CCD6F6; + --text-dark-slate: #495670; + --card-background: #112240; + --font-family-headings: 'Poppins', sans-serif; + --font-family-body: 'Inter', sans-serif; +} + +body { + background-color: var(--primary-dark-blue); + color: var(--text-light-slate); + font-family: var(--font-family-body); +} + +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-family-headings); + color: var(--text-light-slate); + font-weight: 600; +} + +/* Hero Section */ +.hero-section { + display: flex; + align-items: center; + justify-content: center; + min-height: 60vh; + padding: 4rem 0; + background: linear-gradient(180deg, var(--background-light-navy) 0%, var(--primary-dark-blue) 100%); +} + +.hero-title { + font-size: 3.5rem; + font-weight: 700; + color: #fff; +} + +.hero-subtitle { + font-size: 1.25rem; + color: var(--secondary-slate); + max-width: 600px; + margin: 1rem auto 2rem; +} + +.btn-accent { + background-color: var(--accent-green); + color: var(--primary-dark-blue); + border: none; + padding: 12px 30px; + font-weight: 700; + font-family: var(--font-family-headings); + transition: all 0.3s ease; +} + +.btn-accent:hover { + background-color: #fff; + color: var(--primary-dark-blue); + transform: translateY(-3px); + box-shadow: 0 10px 20px rgba(0,0,0,0.1); +} + +/* Content Section */ +.content-section { + padding: 4rem 0; +} + +.form-container, .reports-container { + background-color: var(--card-background); + padding: 2.5rem; + border-radius: 8px; + height: 100%; +} + +.form-container h2, .reports-container h2 { + margin-bottom: 0.5rem; + color: #fff; +} + +.form-container p { + color: var(--secondary-slate); + margin-bottom: 1.5rem; +} + +.form-control { + background-color: var(--primary-dark-blue); + border: 1px solid var(--text-dark-slate); + color: var(--text-light-slate); + padding: 0.75rem 1rem; +} + +.form-control:focus { + background-color: var(--primary-dark-blue); + border-color: var(--accent-green); + color: #fff; + box-shadow: 0 0 0 0.25rem rgba(100, 255, 218, 0.25); +} + +.form-control::placeholder { + color: var(--secondary-slate); +} + +.btn-primary { + background-color: var(--accent-green); + border-color: var(--accent-green); + color: var(--primary-dark-blue); + padding: 10px 20px; + font-weight: 700; + transition: background-color 0.3s; +} + +.btn-primary:hover { + background-color: #52d9b8; + border-color: #52d9b8; +} + +/* Reports List */ +.reports-container .list-group { + max-height: 400px; + overflow-y: auto; +} +.report-item { + background-color: var(--primary-dark-blue); + border: 1px solid var(--text-dark-slate); + margin-bottom: 1rem; + border-radius: 5px; +} + +.report-description { + color: var(--text-light-slate); + margin-bottom: 0.5rem; +} + +.report-source { + color: var(--accent-green); + font-family: monospace; + font-size: 0.9rem; +} + +.report-meta { + display: block; + font-size: 0.8rem; + color: var(--secondary-slate); + margin-top: 0.5rem; + text-align: right; +}