first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 22:27:56 +03:00
commit d9f1ea341e
1021 changed files with 70645 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
{% load i18n %}
{% block subject %}
Activate Your Account - {{ site_name }}
{% endblock subject %}
{% block text_body %}
Hi{% if user.first_name %} {{ user.first_name }}{% endif %},
Thank you for registering with {{ site_name }}!
To activate your account, please visit the following link:
http://{{ domain }}/{{ url }}
This activation link will expire in 24 hours for security reasons.
If you didn't create an account with us, you can safely ignore this email.
---
This is an automated message, please do not reply to this email.
© {{ site_name }} - All rights reserved
{% endblock text_body %}
{% block html_body %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f4f4f4;
}
.container {
background-color: #ffffff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.header {
text-align: center;
padding-bottom: 20px;
border-bottom: 2px solid #4CAF50;
}
h1 {
color: #4CAF50;
margin: 0;
}
.content {
margin: 30px 0;
}
.button {
display: inline-block;
padding: 12px 30px;
background-color: #4CAF50;
color: #ffffff !important;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
text-align: center;
}
.button:hover {
background-color: #45a049;
}
.link-container {
text-align: center;
margin: 20px 0;
}
.footer {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #ddd;
font-size: 12px;
color: #666;
text-align: center;
}
.code {
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
word-break: break-all;
font-family: monospace;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Welcome! 🎉</h1>
</div>
<div class="content">
<p>Hi{% if user.first_name %} {{ user.first_name }}{% endif %},</p>
<p>Thank you for registering with {{ site_name }}! To complete your registration and activate your account, please click the button below:</p>
<div class="link-container">
<a href="http://{{ domain }}/{{ url }}" class="button">Activate Your Account</a>
</div>
<p>Or copy and paste this link into your browser:</p>
<div class="code">
http://{{ domain }}/{{ url }}
</div>
<p><strong>Note:</strong> This activation link will expire in 24 hours for security reasons.</p>
<p>If you didn't create an account with us, you can safely ignore this email.</p>
</div>
<div class="footer">
<p>This is an automated message, please do not reply to this email.</p>
<p>&copy; {{ site_name }} - All rights reserved</p>
</div>
</div>
</body>
</html>
{% endblock html_body %}

View File

@@ -0,0 +1,23 @@
{% load i18n %}
{% block subject %}
Activate Your Account - {{ site_name }}
{% endblock subject %}
{% block text_body %}
Hi{% if user.first_name %} {{ user.first_name }}{% endif %},
Thank you for registering with {{ site_name }}!
To activate your account, please visit the following link:
http://{{ domain }}/{{ url }}
This activation link will expire in 24 hours for security reasons.
If you didn't create an account with us, you can safely ignore this email.
---
This is an automated message, please do not reply to this email.
© {{ site_name }} - All rights reserved
{% endblock text_body %}

View File

@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Account Activated</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f4f4f4;
}
.container {
background-color: #ffffff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.header {
text-align: center;
padding-bottom: 20px;
border-bottom: 2px solid #4CAF50;
}
h1 {
color: #4CAF50;
margin: 0;
}
.content {
margin: 30px 0;
}
.footer {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #ddd;
font-size: 12px;
color: #666;
text-align: center;
}
.success-icon {
text-align: center;
font-size: 48px;
margin: 20px 0;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Account Activated! ✅</h1>
</div>
<div class="success-icon">
🎉
</div>
<div class="content">
<p>Hi{% if user.first_name %} {{ user.first_name }}{% endif %},</p>
<p>Great news! Your account has been successfully activated.</p>
<p>You can now log in and start using all features of {{ site_name }}.</p>
<p>If you have any questions or need assistance, please don't hesitate to contact our support team.</p>
<p>Welcome aboard!</p>
</div>
<div class="footer">
<p>This is an automated message, please do not reply to this email.</p>
<p>&copy; {{ site_name }} - All rights reserved</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,16 @@
Account Activated!
Hi{% if user.first_name %} {{ user.first_name }}{% endif %},
Great news! Your account has been successfully activated.
You can now log in and start using all features of {{ site_name }}.
If you have any questions or need assistance, please don't hesitate to contact our support team.
Welcome aboard!
---
This is an automated message, please do not reply to this email.
© {{ site_name }} - All rights reserved

View File

@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Reset</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f4f4f4;
}
.container {
background-color: #ffffff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.header {
text-align: center;
padding-bottom: 20px;
border-bottom: 2px solid #FF9800;
}
h1 {
color: #FF9800;
margin: 0;
}
.content {
margin: 30px 0;
}
.button {
display: inline-block;
padding: 12px 30px;
background-color: #FF9800;
color: #ffffff;
text-decoration: none;
border-radius: 5px;
margin: 20px 0;
text-align: center;
}
.button:hover {
background-color: #F57C00;
}
.link-container {
text-align: center;
margin: 20px 0;
}
.footer {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #ddd;
font-size: 12px;
color: #666;
text-align: center;
}
.code {
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
word-break: break-all;
font-family: monospace;
}
.warning {
background-color: #fff3cd;
border-left: 4px solid #FF9800;
padding: 12px;
margin: 20px 0;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Password Reset 🔐</h1>
</div>
<div class="content">
<p>Hi{% if user.first_name %} {{ user.first_name }}{% endif %},</p>
<p>We received a request to reset your password. Click the button below to choose a new password:</p>
<div class="link-container">
<a href="{{ protocol }}://{{ domain }}/{{ url }}" class="button">Reset Password</a>
</div>
<p>Or copy and paste this link into your browser:</p>
<div class="code">
{{ protocol }}://{{ domain }}/{{ url }}
</div>
<div class="warning">
<strong>⚠️ Security Note:</strong> This password reset link will expire in 1 hour. If you didn't request a password reset, please ignore this email and your password will remain unchanged.
</div>
<p>For security reasons, we recommend that you:</p>
<ul>
<li>Choose a strong, unique password</li>
<li>Don't reuse passwords from other sites</li>
<li>Enable two-factor authentication if available</li>
</ul>
</div>
<div class="footer">
<p>This is an automated message, please do not reply to this email.</p>
<p>&copy; {{ site_name }} - All rights reserved</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,21 @@
Password Reset Request
Hi{% if user.first_name %} {{ user.first_name }}{% endif %},
We received a request to reset your password. To choose a new password, please visit the following link:
{{ protocol }}://{{ domain }}/{{ url }}
This password reset link will expire in 1 hour for security reasons.
If you didn't request a password reset, please ignore this email and your password will remain unchanged.
For security reasons, we recommend that you:
- Choose a strong, unique password
- Don't reuse passwords from other sites
- Enable two-factor authentication if available
---
This is an automated message, please do not reply to this email.
© {{ site_name }} - All rights reserved

View File

@@ -0,0 +1,168 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Activating Account...</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 3rem;
max-width: 500px;
width: 100%;
text-align: center;
}
.spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #667eea;
border-radius: 50%;
width: 60px;
height: 60px;
animation: spin 1s linear infinite;
margin: 0 auto 2rem;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.success {
display: none;
}
.success-icon {
font-size: 64px;
margin-bottom: 1rem;
}
.error {
display: none;
}
.error-icon {
font-size: 64px;
margin-bottom: 1rem;
}
h1 {
color: #333;
margin-bottom: 1rem;
}
p {
color: #666;
margin-bottom: 2rem;
}
.btn {
display: inline-block;
padding: 1rem 2rem;
background: #667eea;
color: white;
text-decoration: none;
border-radius: 8px;
font-weight: 600;
transition: background 0.3s;
}
.btn:hover {
background: #5568d3;
}
</style>
</head>
<body>
<div class="container">
<div id="loading">
<div class="spinner"></div>
<h1>Activating Your Account...</h1>
<p>Please wait while we activate your account.</p>
</div>
<div id="success" class="success">
<div class="success-icon"></div>
<h1>Account Activated!</h1>
<p>Your account has been successfully activated. You can now log in.</p>
<a href="/api/v1/spa/" class="btn">Go to Login</a>
</div>
<div id="error" class="error">
<div class="error-icon"></div>
<h1>Activation Failed</h1>
<p id="errorMessage">The activation link is invalid or has expired.</p>
<a href="/api/v1/spa/" class="btn">Back to Login</a>
</div>
</div>
<script>
// Get uid and token from Django template context
const finalUid = '{{ uid }}';
const finalToken = '{{ token }}';
console.log('Activating with:', { uid: finalUid, token: finalToken });
// Activate account
async function activateAccount() {
try {
const response = await fetch('http://localhost:8000/api/v1/auth/users/activation/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
uid: finalUid,
token: finalToken
})
});
document.getElementById('loading').style.display = 'none';
if (response.ok || response.status === 204) {
document.getElementById('success').style.display = 'block';
} else {
const data = await response.json().catch(() => ({}));
document.getElementById('error').style.display = 'block';
if (data.detail || data.token || data.uid) {
document.getElementById('errorMessage').textContent =
data.detail || data.token?.[0] || data.uid?.[0] || 'Activation failed.';
}
}
} catch (error) {
console.error('Activation error:', error);
document.getElementById('loading').style.display = 'none';
document.getElementById('error').style.display = 'block';
document.getElementById('errorMessage').textContent = 'Network error. Please try again.';
}
}
// Start activation
if (finalUid && finalToken) {
activateAccount();
} else {
document.getElementById('loading').style.display = 'none';
document.getElementById('error').style.display = 'block';
document.getElementById('errorMessage').textContent = 'Missing activation parameters.';
}
</script>
</body>
</html>

