Files
atabackend/static/spa-test.js
Beyhan Oğur d50f14bcb1 first commit
2026-04-26 22:20:45 +03:00

382 lines
12 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// API Base URL
const API_BASE = 'http://localhost:8000/api/v1';
// Google OAuth Client ID
const GOOGLE_CLIENT_ID = '915364976256-691m0s87as2r5vdbqr96f6humblseobt.apps.googleusercontent.com';
// Initialize app
document.addEventListener('DOMContentLoaded', () => {
checkAuth();
checkOAuthCallback();
});
// Check if user is authenticated
function checkAuth() {
const accessToken = localStorage.getItem('access_token');
if (accessToken) {
// User is logged in, show dashboard
loadUserProfile();
} else {
// User is not logged in, show login page
showLogin();
}
}
// Check for OAuth callback parameters
function checkOAuthCallback() {
const urlParams = new URLSearchParams(window.location.search);
const access = urlParams.get('access');
const refresh = urlParams.get('refresh');
if (access && refresh) {
// Save tokens from OAuth callback
localStorage.setItem('access_token', access);
localStorage.setItem('refresh_token', refresh);
// Clean URL
window.history.replaceState({}, document.title, window.location.pathname);
// Load user profile
loadUserProfile();
}
}
// Show login page
function showLogin() {
document.getElementById('loginPage').style.display = 'flex';
document.getElementById('registerPage').style.display = 'none';
document.getElementById('dashboardPage').style.display = 'none';
document.getElementById('navbar').style.display = 'none';
}
// Show register page
function showRegister() {
document.getElementById('loginPage').style.display = 'none';
document.getElementById('registerPage').style.display = 'flex';
document.getElementById('dashboardPage').style.display = 'none';
document.getElementById('navbar').style.display = 'none';
}
// Show dashboard
function showDashboard() {
document.getElementById('loginPage').style.display = 'none';
document.getElementById('registerPage').style.display = 'none';
document.getElementById('dashboardPage').style.display = 'flex';
document.getElementById('navbar').style.display = 'block';
}
// Show loading
function showLoading() {
document.getElementById('loadingOverlay').style.display = 'flex';
}
// Hide loading
function hideLoading() {
document.getElementById('loadingOverlay').style.display = 'none';
}
// Show error
function showError(message) {
const errorAlert = document.getElementById('errorAlert');
errorAlert.textContent = message;
errorAlert.style.display = 'block';
setTimeout(() => {
errorAlert.style.display = 'none';
}, 5000);
}
// Handle login form submit
async function handleLogin(event) {
event.preventDefault();
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
showLoading();
try {
const response = await fetch(`${API_BASE}/auth/jwt/create/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password })
});
const data = await response.json();
if (response.ok) {
// Save tokens
localStorage.setItem('access_token', data.access);
localStorage.setItem('refresh_token', data.refresh);
// Load profile
await loadUserProfile();
} else {
hideLoading();
showError(data.detail || 'Login failed. Please check your credentials.');
}
} catch (error) {
hideLoading();
showError('Network error. Please try again.');
}
}
// Handle register form submit
async function handleRegister(event) {
event.preventDefault();
const email = document.getElementById('regEmail').value;
const password = document.getElementById('regPassword').value;
const passwordConfirm = document.getElementById('regPasswordConfirm').value;
const firstName = document.getElementById('firstName').value;
const lastName = document.getElementById('lastName').value;
if (password !== passwordConfirm) {
showError('Passwords do not match!');
return;
}
showLoading();
try {
const response = await fetch(`${API_BASE}/auth/users/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
re_password: passwordConfirm,
first_name: firstName,
last_name: lastName
})
});
const data = await response.json();
hideLoading();
if (response.ok) {
// Show success message
document.getElementById('registerSuccess').style.display = 'block';
document.getElementById('registerForm').reset();
// Redirect to login after 3 seconds
setTimeout(() => {
showLogin();
document.getElementById('registerSuccess').style.display = 'none';
}, 3000);
} else {
const errorMsg = Object.values(data).flat().join(', ');
showError(errorMsg || 'Registration failed.');
}
} catch (error) {
hideLoading();
showError('Network error. Please try again.');
}
}
// Load user profile
async function loadUserProfile() {
showLoading();
const accessToken = localStorage.getItem('access_token');
try {
const response = await fetch(`${API_BASE}/auth/users/me/`, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
if (response.ok) {
const user = await response.json();
// Update UI with user data
document.getElementById('userEmail').textContent = user.email;
document.getElementById('profileName').textContent =
`${user.first_name} ${user.last_name}` || user.email;
document.getElementById('profileEmail').textContent = user.email;
document.getElementById('userEmailStat').textContent = user.email;
document.getElementById('profileStatus').textContent =
user.is_active ? '✅ Active' : '❌ Inactive';
// Format date
const joinDate = new Date(user.date_joined);
document.getElementById('joinedDate').textContent =
joinDate.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
// Show tokens
document.getElementById('accessToken').value = localStorage.getItem('access_token');
document.getElementById('refreshToken').value = localStorage.getItem('refresh_token');
hideLoading();
showDashboard();
} else {
// Token expired or invalid
logout();
}
} catch (error) {
hideLoading();
showError('Failed to load profile.');
logout();
}
}
// Logout
function logout() {
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
showLogin();
}
// Copy token to clipboard
function copyToken(type) {
const token = type === 'access'
? document.getElementById('accessToken').value
: document.getElementById('refreshToken').value;
navigator.clipboard.writeText(token)
.then(() => alert(`${type} token copied to clipboard!`))
.catch(() => alert('Failed to copy token'));
}
// ============================================================================
// SOCIAL AUTH - TOKEN-BASED FLOW (like Nuxt/Next.js)
// ============================================================================
// Google Login (Token-Based)
function loginWithGoogle() {
// Trigger Google One Tap or popup
google.accounts.id.prompt();
}
// Handle Google OAuth callback
async function handleGoogleCallback(response) {
console.log('[Google OAuth] Credential received:', response.credential);
showLoading();
try {
// Send Google's ID token to Django backend
const result = await fetch(`${API_BASE}/auth/social/google-oauth2/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
access_token: response.credential, // Google's ID token
id_token: response.credential
})
});
const data = await result.json();
console.log('[Django Response]:', data);
hideLoading();
if (result.ok) {
// Save JWT tokens from Django
localStorage.setItem('access_token', data.access);
localStorage.setItem('refresh_token', data.refresh);
console.log('[Success] JWT tokens saved to localStorage');
// Load user profile
await loadUserProfile();
} else {
showError(data.error || 'Google login failed');
}
} catch (error) {
hideLoading();
console.error('[Error]:', error);
showError('Network error during Google login');
}
}
// GitHub Login (Token-Based)
async function loginWithGitHub() {
alert(`
⚠️ GitHub Token-Based Flow için:
1. GitHub Personal Access Token oluşturun:
https://github.com/settings/tokens
2. Scopes: user, user:email
3. Token'ı prompt'a girin
NOT: Production'da OAuth2 PKCE flow kullanılmalı.
Bu sadece test için!
`);
const token = prompt('GitHub Personal Access Token girin:');
if (!token) return;
showLoading();
try {
const result = await fetch(`${API_BASE}/auth/social/github/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
access_token: token
})
});
const data = await result.json();
console.log('[Django Response]:', data);
hideLoading();
if (result.ok) {
// Save JWT tokens from Django
localStorage.setItem('access_token', data.access);
localStorage.setItem('refresh_token', data.refresh);
console.log('[Success] JWT tokens saved to localStorage');
// Load user profile
await loadUserProfile();
} else {
showError(data.error || 'GitHub login failed');
}
} catch (error) {
hideLoading();
console.error('[Error]:', error);
showError('Network error during GitHub login');
}
}
// Test protected endpoint
async function testProtectedEndpoint() {
showLoading();
const accessToken = localStorage.getItem('access_token');
try {
const response = await fetch(`${API_BASE}/auth/users/me/`, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
hideLoading();
if (response.ok) {
alert('✅ Protected endpoint access successful!\n\nYour JWT token is working correctly.');
} else {
alert('❌ Protected endpoint access failed.\n\nToken may be expired or invalid.');
}
} catch (error) {
hideLoading();
alert('❌ Network error while testing endpoint.');
}
}