Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
d8fe932
Made it workable again
notnotrachit Dec 26, 2024
c2ccf13
feat: initial navbar changes
syndrizzle Dec 27, 2024
352c8d9
feat: logo changes
syndrizzle Dec 27, 2024
717d580
feat: better mobile nav
syndrizzle Dec 27, 2024
0b17f19
feat: homepage overhaul, better nav
syndrizzle Dec 27, 2024
5bb8e1d
fix: better toast
syndrizzle Dec 27, 2024
df753e8
feat: update theme colors and improve UI consistency across templates
notnotrachit Dec 27, 2024
a190e22
refactor: remove animated background from templates for improved perf…
notnotrachit Dec 27, 2024
045e499
feat: redesign rules, guidelines and faq, redo code at a lot of places
syndrizzle Dec 27, 2024
ac43422
feat: animations, better error pages
syndrizzle Dec 28, 2024
eb25999
fix: overhaul 403 page
syndrizzle Dec 28, 2024
1116c92
fixing tags
notnotrachit Dec 28, 2024
e7dd6bf
feat: new login and signup pages(functionality implementation remains…
syndrizzle Dec 31, 2024
9ec3c73
chore: format pages
syndrizzle Dec 31, 2024
790bc86
fix: Remove extra blank line in accounts/views.py
notnotrachit Jan 1, 2025
f7fc594
feat: Add check for unique email and username on signup
notnotrachit Jan 1, 2025
0c45e1f
feat: Add check_unique view to validate email and username uniqueness
notnotrachit Jan 1, 2025
569ab31
Signup Fixed
notnotrachit Jan 1, 2025
7e1823c
fix: Refactor login form and enhance message display functionality
notnotrachit Jan 2, 2025
23392e9
fix: avatars, navbar, homepage
syndrizzle Jan 2, 2025
34d66a0
fix: email verification
syndrizzle Jan 2, 2025
b9bb0b9
chore: try implementing email cooldown
syndrizzle Jan 2, 2025
51c586a
chore: update dependencies
syndrizzle Jan 2, 2025
fd671ea
fix: update email pages
syndrizzle Jan 2, 2025
c5b0f5c
fix: profile page overhaul
syndrizzle Jan 2, 2025
e326508
chore: update dependencies and reset migrations
notnotrachit Jan 2, 2025
2c3868f
feat: Add hCaptcha verification to contact form submission
notnotrachit Jan 2, 2025
7ee1bc8
fix: Improve error handling and toast notifications in signup and log…
notnotrachit Jan 2, 2025
4436080
fix: accessing profile without login resulted in an error
syndrizzle Jan 3, 2025
430d212
feat: complete profile management overhaul
syndrizzle Jan 3, 2025
73c3a05
fix: enforce required fields in login and signup forms; improve toast…
notnotrachit Jan 3, 2025
1425aca
fix: enhance toast message handling in signup and login forms
notnotrachit Jan 3, 2025
68585e2
fix: improve login page, profile fixes
syndrizzle Jan 3, 2025
21a6de3
chore: better toasts
syndrizzle Jan 3, 2025
aaaa8a3
feat: implement Google social login integration and update dependencies
notnotrachit Jan 3, 2025
8b7fea1
feat: add email authentication for social accounts and create user pr…
notnotrachit Jan 5, 2025
9eec1a4
feat: update user profile handling and improve avatar assignment duri…
notnotrachit Jan 5, 2025
e644624
fixed profile error
notnotrachit Jan 6, 2025
014ef3c
chore: remove unused dependencies from requirements.txt
notnotrachit Jan 6, 2025
2f0f98b
chore: add jwt to requirements.txt
notnotrachit Jan 6, 2025
f146e8f
chore: add gunicorn to requirements.txt
notnotrachit Jan 6, 2025
5d0fd79
chore: replace jwt with PyJWT in requirements.txt
notnotrachit Jan 6, 2025
ad4b9f7
chore: update python-dotenv and sentry-sdk versions, add cryptography…
notnotrachit Jan 6, 2025
cd0e1a9
chore: update DATABASES configuration for different environments
notnotrachit Jan 6, 2025
934ed5f
chore: add psycopg2-binary to requirements.txt
notnotrachit Jan 6, 2025
8296b3d
feat: completely revamp the signup and login process
syndrizzle Jan 6, 2025
adcc31f
fix: google button and hcaptcha
notnotrachit Jan 6, 2025
2a1ffb8
feat: enhance email templates with improved styling and messaging
notnotrachit Jan 6, 2025
0bfe21b
fix: update logo URL in email template and remove sponsor section
notnotrachit Jan 6, 2025
d2bb41d
feat: initial revamps of about and leaderboard, and some fixes
syndrizzle Jan 6, 2025
c6dd6e1
feat: update signup process to require password confirmation and impr…
notnotrachit Jan 6, 2025
fd9c5f9
feat: configure static file storage and add logging settings for acco…
notnotrachit Jan 6, 2025
0654c21
google ubtton fix
notnotrachit Jan 6, 2025
ca360a6
fix: replace SVG logo with an image in email template
notnotrachit Jan 6, 2025
b24f4dd
fix: google buttons and animations
syndrizzle Jan 6, 2025
18bd1f0
fix: update meta title for Re-Dcrypt to version 3
notnotrachit Jan 6, 2025
81635d6
fix: update contact and social media links in about page
notnotrachit Jan 6, 2025
ca853ac
chore: update leaderboard design
syndrizzle Jan 6, 2025
8bce225
fix: update game logic for level completion and remove unused PWA files
notnotrachit Jan 7, 2025
2cc1386
fix: update label and placeholder text
notnotrachit Jan 7, 2025
7939373
fix: animations
syndrizzle Jan 7, 2025
49d0f6a
chore: nav overhaul
syndrizzle Jan 7, 2025
40f5745
fix: profile tags not loading on base for nav name visibility
syndrizzle Jan 7, 2025
79374c4
refix: profile tags implementation
syndrizzle Jan 7, 2025
307afd3
fix: misc changes
syndrizzle Jan 7, 2025
b09d84a
feat: not active page overhaul
syndrizzle Jan 7, 2025
e2d2e55
fix: update contact links to use email and remove support button from…
notnotrachit Jan 7, 2025
08fe609
feat: overhaul complete page and fix countdown clock
syndrizzle Jan 7, 2025
4b1ea8d
feat: add sponsorship modal to homepage
notnotrachit Jan 7, 2025
6b5c896
fix: update sponsorship modal to hide after submission
notnotrachit Jan 7, 2025
583a40d
public profile revamp
notnotrachit Jan 7, 2025
288d62d
Re-Dcrypt 2025
notnotrachit Jan 7, 2025
2ace976
fix: final touch all (except play and sample questions) the root temp…
syndrizzle Jan 7, 2025
9907a1d
Merge pull request #2 from FOSS-Club-BU/feat/design-overhaul
notnotrachit Jan 8, 2025
7e387a0
feat: add organization field to ProfileAdmin list display
notnotrachit Jan 8, 2025
6409e34
fix: password implementations part 1
syndrizzle Jan 8, 2025
7fef9fc
feat: complete changes
syndrizzle Jan 10, 2025
4c7c247
fix: leaderboard implementation
syndrizzle Jan 10, 2025
ffafc56
chore: remove any material icon references
syndrizzle Jan 10, 2025
a50ef78
chore: misc linting fixes
syndrizzle Jan 10, 2025
467f408
fix: replace the deprecated use of email rate limit
syndrizzle Jan 10, 2025
24de723
fix: add toast click dismissal and tip
syndrizzle Jan 10, 2025
e789f84
refactor: remove last_activity field and adjust profile saving logic;…
notnotrachit Jan 10, 2025
b4be0d4
Merge pull request #3 from FOSS-Club-BU/feat/design-overhaul
notnotrachit Jan 10, 2025
8ca66ab
refactor: streamline leaderboard view by removing unused hunt status …
notnotrachit Jan 10, 2025
6cbbbd4
Merge pull request #4 from FOSS-Club-BU/feat/design-overhaul
notnotrachit Jan 10, 2025
824acb6
fix: set default last_completed_time for new users in rank calculation
notnotrachit Jan 10, 2025
50637f6
Merge branch 'feat/design-overhaul'
notnotrachit Jan 10, 2025
303fb6b
fix: enhance answer matching by normalizing actual answer input
notnotrachit Jan 10, 2025
39ab910
refactor: remove default short name display for question level
notnotrachit Jan 10, 2025
e2e0f34
fix: verification email
notnotrachit Jan 10, 2025
dc82280
feat: add Umami analytics script to base template
notnotrachit Jan 10, 2025
4e2fe15
fix: prevent banned users from submitting answers
notnotrachit Jan 11, 2025
0ecdd39
fix: reload page for banned users on answer submission error
notnotrachit Jan 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .djlintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore": "H021,D018,H037"
}
156 changes: 147 additions & 9 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,147 @@
API_Authorization=<api_authorization_key>
SENTRY_DSN=<sentry_dsn_url>
EMAIL_HOST_USER=<email_host_user>
EMAIL_HOST_PASSWORD=<email_host_password>
DISCORD_LOGGING_WEBHOOK=<discord_logging_webhook_url>
HCAPTCHA_SITEKEY=<hcaptcha_sitekey>
HCAPTCHA_SECRET=<hcaptcha_secret>
MAINTENANCE_MODE=<true/false>
BOT_HOST=<bot_host url>
#==============================================================================
# Server Configuration
#==============================================================================