View File

@@ -0,0 +1,205 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Django Auth - SPA Test (Token-Based)</title>
<link rel="stylesheet" href="/static/spa-test.css">
<!-- Google OAuth2 -->
<script src="https://accounts.google.com/gsi/client" async defer></script>
</head>
<body>
<div id="app">
<!-- Navigation -->
<nav class="navbar" id="navbar" style="display: none;">
<div class="nav-container">
<div class="nav-brand">🔐 Django Auth</div>
<div class="nav-menu">
<span id="userEmail" class="user-email"></span>
<button onclick="logout()" class="btn-logout">Logout</button>
</div>
</div>
</nav>
<!-- Login Page -->
<div id="loginPage" class="page">
<div class="container">
<div class="card">
<h1>Welcome Back! 👋</h1>
<p class="subtitle">Sign in to continue</p>
<!-- Email/Password Login -->
<form id="loginForm" onsubmit="handleLogin(event)">
<div class="form-group">
<label>Email</label>
<input type="email" id="email" placeholder="your@email.com" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" id="password" placeholder="••••••••" required>
</div>
<button type="submit" class="btn btn-primary">
Sign In
</button>
</form>
<div class="divider">OR</div>
<!-- Social Login (Token-Based) -->
<div class="social-buttons">
<button onclick="loginWithGoogle()" class="btn btn-google">
🔵 Continue with Google
</button>
<button onclick="loginWithGitHub()" class="btn btn-github">
⚫ Continue with GitHub
</button>
</div>
<p class="footer-text">
Don't have an account? <a href="#" onclick="showRegister()">Sign up</a>
</p>
</div>
<div id="errorAlert" class="alert alert-error" style="display: none;"></div>
<div class="info-box">
<strong> Token-Based Flow:</strong>
<p>Bu sayfa Nuxt/Next.js gibi çalışır:</p>
<ol>
<li>Frontend'de Google/GitHub OAuth</li>
<li>Access token alınır</li>
<li>Token Django'ya POST edilir</li>
<li>Django JWT token döner</li>
<li>JWT localStorage'a kaydedilir</li>
</ol>
</div>
</div>
</div>
<!-- Register Page -->
<div id="registerPage" class="page" style="display: none;">
<div class="container">
<div class="card">
<h1>Create Account 🎉</h1>
<p class="subtitle">Join us today</p>
<form id="registerForm" onsubmit="handleRegister(event)">
<div class="form-group">
<label>Email</label>
<input type="email" id="regEmail" placeholder="your@email.com" required>
</div>
<div class="form-group">
<label>First Name</label>
<input type="text" id="firstName" placeholder="John" required>
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" id="lastName" placeholder="Doe" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" id="regPassword" placeholder="••••••••" required>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" id="regPasswordConfirm" placeholder="••••••••" required>
</div>
<button type="submit" class="btn btn-primary">
Create Account
</button>
</form>
<p class="footer-text">
Already have an account? <a href="#" onclick="showLogin()">Sign in</a>
</p>
</div>
<div id="registerSuccess" class="alert alert-success" style="display: none;">
✅ Account created! Please check your email to activate your account.
</div>
</div>
</div>
<!-- Dashboard Page -->
<div id="dashboardPage" class="page" style="display: none;">
<div class="container">
<div class="card">
<h1>Dashboard 🎯</h1>
<p class="subtitle">Welcome to your account</p>
<div class="profile-section">
<div class="profile-avatar">👤</div>
<div class="profile-info">
<h2 id="profileName">Loading...</h2>
<p id="profileEmail" class="text-muted">Loading...</p>
<span id="profileStatus" class="badge"></span>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon">📧</div>
<div class="stat-info">
<h3 id="userEmailStat">-</h3>
<p>Email Address</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">🔑</div>
<div class="stat-info">
<h3>JWT</h3>
<p>Authentication</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">📅</div>
<div class="stat-info">
<h3 id="joinedDate">-</h3>
<p>Member Since</p>
</div>
</div>
</div>
<div class="token-section">
<h3>Your JWT Tokens 🔐</h3>
<div class="token-box">
<label>Access Token (from Django)</label>
<textarea id="accessToken" readonly></textarea>
<button onclick="copyToken('access')" class="btn btn-small">Copy</button>
</div>
<div class="token-box">
<label>Refresh Token (from Django)</label>
<textarea id="refreshToken" readonly></textarea>
<button onclick="copyToken('refresh')" class="btn btn-small">Copy</button>
</div>
</div>
<button onclick="testProtectedEndpoint()" class="btn btn-primary">
🧪 Test Protected Endpoint
</button>
</div>
</div>
</div>
<!-- Loading Overlay -->
<div id="loadingOverlay" class="loading-overlay" style="display: none;">
<div class="spinner"></div>
<p>Loading...</p>
</div>
</div>
<script src="/static/spa-test.js"></script>
<!-- Google OAuth Initialization -->
<script>
window.onload = function() {
// Initialize Google OAuth
if (typeof google !== 'undefined') {
google.accounts.id.initialize({
client_id: '915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com',
callback: handleGoogleCallback
});
}
};
</script>
</body>
</html>

