Refactor backend CORS settings to include default origins and improve error handling in chat services: Introduce dynamic CORS origin handling, enhance RabbitMQ message sending with fallback mechanisms, and update WebSocket service to manage pending messages. Update UI components for better accessibility and responsiveness, including adjustments to dialog and navigation elements. Enhance styling for improved user experience across various components.
This commit is contained in:
@@ -36,10 +36,18 @@ const app = express();
|
||||
// - LOG_ALL_REQ=1: Logge alle Requests
|
||||
const LOG_ALL_REQ = process.env.LOG_ALL_REQ === '1';
|
||||
const LOG_SLOW_REQ_MS = Number.parseInt(process.env.LOG_SLOW_REQ_MS || '500', 10);
|
||||
const defaultCorsOrigins = [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://127.0.0.1:3000',
|
||||
'http://127.0.0.1:5173'
|
||||
];
|
||||
const corsOrigins = (process.env.CORS_ORIGINS || process.env.FRONTEND_URL || '')
|
||||
.split(',')
|
||||
.map((origin) => origin.trim())
|
||||
.filter(Boolean);
|
||||
const effectiveCorsOrigins = corsOrigins.length > 0 ? corsOrigins : defaultCorsOrigins;
|
||||
const corsAllowAll = process.env.CORS_ALLOW_ALL === '1';
|
||||
|
||||
app.use((req, res, next) => {
|
||||
const reqId = req.headers['x-request-id'] || (crypto.randomUUID ? crypto.randomUUID() : crypto.randomBytes(8).toString('hex'));
|
||||
@@ -61,7 +69,7 @@ const corsOptions = {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
if (corsOrigins.length === 0 || corsOrigins.includes(origin)) {
|
||||
if (corsAllowAll || effectiveCorsOrigins.includes(origin)) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,13 @@ class ChatService {
|
||||
});
|
||||
}
|
||||
if (this.channel && this.amqpAvailable) {
|
||||
this.channel.sendToQueue(QUEUE, Buffer.from(JSON.stringify(messageBundle)));
|
||||
try {
|
||||
this.channel.sendToQueue(QUEUE, Buffer.from(JSON.stringify(messageBundle)));
|
||||
} catch (error) {
|
||||
console.warn('[chatService] sendToQueue fehlgeschlagen, Queue-Bridge vorübergehend deaktiviert:', error.message);
|
||||
this.channel = null;
|
||||
this.amqpAvailable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -389,6 +389,8 @@ class FalukantService extends BaseService {
|
||||
one: { min: 50, max: 5000 },
|
||||
all: { min: 400, max: 40000 }
|
||||
};
|
||||
static WOOING_PROGRESS_TARGET = 70;
|
||||
static WOOING_GIFT_COOLDOWN_MS = 30 * 60 * 1000;
|
||||
static HEALTH_ACTIVITIES = [
|
||||
{ tr: "barber", method: "healthBarber", cost: 10 },
|
||||
{ tr: "doctor", method: "healthDoctor", cost: 50 },
|
||||
@@ -3311,8 +3313,8 @@ class FalukantService extends BaseService {
|
||||
order: [['createdAt', 'DESC']],
|
||||
limit: 1
|
||||
});
|
||||
if (lastGift && (lastGift.createdAt.getTime() + 3_600_000) > Date.now()) {
|
||||
const retryAt = new Date(lastGift.createdAt.getTime() + 3_600_000);
|
||||
if (lastGift && (lastGift.createdAt.getTime() + FalukantService.WOOING_GIFT_COOLDOWN_MS) > Date.now()) {
|
||||
const retryAt = new Date(lastGift.createdAt.getTime() + FalukantService.WOOING_GIFT_COOLDOWN_MS);
|
||||
const err = new PreconditionError('tooOften');
|
||||
err.meta = { retryAt: retryAt.toISOString() };
|
||||
throw err;
|
||||
@@ -3381,7 +3383,7 @@ class FalukantService extends BaseService {
|
||||
|
||||
async checkProposalProgress(relation) {
|
||||
const { nextStepProgress } = relation;
|
||||
if (nextStepProgress >= 100) {
|
||||
if (nextStepProgress >= FalukantService.WOOING_PROGRESS_TARGET) {
|
||||
const engagedStatus = await RelationshipType.findOne({ where: { tr: 'engaged' } });
|
||||
await relation.update({ nextStepProgress: 0, relationshipTypeId: engagedStatus.id });
|
||||
const user = await User.findOne({
|
||||
|
||||
@@ -4,10 +4,50 @@ import amqp from 'amqplib/callback_api.js';
|
||||
|
||||
const RABBITMQ_URL = process.env.AMQP_URL || 'amqp://localhost';
|
||||
const QUEUE = 'chat_messages';
|
||||
const MAX_PENDING_MESSAGES = 500;
|
||||
|
||||
function routeMessage(io, message) {
|
||||
if (!message || typeof message !== 'object') return;
|
||||
|
||||
if (message.socketId) {
|
||||
io.to(message.socketId).emit('newMessage', message);
|
||||
return;
|
||||
}
|
||||
if (message.recipientSocketId) {
|
||||
io.to(message.recipientSocketId).emit('newMessage', message);
|
||||
return;
|
||||
}
|
||||
if (message.roomId) {
|
||||
io.to(String(message.roomId)).emit('newMessage', message);
|
||||
return;
|
||||
}
|
||||
if (message.room) {
|
||||
io.to(String(message.room)).emit('newMessage', message);
|
||||
return;
|
||||
}
|
||||
|
||||
io.emit('newMessage', message);
|
||||
}
|
||||
|
||||
export function setupWebSocket(server) {
|
||||
const io = new Server(server);
|
||||
let channel = null;
|
||||
let pendingMessages = [];
|
||||
|
||||
const flushPendingMessages = () => {
|
||||
if (!channel || pendingMessages.length === 0) return;
|
||||
const queued = pendingMessages;
|
||||
pendingMessages = [];
|
||||
for (const message of queued) {
|
||||
try {
|
||||
channel.sendToQueue(QUEUE, Buffer.from(JSON.stringify(message)));
|
||||
} catch (err) {
|
||||
console.warn('[webSocketService] Flush fehlgeschlagen, Nachricht bleibt im Fallback:', err.message);
|
||||
pendingMessages.unshift(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
amqp.connect(RABBITMQ_URL, (err, connection) => {
|
||||
if (err) {
|
||||
@@ -36,8 +76,9 @@ export function setupWebSocket(server) {
|
||||
channel.consume(QUEUE, (msg) => {
|
||||
if (!msg) return;
|
||||
const message = JSON.parse(msg.content.toString());
|
||||
io.emit('newMessage', message);
|
||||
routeMessage(io, message);
|
||||
}, { noAck: true });
|
||||
flushPendingMessages();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,11 +87,21 @@ export function setupWebSocket(server) {
|
||||
|
||||
socket.on('newMessage', (message) => {
|
||||
if (channel) {
|
||||
channel.sendToQueue(QUEUE, Buffer.from(JSON.stringify(message)));
|
||||
return;
|
||||
try {
|
||||
channel.sendToQueue(QUEUE, Buffer.from(JSON.stringify(message)));
|
||||
} catch (err) {
|
||||
console.warn('[webSocketService] sendToQueue fehlgeschlagen, nutze In-Memory-Fallback:', err.message);
|
||||
channel = null;
|
||||
}
|
||||
}
|
||||
|
||||
io.emit('newMessage', message);
|
||||
if (!channel) {
|
||||
pendingMessages.push(message);
|
||||
if (pendingMessages.length > MAX_PENDING_MESSAGES) {
|
||||
pendingMessages = pendingMessages.slice(-MAX_PENDING_MESSAGES);
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
|
||||
Reference in New Issue
Block a user