# Enable Django debug mode (True/False)
# Default: False
# WARNING: Never set to True in production
# DEBUG=False

# Django secret key for cryptographic signing
# REQUIRED: Generate a new one using `python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'`
# SECRET_KEY=your-secret-key-here

# Comma-separated list of allowed hosts
# Default: "localhost,127.0.0.1"
# Example: "example.com,subdomain.example.com,localhost"
# ALLOWED_HOSTS=localhost,127.0.0.1

# Comma-separated list of trusted origins for CSRF
# Default: "http://localhost:8000"
# Example: "https://example.com,https://subdomain.example.com"
# CSRF_TRUSTED_ORIGINS=http://localhost:8000

#==============================================================================
# Database Configuration (PostgreSQL)
#==============================================================================

# PostgreSQL database name
# REQUIRED: Name of your database
# DB_NAME=redcrypt

# PostgreSQL database user
# REQUIRED: Username with access to the database
# DB_USER=your_db_user

# PostgreSQL database password
# REQUIRED: Password for the database user
# DB_PASSWORD=your_db_password

# PostgreSQL host address
# Default: localhost
# Example: "db.example.com" or "postgresql.service"
# DB_HOST=localhost

# PostgreSQL port number
# Default: 5432
# DB_PORT=5432

#==============================================================================
# Email Configuration (SMTP)
#==============================================================================

