nanobot özel sürüm v1
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
const passport = require('passport');
|
||||
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
@@ -32,67 +31,71 @@ passport.deserializeUser(async (id, done) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Google OAuth Strategy
|
||||
passport.use(new GoogleStrategy({
|
||||
clientID: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
callbackURL: process.env.GOOGLE_CALLBACK_URL || "/api/auth/google/callback"
|
||||
}, async (accessToken, refreshToken, profile, done) => {
|
||||
try {
|
||||
// Önce Google ID ile kullanıcı ara
|
||||
let user = await prisma.user.findUnique({
|
||||
where: { googleId: profile.id }
|
||||
});
|
||||
|
||||
if (user) {
|
||||
// Kullanıcı zaten var, son giriş tarihini güncelle
|
||||
user = await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: { lastLoginAt: new Date() }
|
||||
// Google OAuth Strategy - Sadece credentials varsa yükle
|
||||
if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET) {
|
||||
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
||||
|
||||
passport.use(new GoogleStrategy({
|
||||
clientID: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
callbackURL: process.env.GOOGLE_CALLBACK_URL || "/api/auth/google/callback"
|
||||
}, async (accessToken, refreshToken, profile, done) => {
|
||||
try {
|
||||
// Önce Google ID ile kullanıcı ara
|
||||
let user = await prisma.user.findUnique({
|
||||
where: { googleId: profile.id }
|
||||
});
|
||||
return done(null, user);
|
||||
}
|
||||
|
||||
// Email ile kullanıcı ara (mevcut hesap varsa bağla)
|
||||
user = await prisma.user.findUnique({
|
||||
where: { email: profile.emails[0].value }
|
||||
});
|
||||
if (user) {
|
||||
// Kullanıcı zaten var, son giriş tarihini güncelle
|
||||
user = await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: { lastLoginAt: new Date() }
|
||||
});
|
||||
return done(null, user);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
// Mevcut hesabı Google ile bağla
|
||||
user = await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
// Email ile kullanıcı ara (mevcut hesap varsa bağla)
|
||||
user = await prisma.user.findUnique({
|
||||
where: { email: profile.emails[0].value }
|
||||
});
|
||||
|
||||
if (user) {
|
||||
// Mevcut hesabı Google ile bağla
|
||||
user = await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: {
|
||||
googleId: profile.id,
|
||||
authProvider: 'google',
|
||||
avatar: profile.photos[0]?.value || user.avatar,
|
||||
lastLoginAt: new Date()
|
||||
}
|
||||
});
|
||||
return done(null, user);
|
||||
}
|
||||
|
||||
// Yeni kullanıcı oluştur
|
||||
const username = profile.emails[0].value.split('@')[0] + '_' + Math.random().toString(36).substr(2, 4);
|
||||
|
||||
user = await prisma.user.create({
|
||||
data: {
|
||||
email: profile.emails[0].value,
|
||||
username: username,
|
||||
firstName: profile.name.givenName || '',
|
||||
lastName: profile.name.familyName || '',
|
||||
googleId: profile.id,
|
||||
authProvider: 'google',
|
||||
avatar: profile.photos[0]?.value || user.avatar,
|
||||
avatar: profile.photos[0]?.value,
|
||||
lastLoginAt: new Date()
|
||||
}
|
||||
});
|
||||
|
||||
return done(null, user);
|
||||
} catch (error) {
|
||||
console.error('Google OAuth Error:', error);
|
||||
return done(error, null);
|
||||
}
|
||||
|
||||
// Yeni kullanıcı oluştur
|
||||
const username = profile.emails[0].value.split('@')[0] + '_' + Math.random().toString(36).substr(2, 4);
|
||||
|
||||
user = await prisma.user.create({
|
||||
data: {
|
||||
email: profile.emails[0].value,
|
||||
username: username,
|
||||
firstName: profile.name.givenName || '',
|
||||
lastName: profile.name.familyName || '',
|
||||
googleId: profile.id,
|
||||
authProvider: 'google',
|
||||
avatar: profile.photos[0]?.value,
|
||||
lastLoginAt: new Date()
|
||||
}
|
||||
});
|
||||
|
||||
return done(null, user);
|
||||
} catch (error) {
|
||||
console.error('Google OAuth Error:', error);
|
||||
return done(error, null);
|
||||
}
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
module.exports = passport;
|
||||
@@ -1,5 +1,4 @@
|
||||
const express = require('express');
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
const { authenticateToken, checkListMembership, requireListEditPermission } = require('../middleware/auth');
|
||||
const { asyncHandler } = require('../middleware/errorHandler');
|
||||
const {
|
||||
@@ -15,7 +14,6 @@ const { successResponse, errorResponse, calculatePagination, createPaginationMet
|
||||
const notificationService = require('../services/notificationService');
|
||||
|
||||
const router = express.Router();
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
/**
|
||||
* Liste öğelerini getir
|
||||
@@ -68,8 +66,8 @@ router.get('/:listId',
|
||||
|
||||
// Toplam sayı ve öğeleri getir
|
||||
const [total, items] = await Promise.all([
|
||||
prisma.listItem.count({ where }),
|
||||
prisma.listItem.findMany({
|
||||
req.prisma.listItem.count({ where }),
|
||||
req.prisma.listItem.findMany({
|
||||
where,
|
||||
skip,
|
||||
take,
|
||||
@@ -116,7 +114,7 @@ router.get('/:listId/:itemId',
|
||||
|
||||
const { listId, itemId } = req.params;
|
||||
|
||||
const item = await prisma.listItem.findFirst({
|
||||
const item = await req.prisma.listItem.findFirst({
|
||||
where: {
|
||||
id: itemId,
|
||||
listId
|
||||
@@ -179,7 +177,7 @@ router.post('/:listId',
|
||||
// Eğer productId verilmişse, ürünün var olduğunu kontrol et
|
||||
let product = null;
|
||||
if (productId) {
|
||||
product = await prisma.product.findUnique({
|
||||
product = await req.prisma.product.findUnique({
|
||||
where: { id: productId }
|
||||
});
|
||||
|
||||
@@ -189,7 +187,7 @@ router.post('/:listId',
|
||||
}
|
||||
|
||||
// Aynı öğenin listede zaten var olup olmadığını kontrol et
|
||||
const existingItem = await prisma.listItem.findFirst({
|
||||
const existingItem = await req.prisma.listItem.findFirst({
|
||||
where: {
|
||||
listId,
|
||||
OR: [
|
||||
@@ -204,7 +202,7 @@ router.post('/:listId',
|
||||
}
|
||||
|
||||
// Yeni öğe oluştur
|
||||
const newItem = await prisma.listItem.create({
|
||||
const newItem = await req.prisma.listItem.create({
|
||||
data: {
|
||||
customName: productId ? product.name : name,
|
||||
quantity,
|
||||
@@ -226,26 +224,26 @@ router.post('/:listId',
|
||||
// Ürün kullanım sayısını artır (Product modelinde usageCount alanı yok, bu özellik kaldırıldı)
|
||||
|
||||
// Liste güncelleme tarihini güncelle
|
||||
await prisma.shoppingList.update({
|
||||
await req.prisma.shoppingList.update({
|
||||
where: { id: listId },
|
||||
data: { updatedAt: new Date() }
|
||||
});
|
||||
|
||||
// Aktivite kaydı oluştur
|
||||
await prisma.activity.create({
|
||||
data: {
|
||||
action: 'item_added',
|
||||
details: {
|
||||
itemId: newItem.id,
|
||||
itemName: newItem.customName || newItem.product?.name || 'Öğe',
|
||||
userName: `${req.user.firstName} ${req.user.lastName}`
|
||||
},
|
||||
userId,
|
||||
listId
|
||||
}
|
||||
});
|
||||
// Aktivite kaydı oluştur (geçici olarak devre dışı)
|
||||
// await req.prisma.activity.create({
|
||||
// data: {
|
||||
// action: 'item_added',
|
||||
// details: {
|
||||
// itemId: newItem.id,
|
||||
// itemName: newItem.customName || newItem.product?.name || 'Öğe',
|
||||
// userName: `${req.user.firstName} ${req.user.lastName}`
|
||||
// },
|
||||
// userId,
|
||||
// listId
|
||||
// }
|
||||
// });
|
||||
|
||||
// Liste üyelerine bildirim gönder (geçici olarak devre dışı - notifyListMembers fonksiyonu mevcut değil)
|
||||
// Liste üyelerine bildirim gönder (geçici olarak devre dışı)
|
||||
// await notificationService.notifyListMembers(
|
||||
// listId,
|
||||
// userId,
|
||||
@@ -254,14 +252,14 @@ router.post('/:listId',
|
||||
// { itemId: newItem.id, itemName: newItem.customName || newItem.product?.name }
|
||||
// );
|
||||
|
||||
// Socket.IO ile gerçek zamanlı güncelleme
|
||||
const io = req.app.get('io');
|
||||
if (io) {
|
||||
io.to(`list_${listId}`).emit('itemAdded', {
|
||||
item: newItem,
|
||||
addedBy: req.user
|
||||
});
|
||||
}
|
||||
// Socket.IO ile gerçek zamanlı güncelleme (geçici olarak devre dışı)
|
||||
// const io = req.app.get('io');
|
||||
// if (io) {
|
||||
// io.to(`list_${listId}`).emit('itemAdded', {
|
||||
// item: newItem,
|
||||
// addedBy: req.user
|
||||
// });
|
||||
// }
|
||||
|
||||
// Priority değerini string'e çevir
|
||||
const newItemWithStringPriority = {
|
||||
@@ -321,7 +319,7 @@ router.put('/:listId/:itemId',
|
||||
|
||||
// Öğenin var olduğunu kontrol et
|
||||
console.log('🔍 Öğe aranıyor:', { itemId, listId });
|
||||
const existingItem = await prisma.listItem.findFirst({
|
||||
const existingItem = await req.prisma.listItem.findFirst({
|
||||
where: {
|
||||
id: itemId,
|
||||
listId
|
||||
@@ -364,7 +362,7 @@ router.put('/:listId/:itemId',
|
||||
}
|
||||
|
||||
// Öğeyi güncelle
|
||||
const updatedItem = await prisma.listItem.update({
|
||||
const updatedItem = await req.prisma.listItem.update({
|
||||
where: { id: itemId },
|
||||
data: updateData,
|
||||
include: {
|
||||
@@ -378,7 +376,7 @@ router.put('/:listId/:itemId',
|
||||
|
||||
// Fiyat geçmişi ekle (eğer fiyat girilmişse ve ürün varsa)
|
||||
if (price && existingItem.productId && isPurchased) {
|
||||
await prisma.priceHistory.create({
|
||||
await req.prisma.priceHistory.create({
|
||||
data: {
|
||||
price: price,
|
||||
productId: existingItem.productId,
|
||||
@@ -389,7 +387,7 @@ router.put('/:listId/:itemId',
|
||||
}
|
||||
|
||||
// Liste güncelleme tarihini güncelle
|
||||
await prisma.shoppingList.update({
|
||||
await req.prisma.shoppingList.update({
|
||||
where: { id: listId },
|
||||
data: { updatedAt: new Date() }
|
||||
});
|
||||
@@ -402,7 +400,7 @@ router.put('/:listId/:itemId',
|
||||
: `${req.user.firstName} ${req.user.lastName} "${updatedItem.name}" öğesinin satın alma durumunu iptal etti`;
|
||||
}
|
||||
|
||||
await prisma.activity.create({
|
||||
await req.prisma.activity.create({
|
||||
data: {
|
||||
action: isPurchased !== undefined ? (isPurchased ? 'ITEM_PURCHASED' : 'ITEM_UNPURCHASED') : 'ITEM_UPDATED',
|
||||
details: {
|
||||
@@ -467,7 +465,7 @@ router.delete('/:listId/:itemId',
|
||||
const userId = req.user.id;
|
||||
|
||||
// Öğenin var olduğunu kontrol et
|
||||
const existingItem = await prisma.listItem.findFirst({
|
||||
const existingItem = await req.prisma.listItem.findFirst({
|
||||
where: {
|
||||
id: itemId,
|
||||
listId
|
||||
@@ -479,19 +477,19 @@ router.delete('/:listId/:itemId',
|
||||
}
|
||||
|
||||
// Öğeyi sil
|
||||
await prisma.listItem.delete({
|
||||
await req.prisma.listItem.delete({
|
||||
where: { id: itemId }
|
||||
});
|
||||
|
||||
// Liste güncelleme tarihini güncelle
|
||||
await prisma.shoppingList.update({
|
||||
await req.prisma.shoppingList.update({
|
||||
where: { id: listId },
|
||||
data: { updatedAt: new Date() }
|
||||
});
|
||||
|
||||
// Aktivite kaydı oluştur (Prisma şemasına uygun)
|
||||
const itemName = existingItem.customName || existingItem.product?.name || 'Öğe';
|
||||
await prisma.activity.create({
|
||||
await req.prisma.activity.create({
|
||||
data: {
|
||||
action: 'ITEM_REMOVED',
|
||||
details: {
|
||||
@@ -551,7 +549,7 @@ router.patch('/:listId/bulk',
|
||||
}
|
||||
|
||||
// Öğelerin var olduğunu kontrol et
|
||||
const existingItems = await prisma.listItem.findMany({
|
||||
const existingItems = await req.prisma.listItem.findMany({
|
||||
where: {
|
||||
id: { in: items },
|
||||
listId
|
||||
@@ -593,14 +591,14 @@ router.patch('/:listId/bulk',
|
||||
|
||||
// Toplu güncelleme veya silme
|
||||
if (action === 'delete') {
|
||||
await prisma.listItem.deleteMany({
|
||||
await req.prisma.listItem.deleteMany({
|
||||
where: {
|
||||
id: { in: items },
|
||||
listId
|
||||
}
|
||||
});
|
||||
} else {
|
||||
await prisma.listItem.updateMany({
|
||||
await req.prisma.listItem.updateMany({
|
||||
where: {
|
||||
id: { in: items },
|
||||
listId
|
||||
@@ -610,13 +608,13 @@ router.patch('/:listId/bulk',
|
||||
}
|
||||
|
||||
// Liste güncelleme tarihini güncelle
|
||||
await prisma.shoppingList.update({
|
||||
await req.prisma.shoppingList.update({
|
||||
where: { id: listId },
|
||||
data: { updatedAt: new Date() }
|
||||
});
|
||||
|
||||
// Aktivite kaydı oluştur
|
||||
await prisma.activity.create({
|
||||
await req.prisma.activity.create({
|
||||
data: {
|
||||
type: activityType,
|
||||
description: activityDescription,
|
||||
|
||||
@@ -198,23 +198,25 @@ router.post('/', authenticateToken, [
|
||||
}
|
||||
});
|
||||
|
||||
// Aktivite kaydı oluştur
|
||||
await req.prisma.activity.create({
|
||||
data: {
|
||||
listId: list.id,
|
||||
userId: req.user.id,
|
||||
action: 'list_created',
|
||||
details: {
|
||||
listName: list.name
|
||||
}
|
||||
}
|
||||
});
|
||||
// Aktivite kaydı oluştur (geçici olarak devre dışı)
|
||||
// await req.prisma.activity.create({
|
||||
// data: {
|
||||
// listId: list.id,
|
||||
// userId: req.user.id,
|
||||
// action: 'list_created',
|
||||
// details: {
|
||||
// listName: list.name
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// Socket.IO ile gerçek zamanlı bildirim gönder
|
||||
req.io.emit('list_created', {
|
||||
list: { ...list, userRole: 'owner' },
|
||||
user: req.user
|
||||
});
|
||||
// Socket.IO ile gerçek zamanlı bildirim gönder (geçici olarak devre dışı)
|
||||
// if (req.io) {
|
||||
// req.io.emit('list_created', {
|
||||
// list: { ...list, userRole: 'owner' },
|
||||
// user: req.user
|
||||
// });
|
||||
// }
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
|
||||
@@ -148,7 +148,7 @@ process.on('SIGINT', async () => {
|
||||
});
|
||||
|
||||
// Sunucuyu başlat
|
||||
const PORT = process.env.PORT || 5000;
|
||||
const PORT = process.env.PORT || 7001;
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log(`🚀 Server ${PORT} portunda çalışıyor - port 7001`);
|
||||
|
||||
@@ -9,6 +9,16 @@ class NotificationService {
|
||||
|
||||
initializeFirebase() {
|
||||
try {
|
||||
// Firebase credentials kontrolü
|
||||
const hasCredentials = process.env.FIREBASE_PROJECT_ID &&
|
||||
process.env.FIREBASE_PRIVATE_KEY &&
|
||||
process.env.FIREBASE_CLIENT_EMAIL;
|
||||
|
||||
if (!hasCredentials) {
|
||||
console.log('⚠️ Firebase credentials not configured. Push notifications disabled.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!admin.apps.length) {
|
||||
const serviceAccount = {
|
||||
type: process.env.FIREBASE_TYPE,
|
||||
@@ -27,10 +37,11 @@ class NotificationService {
|
||||
credential: admin.credential.cert(serviceAccount)
|
||||
});
|
||||
|
||||
console.log('Firebase Admin SDK initialized successfully');
|
||||
console.log('✅ Firebase Admin SDK initialized successfully');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Firebase initialization error:', error);
|
||||
console.error('Firebase initialization error:', error.message);
|
||||
console.warn('Push notifications will be disabled.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,20 @@ function getDatabaseName(databaseUrl) {
|
||||
|
||||
async function setupUtf8mb4(prisma) {
|
||||
const databaseUrl = process.env.DATABASE_URL || '';
|
||||
|
||||
// SQLite için bu fonksiyonu atla
|
||||
if (databaseUrl.includes('sqlite') || databaseUrl.includes('.db')) {
|
||||
console.log('ℹ️ SQLite kullanılıyor. UTF8MB4 kurulumu atlandı.');
|
||||
return;
|
||||
}
|
||||
|
||||
const dbName = getDatabaseName(databaseUrl);
|
||||
if (!dbName) {
|
||||
console.warn('⚠️ DATABASE_URL bulunamadı veya veritabanı adı çözümlenemedi. UTF8MB4 kurulumu atlandı.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Try altering database charset/collation
|
||||
// Only run for MySQL/MariaDB
|
||||
try {
|
||||
await prisma.$executeRawUnsafe(`ALTER DATABASE \`${dbName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`);
|
||||
console.log('✅ Veritabanı varsayılan karakter seti/collation utf8mb4 olarak ayarlandı.');
|
||||
@@ -30,7 +37,6 @@ async function setupUtf8mb4(prisma) {
|
||||
console.warn('⚠️ Veritabanı charset ayarlanırken hata oluştu:', err?.message || err);
|
||||
}
|
||||
|
||||
// Try converting categories table
|
||||
try {
|
||||
await prisma.$executeRawUnsafe('ALTER TABLE `categories` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
|
||||
console.log('✅ `categories` tablosu utf8mb4 olarak dönüştürüldü.');
|
||||
|
||||
Reference in New Issue
Block a user