Files
AuthCentral/USER_PROFILE_API.md
Beyhan Oğur 8b1fbdee99 first commit
2026-04-26 21:37:58 +03:00

587 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# Kullanıcı Profil Yönetimi API
## Genel Bakış
AuthCentral kullanıcıları kendi profillerini yönetebilir. Bu dokümantasyon kullanıcı profil yönetimi endpoint'lerini açıklar.
## Endpoint'ler
### 1. Profil Bilgilerini Getir
```bash
GET /v1/profile
```
**Headers:**
- `Authorization: Bearer {access_token}`
**Yanıt:**
```json
{
"id": "7d8b023c-d5e4-4f62-8811-ddbf00d675bb",
"username": "admin",
"email": "admin@gauth.local",
"avatar": "/uploads/avatars/admin_avatar.png",
"email_verified": true,
"is_oauth_user": false,
"created_at": "2026-02-04T20:00:00Z",
"updated_at": "2026-02-05T10:00:00Z",
"roles": [
{
"id": 1,
"name": "admin",
"description": "Administrator role"
}
],
"social_accounts": []
}
```
**Yeni Field:**
- `is_oauth_user` (boolean) - Kullanıcı OAuth ile mi giriş yapmış (Google/GitHub)
**Örnek:**
```bash
TOKEN="your_access_token_here"
curl -X GET "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN"
```
---
### 2. Profil Güncelle
```bash
PUT /v1/profile
```
**Headers:**
- `Authorization: Bearer {access_token}`
- `Content-Type: multipart/form-data` (avatar yüklemek için)
**Form Data:**
- `user_name` (string, optional) - Yeni kullanıcı adı
- `avatar` (file, optional) - Profil resmi (max 5MB)
**Örnek (Username Güncelleme):**
```bash
TOKEN="your_access_token_here"
curl -X PUT "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" \
-F "user_name=Beyhan Oğur"
```
**Örnek (Avatar Yükleme):**
```bash
TOKEN="your_access_token_here"
curl -X PUT "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" \
-F "avatar=@/path/to/profile-picture.jpg"
```
**Örnek (Username + Avatar):**
```bash
TOKEN="your_access_token_here"
curl -X PUT "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" \
-F "user_name=Beyhan Oğur" \
-F "avatar=@/path/to/profile-picture.jpg"
```
**Başarılı Yanıt:**
```json
{
"message": "Profile updated successfully",
"user": {
"id": "7d8b023c-d5e4-4f62-8811-ddbf00d675bb",
"username": "Beyhan Oğur",
"email": "admin@gauth.local",
"avatar": "/uploads/avatars/7d8b023c_1770238858420987000.png",
"email_verified": true,
"roles": [...]
}
}
```
---
### 3. Şifre Değiştir
```bash
PUT /v1/profile/password
```
**Headers:**
- `Authorization: Bearer {access_token}`
- `Content-Type: application/json`
**Request Body:**
```json
{
"current_password": "OldPassword123",
"new_password": "NewPassword123"
}
```
**Örnek:**
```bash
TOKEN="your_access_token_here"
curl -X PUT "http://localhost:8080/v1/profile/password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"current_password": "OldPassword123",
"new_password": "NewPassword123"
}'
```
**Başarılı Yanıt:**
```json
{
"message": "Password changed successfully"
}
```
**Hata Yanıtları:**
```json
{
"error": "Current password is incorrect"
}
```
```json
{
"error": "Cannot change password for OAuth users (Google/GitHub login)"
}
```
**Notlar:**
- ✅ Mevcut şifre doğrulanır
- ✅ Yeni şifre minimum 6 karakter olmalı
- ⚠️ **OAuth kullanıcıları (Google/GitHub) şifre değiştiremez**
- ⚠️ Şifre değiştirildikten sonra yeni şifre ile login yapılmalı
- 💡 `is_oauth_user: true` ise şifre değiştirme butonu gösterilmemeli
---
### 4. Email Adresi Değiştir
```bash
PUT /v1/profile/email
```
**Headers:**
- `Authorization: Bearer {access_token}`
- `Content-Type: application/json`
**Request Body:**
```json
{
"new_email": "newemail@example.com",
"password": "YourCurrentPassword"
}
```
**Örnek:**
```bash
TOKEN="your_access_token_here"
curl -X PUT "http://localhost:8080/v1/profile/email" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"new_email": "newemail@example.com",
"password": "YourPassword123"
}'
```
**Başarılı Yanıt:**
```json
{
"message": "Email updated. Please verify your new email address.",
"new_email": "newemail@example.com",
"verification_token": "abc123def456..."
}
```
**Hata Yanıtları:**
```json
{
"error": "Password is incorrect"
}
```
```json
{
"error": "Email already in use"
}
```
```json
{
"error": "Cannot change email for OAuth users (Google/GitHub login)"
}
```
**Önemli Notlar:**
- ⚠️ **OAuth kullanıcıları (Google/GitHub) email değiştiremez**
- ⚠️ Email değiştirildiğinde `email_verified` false olur
- ⚠️ Yeni email adresine doğrulama email'i gönderilir
- ⚠️ Email doğrulanana kadar login yapılamaz
- ⚠️ Email doğrulama için `/v1/auth/verify-email?token=...` endpoint'i kullanılır
- 💡 `is_oauth_user: true` ise email değiştirme butonu gösterilmemeli
---
## Kullanım Senaryoları
### Senaryo 1: Tam Profil Güncelleme
```bash
#!/bin/bash
# Login
TOKEN=$(curl -s -X POST http://localhost:8080/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password123"}' | jq -r '.access_token')
# 1. Kullanıcı adını güncelle
curl -X PUT "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" \
-F "user_name=Yeni İsim"
# 2. Avatar yükle
curl -X PUT "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" \
-F "avatar=@./my-photo.jpg"
# 3. Şifre değiştir
curl -X PUT "http://localhost:8080/v1/profile/password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"current_password": "password123",
"new_password": "newpassword456"
}'
# 4. Profili kontrol et
curl -X GET "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" | jq '.'
```
### Senaryo 2: Email Değiştirme ve Doğrulama
```bash
#!/bin/bash
# Login
TOKEN=$(curl -s -X POST http://localhost:8080/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"old@example.com","password":"password123"}' | jq -r '.access_token')
# 1. Email değiştir
RESPONSE=$(curl -s -X PUT "http://localhost:8080/v1/profile/email" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"new_email": "new@example.com",
"password": "password123"
}')
echo $RESPONSE | jq '.'
# 2. Verification token'ı al
VERIFY_TOKEN=$(echo $RESPONSE | jq -r '.verification_token')
# 3. Email'i doğrula
curl -X GET "http://localhost:8080/v1/auth/verify-email?token=$VERIFY_TOKEN"
# 4. Yeni email ile login
curl -X POST http://localhost:8080/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "new@example.com",
"password": "password123"
}'
```
---
## Frontend Entegrasyonu
### React Örneği
```jsx
import React, { useState, useEffect } from 'react';
function ProfilePage() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
const token = localStorage.getItem('access_token');
// Profil bilgilerini yükle
const fetchProfile = async () => {
try {
const response = await fetch('http://localhost:8080/v1/profile', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
setUser(data);
} catch (error) {
console.error('Error fetching profile:', error);
}
};
// Username güncelle
const updateUsername = async (newUsername) => {
const formData = new FormData();
formData.append('user_name', newUsername);
try {
const response = await fetch('http://localhost:8080/v1/profile', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});
if (response.ok) {
fetchProfile(); // Profili yenile
alert('Username updated!');
}
} catch (error) {
console.error('Error updating username:', error);
}
};
// Avatar yükle
const uploadAvatar = async (file) => {
const formData = new FormData();
formData.append('avatar', file);
try {
const response = await fetch('http://localhost:8080/v1/profile', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});
if (response.ok) {
fetchProfile(); // Profili yenile
alert('Avatar uploaded!');
}
} catch (error) {
console.error('Error uploading avatar:', error);
}
};
// Şifre değiştir
const changePassword = async (currentPassword, newPassword) => {
try {
const response = await fetch('http://localhost:8080/v1/profile/password', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
current_password: currentPassword,
new_password: newPassword
})
});
const data = await response.json();
if (response.ok) {
alert('Password changed successfully!');
} else {
alert(data.error);
}
} catch (error) {
console.error('Error changing password:', error);
}
};
// Email değiştir
const changeEmail = async (newEmail, password) => {
try {
const response = await fetch('http://localhost:8080/v1/profile/email', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
new_email: newEmail,
password: password
})
});
const data = await response.json();
if (response.ok) {
alert('Email updated! Please check your email to verify.');
} else {
alert(data.error);
}
} catch (error) {
console.error('Error changing email:', error);
}
};
useEffect(() => {
fetchProfile();
}, []);
return (
<div>
<h1>Profile</h1>
{user && (
<div>
<img src={`http://localhost:8080${user.avatar}`} alt="Avatar" />
<p>Username: {user.username}</p>
<p>Email: {user.email}</p>
<p>Verified: {user.email_verified ? 'Yes' : 'No'}</p>
{/* OAuth user indicator */}
{user.is_oauth_user && (
<p className="info">
Logged in with {user.social_accounts?.[0]?.provider || 'OAuth'}
</p>
)}
{/* Password change - only for non-OAuth users */}
{!user.is_oauth_user && (
<button onClick={() => {
const current = prompt('Current password:');
const newPass = prompt('New password:');
if (current && newPass) changePassword(current, newPass);
}}>
Change Password
</button>
)}
{/* Email change - only for non-OAuth users */}
{!user.is_oauth_user && (
<button onClick={() => {
const newEmail = prompt('New email:');
const password = prompt('Your password:');
if (newEmail && password) changeEmail(newEmail, password);
}}>
Change Email
</button>
)}
</div>
)}
</div>
);
}
```
---
## API Özeti
| Endpoint | Method | Açıklama | Auth Required |
|----------|--------|----------|---------------|
| `/v1/profile` | GET | Profil bilgilerini getir | ✅ |
| `/v1/profile` | PUT | Profil güncelle (username, avatar) | ✅ |
| `/v1/profile/password` | PUT | Şifre değiştir | ✅ |
| `/v1/profile/email` | PUT | Email değiştir | ✅ |
---
## Güvenlik Notları
**İyi Pratikler:**
- Şifre değiştirirken mevcut şifre doğrulanır
- Email değiştirirken doğrulama email'i gönderilir
- Avatar dosya boyutu sınırlandırılmıştır (max 5MB)
- Tüm endpoint'ler authentication gerektirir
⚠️ **Dikkat Edilmesi Gerekenler:**
- **OAuth kullanıcıları (Google/GitHub) şifre ve email değiştiremez**
- OAuth kullanıcıları sadece username ve avatar değiştirebilir
- Frontend'de `is_oauth_user` flag'ini kontrol edin
- Şifre değiştirme butonu OAuth kullanıcılarına gösterilmemeli
- Email değiştirme butonu OAuth kullanıcılarına gösterilmemeli
- Email değiştirildiğinde yeniden doğrulama gerekir
- Şifre minimum 6 karakter olmalı
- Avatar sadece resim formatları kabul edilir
## OAuth Kullanıcı Kısıtlamaları
| Özellik | Email/Password Kullanıcı | OAuth Kullanıcı (Google/GitHub) |
|---------|-------------------------|--------------------------------|
| Profil Görüntüleme | ✅ Evet | ✅ Evet |
| Username Değiştirme | ✅ Evet | ✅ Evet |
| Avatar Yükleme | ✅ Evet | ✅ Evet |
| **Şifre Değiştirme** | ✅ Evet | ❌ **Hayır** |
| **Email Değiştirme** | ✅ Evet | ❌ **Hayır** |
**Önemli:** Frontend'de `is_oauth_user` field'ını kontrol ederek UI'ı buna göre düzenleyin.
---
## Test Komutları
```bash
# Login ve token al
TOKEN=$(curl -s -X POST http://localhost:8080/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password123"}' | jq -r '.access_token')
# Profil bilgilerini getir
curl -X GET "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" | jq '.'
# Username güncelle
curl -X PUT "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" \
-F "user_name=New Name"
# Avatar yükle
curl -X PUT "http://localhost:8080/v1/profile" \
-H "Authorization: Bearer $TOKEN" \
-F "avatar=@./photo.jpg"
# Şifre değiştir
curl -X PUT "http://localhost:8080/v1/profile/password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"current_password":"old123","new_password":"new456"}'
# Email değiştir
curl -X PUT "http://localhost:8080/v1/profile/email" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"new_email":"new@email.com","password":"password123"}'
```
---
## Özet
🎯 **Özellikler:**
- ✅ Profil bilgilerini görüntüleme
- ✅ Kullanıcı adı güncelleme
- ✅ Avatar yükleme (max 5MB)
- ✅ Şifre değiştirme (mevcut şifre doğrulaması ile)
- ✅ Email değiştirme (yeniden doğrulama ile)
📊 **Kullanım:**
- Her kullanıcı kendi profilini yönetebilir
- OAuth kullanıcıları şifre değiştiremez
- Email değişikliği doğrulama gerektirir
- Avatar otomatik optimize edilir