# SMTP server hostname
# Example: "smtp.gmail.com" for Gmail
# EMAIL_HOST=smtp.gmail.com

# SMTP server port
# Common values: 587 (TLS) or 465 (SSL)
# EMAIL_PORT=587

# Enable TLS for SMTP
# Default: True
# EMAIL_USE_TLS=True

# SMTP authentication username
# Usually your email address
# [email protected]

# SMTP authentication password
# For Gmail: Use App Password, not account password
# EMAIL_HOST_PASSWORD=your-app-specific-password

# Email sender address
# Default: Same as EMAIL_HOST_USER
# Example: "Re-Dcrypt <[email protected]>"
# [email protected]

#==============================================================================
# Authentication & Security
#==============================================================================

# hCaptcha site key (public key)
# Get from: https://www.hcaptcha.com/
# HCAPTCHA_SITEKEY=your-hcaptcha-site-key

# hCaptcha secret key
# Get from: https://www.hcaptcha.com/
# HCAPTCHA_SECRET=your-hcaptcha-secret-key

# Google OAuth credentials
# Get from: https://console.cloud.google.com/
# GOOGLE_CLIENT_ID=your-google-client-id
# GOOGLE_CLIENT_SECRET=your-google-client-secret

#==============================================================================
# Discord Integration
#==============================================================================

# Discord bot host URL
# Example: "https://bot.example.com"
# BOT_HOST=https://your-discord-bot-host

# API authorization token for bot communication
# REQUIRED: Generate a secure random string
# API_Authorization=your-api-authorization-token

# Discord webhook URL for backups
# Get from Discord channel settings
# Discord_backup_webhook=your-discord-webhook-url