View File

@@ -0,0 +1,353 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub OAuth Test</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #24292e 0%, #1a1e22 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
padding: 40px;
max-width: 600px;
width: 100%;
}
h1 {
color: #24292e;
margin-bottom: 10px;
text-align: center;
}
.subtitle {
color: #666;
text-align: center;
margin-bottom: 30px;
font-size: 14px;
}
.info-box {
background: #f6f8fa;
border: 2px solid #e1e4e8;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.info-box h3 {
color: #24292e;
margin-bottom: 10px;
font-size: 16px;
}
.info-box ol {
margin-left: 20px;
color: #586069;
font-size: 14px;
line-height: 1.8;
}
.info-box code {
background: #fff;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-size: 12px;
border: 1px solid #e1e4e8;
}
.input-group {
margin-bottom: 20px;
}
.input-group label {
display: block;
color: #24292e;
font-weight: 600;
margin-bottom: 8px;
font-size: 14px;
}
.input-group input {
width: 100%;
padding: 12px 15px;
border: 2px solid #e1e4e8;
border-radius: 6px;
font-size: 14px;
font-family: 'Courier New', monospace;
transition: border-color 0.3s;
}
.input-group input:focus {
outline: none;
border-color: #0366d6;
}
.btn {
width: 100%;
padding: 15px 20px;
margin: 10px 0;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn-github {
background: #24292e;
color: white;
}
.btn-github:hover {
background: #1a1e22;
}
.btn-github:disabled {
background: #6a737d;
cursor: not-allowed;
transform: none;
}
.result {
margin-top: 30px;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
display: none;
}
.result.show {
display: block;
}
.result h3 {
color: #333;
margin-bottom: 10px;
}
.result.success {
background: #d4edda;
border: 2px solid #c3e6cb;
color: #155724;
}
.result.error {
background: #f8d7da;
border: 2px solid #f5c6cb;
color: #721c24;
}
.json-output {
background: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 12px;
white-space: pre-wrap;
word-wrap: break-word;
margin-top: 10px;
}
.loading {
text-align: center;
padding: 20px;
display: none;
}
.loading.show {
display: block;
}
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #24292e;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.link {
color: #0366d6;
text-decoration: none;
font-weight: 600;
}
.link:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>🐙 GitHub OAuth Test</h1>
<p class="subtitle">Django REST API - GitHub Authentication</p>
<div class="info-box">
<h3>📝 GitHub Personal Access Token Nasıl Alınır?</h3>
<ol>
<li><a href="https://github.com/settings/tokens" target="_blank" class="link">GitHub Settings → Tokens</a> sayfasına git</li>
<li><strong>Generate new token (classic)</strong> butonuna tıkla</li>
<li>Scopes seç:
<ul>
<li><code>user</code></li>
<li><code>user:email</code></li>
</ul>
</li>
<li>Token'ı oluştur ve kopyala</li>
<li>Aşağıdaki alana yapıştır</li>
</ol>
</div>
<div class="input-group">
<label for="githubToken">GitHub Personal Access Token:</label>
<input
type="text"
id="githubToken"
placeholder="ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
autocomplete="off"
/>
</div>
<button class="btn btn-github" onclick="testGitHubAuth()" id="testBtn">
<span></span>
Test GitHub Authentication
</button>
<div class="loading" id="loading">
<div class="spinner"></div>
<p style="margin-top: 10px; color: #24292e;">Testing authentication...</p>
</div>
<div class="result" id="result">
<h3 id="resultTitle">Result</h3>
<div id="resultContent"></div>
</div>
</div>
<script>
const API_BASE = 'http://localhost:8000/api/v1';
async function testGitHubAuth() {
const token = document.getElementById('githubToken').value.trim();
if (!token) {
showResult('error', 'Error ❌', {
error: 'Please enter a GitHub Personal Access Token'
});
return;
}
showLoading();
try {
const response = await fetch(`${API_BASE}/auth/social/github/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
access_token: token
})
});
const data = await response.json();
hideLoading();
if (response.ok) {
showResult('success', 'GitHub Authentication Successful! ✅', data);
} else {
showResult('error', 'Authentication Failed ❌', data);
}
} catch (error) {
hideLoading();
showResult('error', 'Error ❌', {
error: error.message,
details: 'Make sure Django server is running on localhost:8000'
});
}
}
function showLoading() {
document.getElementById('loading').classList.add('show');
document.getElementById('result').classList.remove('show');
document.getElementById('testBtn').disabled = true;
}
function hideLoading() {
document.getElementById('loading').classList.remove('show');
document.getElementById('testBtn').disabled = false;
}
function showResult(type, title, data) {
const resultDiv = document.getElementById('result');
const resultTitle = document.getElementById('resultTitle');
const resultContent = document.getElementById('resultContent');
resultDiv.className = `result show ${type}`;
resultTitle.textContent = title;
if (type === 'success' && data.user) {
resultContent.innerHTML = `
<p><strong>🎉 Başarılı! Kullanıcı bilgileri:</strong></p>
<p><strong>Email:</strong> ${data.user.email}</p>
<p><strong>Name:</strong> ${data.user.first_name} ${data.user.last_name}</p>
<p><strong>ID:</strong> ${data.user.id}</p>
<p><strong>Active:</strong> ${data.user.is_active}</p>
<br>
<p><strong>JWT Tokens:</strong></p>
<div class="json-output">${JSON.stringify(data, null, 2)}</div>
`;
} else {
resultContent.innerHTML = `
<div class="json-output">${JSON.stringify(data, null, 2)}</div>
`;
}
}
// Enter key to submit
document.getElementById('githubToken').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
testGitHubAuth();
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<title>Authentication Error</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 40px;
max-width: 600px;
width: 100%;
}
h1 {
color: #e74c3c;
text-align: center;
margin-bottom: 20px;
}
.error-icon {
text-align: center;
font-size: 64px;
margin-bottom: 20px;
}
.error-message {
background: #f8d7da;
border: 2px solid #f5c6cb;
color: #721c24;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
}
.btn {
display: block;
width: 100%;
padding: 12px;
margin-top: 20px;
background: #667eea;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
text-align: center;
text-decoration: none;
}
.btn:hover {
background: #5568d3;
}
</style>
</head>
<body>
<div class="container">
<div class="error-icon"></div>
<h1>Authentication Failed</h1>
<div class="error-message" id="errorMessage">
Something went wrong during authentication.
</div>
<a href="/api/v1/auth/social/test/" class="btn">Try Again</a>
</div>
<script>
const urlParams = new URLSearchParams(window.location.search);
const error = urlParams.get('error');
if (error) {
document.getElementById('errorMessage').textContent = error;
}
</script>
</body>
</html>

View File

@@ -0,0 +1,208 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OAuth Flow Test - Real Authentication</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 40px;
max-width: 600px;
width: 100%;
}
h1 {
color: #333;
margin-bottom: 10px;
text-align: center;
}
.subtitle {
color: #666;
text-align: center;
margin-bottom: 30px;
font-size: 14px;
}
.info {
background: #e7f3ff;
border: 2px solid #b3d9ff;
color: #004085;
padding: 20px;
border-radius: 8px;
margin-bottom: 30px;
font-size: 14px;
line-height: 1.6;
}
.info strong {
display: block;
margin-bottom: 10px;
font-size: 16px;
}
.btn {
width: 100%;
padding: 18px 20px;
margin: 10px 0;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
text-decoration: none;
color: white;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
.btn-google {
background: #4285f4;
}
.btn-google:hover {
background: #357ae8;
}
.btn-github {
background: #24292e;
}
.btn-github:hover {
background: #1a1e22;
}
.icon {
font-size: 24px;
}
.setup-section {
background: #fff3cd;
border: 2px solid #ffc107;
color: #856404;
padding: 20px;
border-radius: 8px;
margin-top: 30px;
font-size: 13px;
}
.setup-section h3 {
margin-bottom: 10px;
color: #856404;
}
.setup-section ol {
margin-left: 20px;
line-height: 1.8;
}
.setup-section code {
background: white;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
border: 1px solid #e0e0e0;
}
.divider {
text-align: center;
margin: 30px 0;
color: #999;
position: relative;
}
.divider::before,
.divider::after {
content: "";
position: absolute;
top: 50%;
width: 45%;
height: 1px;
background: #ddd;
}
.divider::before {
left: 0;
}
.divider::after {
right: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>🔐 OAuth Flow Test</h1>
<p class="subtitle">Gerçek OAuth Authentication - Django REST API</p>
<div class="info">
<strong>✨ Nasıl Çalışır?</strong>
<p>
Butona tıkladığınızda GitHub veya Google'ın kendi sayfasına yönlendirileceksiniz.
Orada giriş yapıp izin verdikten sonra, otomatik olarak geri dönecek ve
JWT token'larınız gösterilecek!
</p>
</div>
<a href="http://localhost:8000/api/v1/social/login/google-oauth2/" class="btn btn-google">
<span class="icon">🔵</span>
Login with Google
</a>
<div class="divider">VEYA</div>
<a href="http://localhost:8000/api/v1/social/login/github/" class="btn btn-github">
<span class="icon"></span>
Login with GitHub
</a>
<div class="setup-section">
<h3>⚠️ GitHub OAuth App Ayarları</h3>
<p>GitHub OAuth çalışması için callback URL'ini ayarlamalısınız:</p>
<ol>
<li><strong>Git:</strong> <a href="https://github.com/settings/developers" target="_blank">GitHub Settings → OAuth Apps</a></li>
<li>OAuth App'inizi bulun veya yeni oluşturun</li>
<li><strong>Authorization callback URL:</strong> <code>http://localhost:8000/api/v1/social/complete/github/</code></li>
<li>Kaydet</li>
</ol>
<h3 style="margin-top: 15px;">⚠️ Google OAuth App Ayarları</h3>
<ol>
<li><strong>Git:</strong> <a href="https://console.cloud.google.com/apis/credentials" target="_blank">Google Cloud Console</a></li>
<li>OAuth 2.0 Client ID'nizi düzenleyin</li>
<li><strong>Authorized redirect URIs:</strong> <code>http://localhost:8000/api/v1/social/complete/google-oauth2/</code></li>
<li><strong>Authorized JavaScript origins:</strong> <code>http://localhost:8000</code></li>
<li>Kaydet</li>
</ol>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,307 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Social Auth Test</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 40px;
max-width: 500px;
width: 100%;
}
h1 {
color: #333;
margin-bottom: 10px;
text-align: center;
}
.subtitle {
color: #666;
text-align: center;
margin-bottom: 30px;
font-size: 14px;
}
.btn {
width: 100%;
padding: 15px 20px;
margin: 10px 0;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn-google {
background: #4285f4;
color: white;
}
.btn-google:hover {
background: #357ae8;
}
.btn-github {
background: #24292e;
color: white;
}
.btn-github:hover {
background: #1a1e22;
}
.result {
margin-top: 30px;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
display: none;
}
.result.show {
display: block;
}
.result h3 {
color: #333;
margin-bottom: 10px;
}
.result.success {
background: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
}
.result.error {
background: #f8d7da;
border: 1px solid #f5c6cb;
color: #721c24;
}
.json-output {
background: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 12px;
white-space: pre-wrap;
word-wrap: break-word;
margin-top: 10px;
}
.loading {
text-align: center;
padding: 20px;
display: none;
}
.loading.show {
display: block;
}
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #667eea;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.info {
background: #e7f3ff;
border: 1px solid #b3d9ff;
color: #004085;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
font-size: 14px;
}
.icon {
font-size: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>🔐 Social Auth Test</h1>
<p class="subtitle">Django REST API - Social Authentication</p>
<div class="info">
<strong>⚠️ Not:</strong> Bu sayfa sadece test amaçlıdır. Google için callback URL'ini Google Console'da ayarlamanız gerekiyor: <code>http://localhost:8000/api/v1/social/complete/google-oauth2/</code>
</div>
<button class="btn btn-google" onclick="loginWithGoogle()">
<span class="icon">🔵</span>
Login with Google
</button>
<button class="btn btn-github" onclick="loginWithGithub()">
<span class="icon"></span>
Login with GitHub
</button>
<div class="loading" id="loading">
<div class="spinner"></div>
<p style="margin-top: 10px;">Processing...</p>
</div>
<div class="result" id="result">
<h3 id="resultTitle">Result</h3>
<div id="resultContent"></div>
</div>
</div>
<!-- Google OAuth2 Library -->
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script>
const API_BASE = 'http://localhost:8000/api/v1';
const GOOGLE_CLIENT_ID = '915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com';
// Initialize Google OAuth
function initGoogleAuth() {
google.accounts.id.initialize({
client_id: GOOGLE_CLIENT_ID,
callback: handleGoogleCallback
});
}
// Google Login
function loginWithGoogle() {
showLoading();
google.accounts.id.prompt();
}
// Handle Google OAuth callback
async function handleGoogleCallback(response) {
console.log('Google OAuth Response:', response);
// Google'dan gelen credential (JWT token)
const credential = response.credential;
try {
// Backend'e gönder
const result = await fetch(`${API_BASE}/auth/social/google-oauth2/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
access_token: credential,
id_token: credential
})
});
const data = await result.json();
hideLoading();
if (result.ok) {
showResult('success', 'Google Login Successful! ✅', data);
} else {
showResult('error', 'Google Login Failed ❌', data);
}
} catch (error) {
hideLoading();
showResult('error', 'Error', { message: error.message });
}
}
// GitHub Login
async function loginWithGithub() {
showResult('error', 'GitHub OAuth Flow', {
message: 'GitHub OAuth requires server-side redirect flow.',
instruction: 'Use this endpoint instead:',
url: `${API_BASE}/social/login/github/`,
note: 'Or use the curl command below for testing with a real GitHub token'
});
}
// Show loading
function showLoading() {
document.getElementById('loading').classList.add('show');
document.getElementById('result').classList.remove('show');
}
// Hide loading
function hideLoading() {
document.getElementById('loading').classList.remove('show');
}
// Show result
function showResult(type, title, data) {
const resultDiv = document.getElementById('result');
const resultTitle = document.getElementById('resultTitle');
const resultContent = document.getElementById('resultContent');
resultDiv.className = `result show ${type}`;
resultTitle.textContent = title;
if (type === 'success' && data.user) {
resultContent.innerHTML = `
<p><strong>User Info:</strong></p>
<p>Email: ${data.user.email}</p>
<p>Name: ${data.user.first_name} ${data.user.last_name}</p>
<p>ID: ${data.user.id}</p>
<p><strong>Tokens:</strong></p>
<div class="json-output">${JSON.stringify(data, null, 2)}</div>
`;
} else {
resultContent.innerHTML = `
<div class="json-output">${JSON.stringify(data, null, 2)}</div>
`;
}
}
// Initialize when page loads
window.onload = function() {
if (typeof google !== 'undefined') {
initGoogleAuth();
}
};
</script>
</body>
</html>