update auth

This commit is contained in:
2025-12-12 23:35:26 +03:30
parent 6094878e0e
commit 2815c503ff
3 changed files with 96 additions and 14 deletions
+4 -4
View File
@@ -27,7 +27,6 @@ export class TokensService {
slug: string,
em?: EntityManager,
) {
const entityManager = em || this.em;
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE');
const accessExpire = this.configService.getOrThrow<number>('JWT_EXPIRATION_TIME');
@@ -39,7 +38,8 @@ export class TokensService {
const refreshToken = this.generateRefreshToken();
const type = isAdmin ? RefreshTokenType.ADMIN : RefreshTokenType.USER;
await this.storeRefreshToken(ownerId, restaurantId, refreshToken, type, entityManager);
// Only pass em if it's a transaction manager (not this.em), otherwise pass undefined to trigger flush
await this.storeRefreshToken(ownerId, restaurantId, refreshToken, type, em);
return {
accessToken: { token: accessToken, expire: dayjs().add(accessExpire, 'seconds').valueOf() },
@@ -79,8 +79,8 @@ export class TokensService {
// Within transaction, just persist (flush will be called by transaction)
entityManager.persist(token);
} else {
// Outside transaction, persist and flush
return entityManager.persistAndFlush(token);
// Outside transaction, persist and flush immediately
await entityManager.persistAndFlush(token);
}
}
@@ -9,8 +9,7 @@ import {
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { Logger, UseGuards, Inject, forwardRef } from '@nestjs/common';
// import { WsRestId } from './decorators/ws-rest-id.decorator';
import { NotificationService } from './services/notification.service';
import { NotificationService } from './services/notification.service';
import { WsAdminAuthGuard, type AuthenticatedSocket } from './guards/ws-admin-auth.guard';
import { ModuleRef } from '@nestjs/core';
import { ExecutionContext } from '@nestjs/common';
@@ -46,6 +45,7 @@ export class NotificationsGateway implements OnGatewayConnection, OnGatewayDisco
this.logger.error(
`Connection authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
);
void client.emit('error', { message: 'Authentication failed' });
client.disconnect();
}
}
@@ -273,7 +273,7 @@ export class NotificationsGateway implements OnGatewayConnection, OnGatewayDisco
const canActivate = await guard.canActivate(context);
if (!canActivate) {
throw new Error('Authentication failed');
throw new Error('Authentication failed');
}
}
}
+89 -7
View File
@@ -249,6 +249,17 @@
font-size: 12px;
color: #999;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
</head>
<body>
@@ -370,9 +381,34 @@
addEvent('ERROR', `Connection error: ${error.message}`);
});
socket.on('joined', data => {
addEvent('SUCCESS', `Joined room: ${data.room || 'unknown'}`, data);
});
// Handle notifications event - can be either:
// 1. List response: { notifications: [...] }
// 2. Real-time notification: { subject: string, body: string }
socket.on('notifications', data => {
addEvent('SUCCESS', `Received ${data.notifications?.length || 0} notifications`, data);
displayNotifications(data.notifications || []);
if (Array.isArray(data.notifications)) {
// List of notifications response
addEvent('SUCCESS', `Received ${data.notifications.length} notifications`, data);
displayNotifications(data.notifications);
} else if (data.subject || data.body) {
// Real-time single notification
addEvent('NOTIFICATION', 'New notification received', data);
addRealTimeNotification(data);
} else if (Array.isArray(data)) {
// Direct array response
addEvent('SUCCESS', `Received ${data.length} notifications`, data);
displayNotifications(data);
} else {
// Unknown format, try to extract notifications from various possible structures
addEvent('INFO', 'Received notifications data', data);
const notifications = data.notifications || data.data || (Array.isArray(data) ? data : [data]);
if (Array.isArray(notifications) && notifications.length > 0) {
displayNotifications(notifications);
}
}
});
socket.on('error', data => {
@@ -423,14 +459,28 @@
let html = '';
notifications.forEach(notification => {
const date = notification.createdAt ? new Date(notification.createdAt).toLocaleString() : 'N/A';
// Handle both full notification objects and simple payloads
const title = notification.title || notification.subject || 'N/A';
const content = notification.content || notification.body || 'No content';
const id = notification.id || 'N/A';
const date = notification.createdAt
? new Date(notification.createdAt).toLocaleString()
: notification.created_at
? new Date(notification.created_at).toLocaleString()
: 'N/A';
const userName = notification.user
? `${notification.user.firstName || ''} ${notification.user.lastName || ''}`.trim()
: notification.userName || '';
html += `
<div class="notification-item">
<div class="notification-title">${notification.title || 'N/A'}</div>
<div class="notification-content">${notification.content || 'No content'}</div>
<div class="notification-title">${escapeHtml(title)}</div>
<div class="notification-content">${escapeHtml(content)}</div>
<div class="notification-meta">
ID: ${notification.id} | Created: ${date}
${notification.user ? ` | User: ${notification.user.firstName || ''} ${notification.user.lastName || ''}` : ''}
ID: ${id} | Created: ${date}
${userName ? ` | User: ${escapeHtml(userName)}` : ''}
${notification.admin ? ` | Admin: ${notification.admin.firstName || ''} ${notification.admin.lastName || ''}` : ''}
</div>
</div>
`;
@@ -439,6 +489,37 @@
listDiv.innerHTML = html;
}
function addRealTimeNotification(notification) {
const listDiv = document.getElementById('notificationsList');
const title = notification.subject || notification.title || 'New Notification';
const content = notification.body || notification.content || 'No content';
const currentTime = new Date().toLocaleString();
const notificationHtml = `
<div class="notification-item" style="animation: slideIn 0.3s ease-out;">
<div class="notification-title">${escapeHtml(title)}</div>
<div class="notification-content">${escapeHtml(content)}</div>
<div class="notification-meta">
Received: ${currentTime}
</div>
</div>
`;
// Add to the top of the list
if (listDiv.children.length === 1 && listDiv.children[0].textContent.includes('No notifications')) {
listDiv.innerHTML = notificationHtml;
} else {
listDiv.insertAdjacentHTML('afterbegin', notificationHtml);
}
}
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function updateStatus(status, message) {
const statusEl = document.getElementById('connectionStatus');
statusEl.className = `status ${status}`;
@@ -457,6 +538,7 @@
WARNING: '#dcdcaa',
ERROR: '#f48771',
NOTIFICATIONS_LIST: '#4fc1ff',
NOTIFICATION: '#9cdcfe',
};
eventItem.innerHTML = `