mirror of
https://github.com/ssep1ol/overleaf-registration-fe.git
synced 2026-07-21 12:30:20 +00:00
security: sanitize hardcoded values with placeholders for public repo
This commit is contained in:
3
Dockerfile
Normal file
3
Dockerfile
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM nginx:alpine
|
||||
COPY ./frontend /usr/share/nginx/html
|
||||
#COPY ./nginx.conf /etc/nginx/nginx.conf
|
||||
28
LICENSE
Normal file
28
LICENSE
Normal file
@@ -0,0 +1,28 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2026, overleaf-registration-fe contributors
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
153
README.md
Normal file
153
README.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# overleaf-registration-fe
|
||||
|
||||
Frontend signup interface for controlled Overleaf account registration.
|
||||
|
||||
Static HTML/JS/CSS site that presents a registration form with domain validation, Cloudflare Turnstile CAPTCHA, and Terms of Service acceptance. Served via nginx and designed to work with the [overleaf-registration-be](https://github.com/ssep1ol/overleaf-registration-be) backend API.
|
||||
|
||||
## Features
|
||||
|
||||
- Clean, responsive signup form
|
||||
- Client-side email domain validation
|
||||
- Cloudflare Turnstile CAPTCHA integration
|
||||
- Terms of Service modal with acceptance checkbox
|
||||
- Privacy policy page
|
||||
- Static site served via nginx
|
||||
- Docker container deployment
|
||||
|
||||
## How It Works
|
||||
|
||||
1. User visits signup page.
|
||||
2. User enters email address (validated client-side against hardcoded domain allowlist).
|
||||
3. User completes Cloudflare Turnstile CAPTCHA challenge.
|
||||
4. User accepts Terms of Service and Privacy Policy.
|
||||
5. Form submits JSON payload to backend API endpoint.
|
||||
6. User sees success/error message based on backend response.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- Vanilla JavaScript (no framework)
|
||||
- HTML5 with semantic markup
|
||||
- CSS (with Bootstrap-style classes from Overleaf theme)
|
||||
- Cloudflare Turnstile
|
||||
- nginx (Alpine-based container)
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
frontend/
|
||||
├── index.html # Main signup page
|
||||
├── script.js # Form validation and submission logic
|
||||
├── privacy.html # Privacy policy page
|
||||
├── main-style-*.css # Compiled CSS from Overleaf theme
|
||||
├── style.css # Additional custom styles
|
||||
├── styles.css # Additional custom styles
|
||||
├── scripts.js # Additional JS (if any)
|
||||
└── fonts/ # Web fonts (Lato, Merriweather, Font Awesome)
|
||||
nginx.conf # nginx server configuration
|
||||
Dockerfile # Container image build instructions
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
**REQUIRED:** Before deploying, you must configure the following hardcoded values in the source files.
|
||||
|
||||
### 1. Cloudflare Turnstile Site Key
|
||||
|
||||
In `frontend/index.html`, replace the placeholder:
|
||||
|
||||
```html
|
||||
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY_HERE"></div>
|
||||
```
|
||||
|
||||
Change `YOUR_TURNSTILE_SITE_KEY_HERE` to your actual Turnstile site key from the Cloudflare dashboard.
|
||||
|
||||
### 2. Allowed Email Domains
|
||||
|
||||
In `frontend/script.js`, update the `allowedDomains` array:
|
||||
|
||||
```javascript
|
||||
const allowedDomains = ['example.edu', 'university.edu']; // CONFIGURE: Replace with your allowed email domains
|
||||
```
|
||||
|
||||
Replace with your institution's email domains (e.g., `['studenti.polito.it', 'edu.unito.it']`).
|
||||
|
||||
### 3. Backend API Endpoint
|
||||
|
||||
In `frontend/script.js`, update the fetch URL:
|
||||
|
||||
```javascript
|
||||
const response = await fetch('https://YOUR_BACKEND_API_URL/signup', { // CONFIGURE: Replace with your backend API endpoint
|
||||
```
|
||||
|
||||
Replace `YOUR_BACKEND_API_URL` with your actual backend service URL.
|
||||
|
||||
### Summary of Required Changes
|
||||
|
||||
| File | Line/Element | What to Replace |
|
||||
|------|--------------|-----------------|
|
||||
| `frontend/index.html` | Turnstile div | `YOUR_TURNSTILE_SITE_KEY_HERE` → your site key |
|
||||
| `frontend/script.js` | `allowedDomains` array | `['example.edu', ...]` → your domains |
|
||||
| `frontend/script.js` | `fetch()` URL | `YOUR_BACKEND_API_URL` → your backend URL |
|
||||
|
||||
## Hardcoded Values in script.js
|
||||
|
||||
The following values are embedded in the client-side JavaScript and must be configured before deployment:
|
||||
|
||||
- **Allowed email domains:** Set in `allowedDomains` array
|
||||
- **Backend API endpoint:** Set in `fetch()` call
|
||||
- **Turnstile Site Key:** Set in `index.html` `data-sitekey` attribute
|
||||
|
||||
## Run Locally
|
||||
|
||||
Serve the `frontend/` directory with any web server.
|
||||
|
||||
Example with Python:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
python3 -m http.server 8080
|
||||
```
|
||||
|
||||
Then visit `http://localhost:8080`.
|
||||
|
||||
## Run With Docker
|
||||
|
||||
Build image:
|
||||
|
||||
```bash
|
||||
docker build -t overleaf-registration-fe .
|
||||
```
|
||||
|
||||
Run container:
|
||||
|
||||
```bash
|
||||
docker run --rm -p 8080:80 overleaf-registration-fe
|
||||
```
|
||||
|
||||
Then visit `http://localhost:8080`.
|
||||
|
||||
## Deployment Notes
|
||||
|
||||
- **Configuration Required:** You must update the placeholders in `frontend/index.html` and `frontend/script.js` before deploying (see Configuration section above).
|
||||
- nginx serves static files from `/usr/share/nginx/html`.
|
||||
- All routes fall back to `index.html` for single-page behavior.
|
||||
- No environment variables or build-time configuration needed - all config is hardcoded in client-side files.
|
||||
- After configuration, rebuild the Docker image to include your changes.
|
||||
|
||||
## Terms of Service
|
||||
|
||||
The embedded ToS modal enforces:
|
||||
- Non-commercial use only
|
||||
- No copyrighted material without authorization
|
||||
- No NSFW, gore, or illegal content
|
||||
- Users must backup their own work
|
||||
- No guarantees on service availability or data safety
|
||||
- Service maintained by volunteers on best-effort basis
|
||||
|
||||
## Privacy Policy
|
||||
|
||||
Located at `frontend/privacy.html` and accessible via link in signup form.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the BSD 3-Clause License - see the [LICENSE](LICENSE) file for details.
|
||||
BIN
frontend/.DS_Store
vendored
Normal file
BIN
frontend/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
frontend/fonts/font-awesome-v470-20fd1704ea223900efa9.woff2
Normal file
BIN
frontend/fonts/font-awesome-v470-20fd1704ea223900efa9.woff2
Normal file
Binary file not shown.
BIN
frontend/fonts/lato-v2-latin-ext-700-b4fe4204d19d86376b18.woff2
Normal file
BIN
frontend/fonts/lato-v2-latin-ext-700-b4fe4204d19d86376b18.woff2
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
125
frontend/index.html
Normal file
125
frontend/index.html
Normal file
@@ -0,0 +1,125 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>AppuntiPolito - Overleaf SignUp</title>
|
||||
|
||||
<!-- Include the provided CSS -->
|
||||
<link rel="stylesheet" href="register/main-style-f17f58e57337cfb154da.css">
|
||||
|
||||
<!-- Include Cloudflare Turnstile -->
|
||||
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
|
||||
<script src="register/script.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-default navbar-main">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button class="navbar-toggle">
|
||||
<i class="fa fa-bars" aria-hidden="true"></i>
|
||||
</button>
|
||||
<a class="navbar-title" href="/" aria-label="Overleaf AppuntiPolito">Overleaf AppuntiPolito</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/register">Sign Up</a></li>
|
||||
<li><a href="/login">Sign In</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Signup Form -->
|
||||
<main class="content content-alt">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
|
||||
<div class="card">
|
||||
<div class="page-header">
|
||||
<h1>AppuntiPolito Overleaf Sign Up</h1>
|
||||
<p>You must use your <b>@studenti.polito.it</b> or <b>@edu.unito.it</b> email.</p>
|
||||
</div>
|
||||
<form id="registration-form">
|
||||
<div class="form-group">
|
||||
<input
|
||||
class="form-control"
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="your.email@allowed-domain.it"
|
||||
required
|
||||
>
|
||||
</div>
|
||||
<!-- Add Turnstile widget -->
|
||||
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY_HERE"></div>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<input type="checkbox" id="agree-tos" name="agree-tos" required>
|
||||
<label for="agree-tos">
|
||||
I have read and agree to the
|
||||
<a href="#" id="open-tos-modal">Terms of Service</a> and the <a href="register/privacy.html" target="_blank">Privacy Policy</a>.
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="btn-primary btn" type="submit">
|
||||
Sign Up
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- ToS Modal -->
|
||||
<div id="tos-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span id="close-tos-modal" class="close">×</span>
|
||||
<h2>Terms of Service</h2>
|
||||
|
||||
<p>Welcome to the AppuntiPolito Overleaf platform, a service provided and maintained by volunteers on a best-effort basis. By using this service, you agree to the following terms:</p>
|
||||
|
||||
<h3>1. Permitted Use</h3>
|
||||
<ul>
|
||||
<li><strong>No Commercial Use:</strong> This service is strictly for personal and educational purposes. Commercial use is not permitted.</li>
|
||||
<li><strong>No Copyrighted Material:</strong> Uploading, sharing, or storing copyrighted materials without proper authorization is strictly prohibited.</li>
|
||||
<li><strong>No NSFW, Gore, or other Illegal Content:</strong> Any content that is obscene, offensive, related to drugs, promotes violence, or violates the law is strictly forbidden.</li>
|
||||
</ul>
|
||||
|
||||
<h3>2. User Responsibility</h3>
|
||||
<ul>
|
||||
<li><strong>Backup Your Work:</strong> Users are responsible for keeping backups of their work. This platform provides no guarantees for data safety or service availability.</li>
|
||||
<li><strong>Self-Reliance:</strong> The platform is provided as-is, without any guarantees. Users assume all responsibility for the consequences of using the service.</li>
|
||||
<li><strong>Academic Focus:</strong> This service is designed to overcome the limitations of the SaaS Overleaf offering (e.g., compile minutes) by hosting a community-driven Overleaf instance.</li>
|
||||
</ul>
|
||||
|
||||
<h3>3. Service Availability and Liability</h3>
|
||||
<p><strong>No Guarantees:</strong> The service is maintained by volunteers on a best-effort basis. We do not guarantee uptime, functionality, or data safety.</p>
|
||||
<p><strong>No Liability:</strong> The staff is not responsible for any loss of data, unavailability of the service, or other issues. Use this service at your own risk.</p>
|
||||
<p><strong>Volunteers Only:</strong> This is a free community service. As such, there is no formal support or warranty.</p>
|
||||
<p class="important">
|
||||
<strong>IMPORTANT:</strong> Keep a backup of your work on a personal storage device or cloud service. Do not rely on this platform as the sole location for your data.
|
||||
</p>
|
||||
|
||||
<h3>4. Abuse and Termination</h3>
|
||||
<ul>
|
||||
<li><strong>Abuse Policy:</strong> Any user found engaging in prohibited activities or violating the rules may have their access revoked without prior notice.</li>
|
||||
<li><strong>Service Shutdown:</strong> The staff reserves the right to discontinue the service at any time, especially in cases of repeated abuse by the user base.</li>
|
||||
<li><strong>Law Enforcement:</strong> In cases of illegal activity, the staff will cooperate with law enforcement authorities and provide any necessary information.</li>
|
||||
</ul>
|
||||
|
||||
<h3>5. Acceptance of Terms</h3>
|
||||
<p>By using this service, you acknowledge that you have read and understood these terms. Continued use of the platform constitutes your agreement to these terms.</p>
|
||||
|
||||
<p>If you have questions or concerns regarding these terms, please contact the staff. Thank you for respecting the community and helping us maintain a safe and productive environment for everyone.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<footer class="site-footer"><div class="site-footer-content hidden-print"><div class="row"><ul class="col-md-9"><li>© 2024
|
||||
<a href="https://www.overleaf.com/for/enterprises">Powered by Overleaf</a></li><li><strong class="text-muted">|</strong></li><li>Hosted and maintained by <a href="mailto:ito@lynxcloud.it">lynxcloud OdV - Turin</a> © 2024</li></ul><ul class="col-md-3 text-right"><li><a href="https://github.com/overleaf/overleaf"><i class="fa fa-github-square"></i> Fork on GitHub!</a></li></ul></div></div></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
71
frontend/main-style-f17f58e57337cfb154da.css
Normal file
71
frontend/main-style-f17f58e57337cfb154da.css
Normal file
File diff suppressed because one or more lines are too long
118
frontend/privacy.html
Normal file
118
frontend/privacy.html
Normal file
@@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Privacy Policy - AppuntiPolito Overleaf</title>
|
||||
<link rel="stylesheet" href="main-style-f17f58e57337cfb154da.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-default navbar-main">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button class="navbar-toggle">
|
||||
<i class="fa fa-bars" aria-hidden="true"></i>
|
||||
</button>
|
||||
<a class="navbar-title" href="/" aria-label="Overleaf AppuntiPolito">Overleaf AppuntiPolito</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="content">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="card">
|
||||
<div class="page-header">
|
||||
<h1>Privacy Policy / Politica sulla Privacy</h1>
|
||||
<p>Effective Date / Data di entrata in vigore: <strong>23/11/2024</strong></p>
|
||||
</div>
|
||||
|
||||
<!-- ENGLISH SECTION -->
|
||||
<div id="english-policy">
|
||||
<h2>Privacy Policy</h2>
|
||||
<h3>1. Data Controller</h3>
|
||||
<p><strong>Name:</strong> lynxcloud OdV</p>
|
||||
<p><strong>Address:</strong> Corso Racconigi 25/9 - 10139 Torino (TO) - Italy</p>
|
||||
<p><strong>Email:</strong> ito@lynxcloud.it</p>
|
||||
|
||||
<h3>2. Legal Basis for Processing</h3>
|
||||
<p>We process your data based on GDPR's legal bases, including performance of a contract, legal obligations, and legitimate interests.</p>
|
||||
|
||||
<h3>3. Data We Collect</h3>
|
||||
<ul>
|
||||
<li>Email address</li>
|
||||
<li>IP address</li>
|
||||
<li>Project data</li>
|
||||
</ul>
|
||||
|
||||
<h3>4. Data Storage and Retention</h3>
|
||||
<p>Your data is stored in compliance with GDPR and deleted when no longer required.</p>
|
||||
|
||||
<h3>5. Your Rights</h3>
|
||||
<ul>
|
||||
<li>Access your data</li>
|
||||
<li>Request data deletion</li>
|
||||
<li>Restrict data processing</li>
|
||||
</ul>
|
||||
|
||||
<h3>6. Cookies and Security</h3>
|
||||
<p>We use minimal cookies and follow strict security practices to safeguard your data.</p>
|
||||
|
||||
<h3>7. Service Availability and Liability</h3>
|
||||
<p>This service is offered on a best-effort basis with no guarantees of uptime or data recovery. You must maintain your own backups.</p>
|
||||
|
||||
<h3>8. Data Transfers Outside the EU</h3>
|
||||
<p>Any transfers outside the EU will comply with GDPR using appropriate safeguards.</p>
|
||||
|
||||
<h3>Contact</h3>
|
||||
<p>Email: ito@lynxcloud.it</p>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- ITALIAN SECTION -->
|
||||
<div id="italian-policy">
|
||||
<h2>Politica sulla Privacy</h2>
|
||||
<h3>1. Titolare del Trattamento</h3>
|
||||
<p><strong>Nome:</strong> lynxcloud OdV</p>
|
||||
<p><strong>Indirizzo:</strong> Corso Racconigi 25/9 - 10139 Torino (TO) - Italy</p>
|
||||
<p><strong>Email:</strong> ito@lynxcloud.it</p>
|
||||
|
||||
<h3>2. Base Giuridica per il Trattamento</h3>
|
||||
<p>Trattiamo i tuoi dati secondo le basi giuridiche del GDPR, inclusi l'esecuzione di un contratto, obblighi legali e interessi legittimi.</p>
|
||||
|
||||
<h3>3. Dati che Raccogliamo</h3>
|
||||
<ul>
|
||||
<li>Indirizzo email</li>
|
||||
<li>Indirizzo IP</li>
|
||||
<li>Dati dei progetti</li>
|
||||
</ul>
|
||||
|
||||
<h3>4. Conservazione e Durata dei Dati</h3>
|
||||
<p>I tuoi dati sono conservati in conformità con il GDPR e cancellati quando non più necessari.</p>
|
||||
|
||||
<h3>5. I tuoi Diritti</h3>
|
||||
<ul>
|
||||
<li>Accedere ai tuoi dati</li>
|
||||
<li>Richiedere la cancellazione dei dati</li>
|
||||
<li>Limitare il trattamento dei dati</li>
|
||||
</ul>
|
||||
|
||||
<h3>6. Cookie e Sicurezza</h3>
|
||||
<p>Utilizziamo cookie minimi e seguiamo pratiche di sicurezza rigorose per proteggere i tuoi dati.</p>
|
||||
|
||||
<h3>7. Disponibilità del Servizio e Responsabilità</h3>
|
||||
<p>Questo servizio è offerto su base "best-effort" senza garanzie di uptime o recupero dei dati. Devi mantenere copie di backup dei tuoi lavori.</p>
|
||||
|
||||
<h3>8. Trasferimenti di Dati al di Fuori dell'UE</h3>
|
||||
<p>Eventuali trasferimenti al di fuori dell'UE saranno conformi al GDPR utilizzando adeguate garanzie.</p>
|
||||
|
||||
<h3>Contatti</h3>
|
||||
<p>Email: ito@lynxcloud.it</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
100
frontend/script.js
Normal file
100
frontend/script.js
Normal file
@@ -0,0 +1,100 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log('Turnstile script loaded.');
|
||||
|
||||
const form = document.getElementById('registration-form');
|
||||
const tosModal = document.getElementById('tos-modal');
|
||||
const openTosModal = document.getElementById('open-tos-modal');
|
||||
const closeTosModal = document.getElementById('close-tos-modal');
|
||||
const tosCheckbox = document.querySelector('input[name="agree-tos"]');
|
||||
const allowedDomains = ['example.edu', 'university.edu']; // CONFIGURE: Replace with your allowed email domains
|
||||
|
||||
// Automatically show the Terms of Service modal on page load
|
||||
if (tosModal) {
|
||||
tosModal.style.display = 'block';
|
||||
}
|
||||
|
||||
// Handle Terms of Service modal
|
||||
if (openTosModal && tosModal) {
|
||||
openTosModal.addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
tosModal.style.display = 'block';
|
||||
});
|
||||
}
|
||||
|
||||
if (closeTosModal && tosModal) {
|
||||
closeTosModal.addEventListener('click', () => {
|
||||
tosModal.style.display = 'none';
|
||||
//if (tosCheckbox) tosCheckbox.checked = true; // Auto-check ToS checkbox
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('click', (event) => {
|
||||
if (event.target === tosModal) {
|
||||
tosModal.style.display = 'none';
|
||||
//if (tosCheckbox) tosCheckbox.checked = true; // Auto-check ToS checkbox
|
||||
}
|
||||
});
|
||||
|
||||
// Ensure the form exists
|
||||
if (!form) {
|
||||
console.error('Form not found!');
|
||||
return;
|
||||
}
|
||||
|
||||
form.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const emailInput = document.querySelector('input[name="email"]');
|
||||
const email = emailInput ? emailInput.value.trim() : '';
|
||||
|
||||
if (!email) {
|
||||
alert('Email is required.');
|
||||
return;
|
||||
}
|
||||
// Validate email
|
||||
const emailDomain = email.split('@')[1];
|
||||
if (!allowedDomains.includes(emailDomain)) {
|
||||
alert(`You must use a valid email from the following domains: ${allowedDomains.join(', ')}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the Terms of Service checkbox is checked
|
||||
if (!tosCheckbox || !tosCheckbox.checked) {
|
||||
alert('You must agree to the Terms of Service and the Privacy Policy to continue.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve Turnstile token
|
||||
const turnstileResponseElement = document.querySelector('input[name="cf-turnstile-response"]');
|
||||
const captchaToken = turnstileResponseElement ? turnstileResponseElement.value : '';
|
||||
|
||||
if (!captchaToken) {
|
||||
console.error('CAPTCHA token is missing.');
|
||||
alert('Please complete the CAPTCHA.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Submitting with Turnstile token:', captchaToken);
|
||||
|
||||
try {
|
||||
const response = await fetch('https://YOUR_BACKEND_API_URL/signup', { // CONFIGURE: Replace with your backend API endpoint
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, captcha: captchaToken }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
alert(result.message || 'Registration successful! Check your email to set your password.');
|
||||
emailInput.value = ''; // Clear the form
|
||||
} else {
|
||||
const error = await response.text();
|
||||
console.error('Backend error:', error);
|
||||
alert(`Registration failed: ${error}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during registration:', error);
|
||||
alert('An error occurred. Please try again.');
|
||||
}
|
||||
});
|
||||
});
|
||||
5
frontend/scripts.js
Normal file
5
frontend/scripts.js
Normal file
File diff suppressed because one or more lines are too long
31
frontend/style.css
Normal file
31
frontend/style.css
Normal file
@@ -0,0 +1,31 @@
|
||||
body {
|
||||
font-family: "Roboto", sans-serif;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
}
|
||||
|
||||
.btn-success:hover {
|
||||
background-color: #218838;
|
||||
border-color: #1e7e34;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
5
frontend/styles.css
Normal file
5
frontend/styles.css
Normal file
File diff suppressed because one or more lines are too long
17
nginx.conf
Normal file
17
nginx.conf
Normal file
@@ -0,0 +1,17 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
# Serve the frontend static files
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Serve all requests as static files
|
||||
location / {
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
|
||||
# Logs for debugging (optional)
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
}
|
||||
Reference in New Issue
Block a user