#==============================================================================
# Application Control
#==============================================================================

# Maintenance mode toggle (true/false)
# Default: false
# MAINTENANCE_MODE=false

# API authentication for cron jobs
# REQUIRED: Generate a secure random string
# API_CRON=your-cron-api-key

#==============================================================================
# Backup Configuration
#==============================================================================

# Password for encrypting backup ZIP files
# REQUIRED: Choose a strong password
# PWD_zip=your-backup-zip-password

#==============================================================================
# Monitoring (Optional)
#==============================================================================

# Sentry DSN for error tracking
# Get from: https://sentry.io/
# Optional: Leave empty to disable Sentry
# SENTRY_DSN=your-sentry-dsn

#==============================================================================
# Site Configuration
#==============================================================================

# Django site ID for social auth
# Default: 3
# WARNING: Change this if you have different site configurations
# SITE_ID=3
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,7 @@ replit.nix
poetry.lock
pyproject.toml
db.zip
.aider*

# Avatars file
media/avatars/*
71 changes: 71 additions & 0 deletions accounts/adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from allauth.account.adapter import DefaultAccountAdapter
from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
import logging

logger = logging.getLogger(__name__)

class CustomAccountAdapter(DefaultAccountAdapter):
def send_mail(self, template_prefix, email, context):
required_settings = [
'EMAIL_HOST',
'EMAIL_PORT',
'EMAIL_HOST_USER',
'EMAIL_HOST_PASSWORD',
'EMAIL_SENDER'
]

smtp_configured = all(hasattr(settings, setting) and getattr(settings, setting)
for setting in required_settings)

if not smtp_configured:
logger.warning(
"SMTP credentials not configured. Skipping email send. "
"Please configure EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, and EMAIL_SENDER"
)
return

try:
from_email = f"Re-Dcrypt <{settings.EMAIL_SENDER}>"

# Remove duplication prior to building final paths
if template_prefix.startswith('account/email/'):
template_prefix = template_prefix.replace('account/email/', '')

html_template = f"account/email/{template_prefix}_message.html"
text_template = f"account/email/{template_prefix}_message.txt"

try:
context['activate_url'] = context.get('activate_url', '')
context['current_site'] = context.get('current_site', '')
html_body = render_to_string(html_template, context)
text_body = render_to_string(text_template, context)
except Exception as e:
logger.warning(f"Template rendering failed: {str(e)}")
# Fallback to basic text email
text_body = (
f"Welcome to Re-Dcrypt!\n\n"
f"Please verify your email by clicking this link: {context.get('activate_url', '')}\n\n"
f"If you did not request this email, please ignore it."
)
html_body = text_body.replace('\n', '<br>')

# Create email message
msg = EmailMultiAlternatives(
subject=f"Re-Dcrypt - {context.get('subject', 'Verify your email')}",
body=text_body,
from_email=from_email,
to=[email],
headers={'From': from_email}
)

if html_body:
msg.attach_alternative(html_body, "text/html")

msg.send()
logger.info(f"Successfully sent verification email to {email}")

except Exception as e:
logger.error(f"Failed to send email: {str(e)}")
logger.exception(e)
7 changes: 4 additions & 3 deletions accounts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class ProfileAdmin(admin.ModelAdmin):
list_display = [
'user',
'score',
'organization',
'current_level',
'ip_address_count'
]
Expand All @@ -31,7 +32,7 @@ class ProfileAdmin(admin.ModelAdmin):
('name', 'is_public_name'),
('organization', 'is_public_organization'),
('discord_id'),
('avatar_url')
('avatar')
]}),
('Hunt',
{'fields': [
Expand All @@ -48,13 +49,13 @@ class ProfileAdmin(admin.ModelAdmin):

def reset_profile_pic(self, request, queryset):
for i in queryset:
i.avatar_url=f"https://source.boringavatars.com/beam/512/{i.user.username}?colors=00D2D2,006D6D,002A2A,055D5D,074848&square"
i.avatar_url=f"https://api.dicebear.com/9.x/fun-emoji/svg?seed={i.user.username}&backgroundColor=059ff2,71cf62,d84be5,d9915b,f6d594,fcbc34,b6e3f4,c0aede,d1d4f9,ffd5dc,ffdfbf&backgroundRotation[]"
i.save()
self.message_user(
request, "Updated URLs"
)

reset_profile_pic.short_description="Reset Avatar URL"
reset_profile_pic.short_description = "Reset Avatar"
actions=[reset_profile_pic]


Expand Down
65 changes: 53 additions & 12 deletions accounts/forms.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
from django import forms
from allauth.account.forms import SignupForm, ResetPasswordForm
from allauth.account.forms import SignupForm, ResetPasswordForm, LoginForm
from allauth.socialaccount.forms import SignupForm as SocialSignupForm
from accounts.models import Profile
from hcaptcha.fields import hCaptchaField
from datetime import datetime
from allauth.socialaccount.adapter import get_adapter

import pytz


class MyCustomSocialSignupForm(SocialSignupForm):
name = forms.CharField(required=False, label="Name [Optional]")
organization = forms.CharField(required=False, label='College/Organization [Optional]')
email = forms.EmailField(required=False)

def save(self, request):
adapter = get_adapter(request)
user = adapter.save_user(request, self.sociallogin, form=self)
self.custom_signup(request, user)
try:
avatar_url = self.sociallogin.account.get_avatar_url()
except:
avatar_url = f"https://api.dicebear.com/9.x/fun-emoji/svg?seed={user.username}&backgroundColor=059ff2,71cf62,d84be5,d9915b,f6d594,fcbc34,b6e3f4,c0aede,d1d4f9,ffd5dc,ffdfbf&backgroundRotation[]"

current_time = datetime.now(pytz.timezone('Asia/Kolkata'))
profile = Profile.objects.create(
user=user,
name=self.cleaned_data['name'],
organization=self.cleaned_data['organization'],
avatar=avatar_url,
last_completed_time=current_time)
profile.save()
return user

def validate_unique_email(self, value):
try:
return super(MyCustomSocialSignupForm, self).validate_unique_email(value)
except forms.ValidationError:
raise forms.ValidationError(
get_adapter().error_messages["email_taken"]
% self.sociallogin.account.get_provider().name
)

class MyCustomSignupForm(SignupForm):
name = forms.CharField(required=False, label="Name [Optional]")
organization = forms.CharField(required=False,
label='School/Organization [Optional]')
organization = forms.CharField(required=False, label='College/Organization [Optional]')
hcaptcha = hCaptchaField(theme='dark')

field_order = [
Expand All @@ -18,23 +53,18 @@ class MyCustomSignupForm(SignupForm):
]

def save(self, request):
# Ensure you call the parent class's save.
# .save() returns a User object.
user = super(MyCustomSignupForm, self).save(request)

profile = Profile.objects.create(
user=user,
name=self.cleaned_data['name'],
organization=self.cleaned_data['organization'],
avatar_url=
f"https://source.boringavatars.com/beam/512/{user.username}?colors=00D2D2,006D6D,002A2A,055D5D,074848&square",
avatar=f"https://api.dicebear.com/9.x/fun-emoji/svg?seed={user.username}&backgroundColor=059ff2,71cf62,d84be5,d9915b,f6d594,fcbc34,b6e3f4,c0aede,d1d4f9,ffd5dc,ffdfbf&backgroundRotation[]",
last_completed_time=datetime.now(pytz.timezone('Asia/Kolkata')))
profile.save()
return user

# Add your own processing here.

# You must return the original result.
return user


class CustomForgetPassword(ResetPasswordForm):
Expand All @@ -45,8 +75,19 @@ class ContactForm(forms.Form):
subject = forms.CharField(
required=True,
max_length=150,
widget=forms.TextInput(attrs={'class': 'text-nblue p-2'}))
label="Subject",
widget=forms.TextInput(attrs={
'class': 'form-input',
'placeholder': 'Enter subject',
})
)
body = forms.CharField(
required=True,
widget=forms.Textarea(attrs={'class': 'text-nblue p-2'}))
label="Message",
widget=forms.Textarea(attrs={
'class': 'form-input',
'placeholder': 'Type your message here...',
'rows': 4,
})
)
hCaptcha = hCaptchaField(theme='dark')
Loading