Fix Netlify Identity confirmation email authentication flow

- Create dedicated /auth page to handle confirmation, recovery, and invite tokens
- Add proper redirects in _redirects and netlify.toml for token handling
- Update main layout to automatically redirect authentication tokens to auth page
- Add Turkish authentication interface with loading states and error handling
- Provide fallback redirect mechanisms for different token types
- Update documentation with current setup status and fixes

This resolves the issue where confirmation emails linked to hash URLs that didn't work.
Now users will be properly guided through the authentication process.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Buğra
2025-07-10 03:18:53 +03:00
parent db63a8f4d8
commit f041165e9b
5 changed files with 204 additions and 10 deletions
+14 -10
View File
@@ -118,19 +118,23 @@ Netlify redirect rules for admin routing
## Troubleshooting
### Current Error: "Unable to access identity settings"
### Fixed Issues:
**This specific error means:**
- Netlify Identity service is not enabled on your site
- Git Gateway is not enabled
- Or both services need to be configured
**"Unable to access identity settings"** - This was fixed by enabling Identity and Git Gateway in Netlify
**Confirmation email links not working** - Created `/auth` page to handle authentication tokens
**Solution steps:**
### Current Setup Status:
The site now has:
- Custom authentication handler at `/auth`
- Proper redirect handling for confirmation emails
- Automatic routing from hash-based tokens to query parameters
**If you're still getting confirmation email issues:**
1. Go to https://app.netlify.com/sites/ym1ktc/settings/identity
2. If Identity is not enabled, click "Enable Identity"
3. Go to Services tab and enable "Git Gateway"
4. Wait a few minutes for services to activate
5. Try accessing `/admin/` again
2. Check that Identity is enabled
3. Go to Services tab and ensure "Git Gateway" is enabled
4. The confirmation links should now work properly
### Common Issues:
+6
View File
@@ -1 +1,7 @@
# Handle Netlify Identity authentication flows
/#confirmation_token=* /auth?confirmation_token=:splat 200
/#recovery_token=* /auth?recovery_token=:splat 200
/#invite_token=* /auth?invite_token=:splat 200
# Admin panel redirect
/admin/* /decapcms/index.html 200
+22
View File
@@ -0,0 +1,22 @@
[build]
publish = "dist"
[[redirects]]
from = "/#confirmation_token=*"
to = "/auth?confirmation_token=:splat"
status = 200
[[redirects]]
from = "/#recovery_token=*"
to = "/auth?recovery_token=:splat"
status = 200
[[redirects]]
from = "/#invite_token=*"
to = "/auth?invite_token=:splat"
status = 200
[[redirects]]
from = "/admin/*"
to = "/decapcms/index.html"
status = 200
+12
View File
@@ -52,6 +52,18 @@ const { language, textDirection } = I18N;
<script>
if (window.netlifyIdentity) {
window.netlifyIdentity.on('init', (user) => {
// Check if we're on a page that needs authentication handling
const currentPath = window.location.pathname;
const hasAuthTokens = window.location.hash.includes('confirmation_token') ||
window.location.hash.includes('recovery_token') ||
window.location.hash.includes('invite_token');
// If we have auth tokens and we're not on the auth page, redirect to auth page
if (hasAuthTokens && currentPath !== '/auth') {
window.location.href = '/auth' + window.location.hash;
return;
}
if (!user) {
window.netlifyIdentity?.on('login', () => {
document.location.href = '/admin/';
+150
View File
@@ -0,0 +1,150 @@
---
// Authentication handler page for Netlify Identity
---
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kimlik Doğrulama - ARC</title>
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 2rem;
background: #f8fafc;
color: #334155;
}
.container {
max-width: 400px;
margin: 0 auto;
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
text-align: center;
}
.logo {
width: 64px;
height: 64px;
margin: 0 auto 1rem;
background: #3b82f6;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24px;
font-weight: bold;
}
.spinner {
border: 3px solid #f3f4f6;
border-top: 3px solid #3b82f6;
border-radius: 50%;
width: 24px;
height: 24px;
animation: spin 1s linear infinite;
margin: 1rem auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.button {
background: #3b82f6;
color: white;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 6px;
cursor: pointer;
text-decoration: none;
display: inline-block;
margin-top: 1rem;
}
.button:hover {
background: #2563eb;
}
</style>
</head>
<body>
<div class="container">
<div class="logo">ARC</div>
<h1>Kimlik Doğrulama</h1>
<div id="status">
<div class="spinner"></div>
<p>Kimlik doğrulama işlemi yapılıyor...</p>
</div>
</div>
<script>
// Handle Netlify Identity authentication
if (window.netlifyIdentity) {
// Handle the confirmation/recovery tokens
window.netlifyIdentity.on('init', (user) => {
if (user) {
// User is already logged in, redirect to admin
document.getElementById('status').innerHTML = `
<p>✅ Giriş başarılı!</p>
<p>Yönetim paneline yönlendiriliyorsunuz...</p>
`;
setTimeout(() => {
window.location.href = '/admin/';
}, 2000);
} else {
// Check for confirmation/recovery tokens in URL
const urlParams = new URLSearchParams(window.location.search);
const hashParams = new URLSearchParams(window.location.hash.substring(1));
const confirmationToken = urlParams.get('confirmation_token') || hashParams.get('confirmation_token');
const recoveryToken = urlParams.get('recovery_token') || hashParams.get('recovery_token');
const inviteToken = urlParams.get('invite_token') || hashParams.get('invite_token');
if (confirmationToken || recoveryToken || inviteToken) {
document.getElementById('status').innerHTML = `
<p>Hesabınız doğrulanıyor...</p>
<div class="spinner"></div>
`;
// The widget will automatically handle the tokens
// Just wait for the user to be confirmed
window.netlifyIdentity.on('login', (user) => {
document.getElementById('status').innerHTML = `
<p>✅ Hesap doğrulandı!</p>
<p>Yönetim paneline yönlendiriliyorsunuz...</p>
`;
setTimeout(() => {
window.location.href = '/admin/';
}, 2000);
});
window.netlifyIdentity.on('error', (err) => {
console.error('Identity error:', err);
document.getElementById('status').innerHTML = `
<p>❌ Doğrulama hatası</p>
<p>Lütfen tekrar deneyin veya yeni bir davet isteyin.</p>
<a href="/admin/" class="button">Yönetim Paneli</a>
`;
});
} else {
// No tokens, show login option
document.getElementById('status').innerHTML = `
<p>Giriş yapmak için aşağıdaki butona tıklayın.</p>
<a href="/admin/" class="button">Yönetim Paneli</a>
`;
}
}
});
// Initialize the widget
window.netlifyIdentity.init();
} else {
document.getElementById('status').innerHTML = `
<p>❌ Kimlik doğrulama servisi yüklenemedi</p>
<a href="/admin/" class="button">Tekrar Dene</a>
`;
}
</script>
</body>
</html>