This commit is contained in:
2025-11-16 12:07:39 +03:30
parent d605303e52
commit b3c44d734c
10 changed files with 88 additions and 25 deletions
+52 -7
View File
@@ -26,10 +26,10 @@ export class TokensService {
private readonly cacheService: CacheService,
) {}
async generateTokens(user: User, rest: Restaurant, em?: EntityManager) {
async generateTokens(ownerId: string, rest: Restaurant, em?: EntityManager) {
return this.generateAccessAndRefreshToken(
{
userId: user.id,
userId: ownerId,
restId: rest.id,
},
em,
@@ -76,7 +76,7 @@ export class TokensService {
const accessToken = await this.jwtService.signAsync(tokenPayload, { expiresIn: `${accessExpire}m` });
const refreshToken = this.generateRefreshToken();
await this.storeRefreshToken(payload.adminId, payload.restId, refreshToken, em);
await this.storeRefreshTokenAdmin(payload.adminId, payload.restId, refreshToken, em);
return {
accessToken: { token: accessToken, expire: dayjs().add(accessExpire, 'minute').valueOf() },
refreshToken: { token: refreshToken, expire: dayjs().add(refreshExpire, 'day').valueOf() },
@@ -105,7 +105,52 @@ export class TokensService {
const token = entityManager.create(RefreshToken, {
token: refreshToken,
restaurant,
user,
ownerId: userId,
expiresAt,
});
// Use persist instead of persistAndFlush when in transaction
if (isExternalTransaction) {
entityManager.persist(token);
} else {
await entityManager.persistAndFlush(token);
if (entityManager.isInTransaction()) {
await entityManager.commit();
}
}
} catch (error) {
this.logger.error(error);
// Only rollback if we started the transaction
if (!isExternalTransaction && entityManager.isInTransaction()) {
await entityManager.rollback();
}
throw error;
}
}
async storeRefreshTokenAdmin(adminId: string, restId: string, refreshToken: string, em?: EntityManager) {
const entityManager = em || this.em.fork();
const isExternalTransaction = !!em && em.isInTransaction();
try {
// Only start transaction if no external EntityManager with transaction is provided
if (!isExternalTransaction && !entityManager.isInTransaction()) {
await entityManager.begin();
}
const refreshExpire = this.configService.getOrThrow<number>('REFRESH_TOKEN_EXPIRE');
const expiresAt = dayjs().add(refreshExpire, 'day').toDate();
const admin = await entityManager.findOne(Admin, { id: adminId });
if (!admin) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
const restaurant = await entityManager.findOne(Restaurant, { id: restId });
if (!restaurant) throw new BadRequestException(UserMessage.Rest_NOT_FOUND);
const token = entityManager.create(RefreshToken, {
token: refreshToken,
restaurant,
ownerId: adminId,
expiresAt,
});
@@ -138,7 +183,7 @@ export class TokensService {
RefreshToken,
{ token: oldRefreshToken },
{
populate: ['user', 'restaurant'],
populate: ['restaurant'],
},
);
@@ -158,7 +203,7 @@ export class TokensService {
entityManager.remove(token);
// Generate new tokens within the same transaction
const tokens = await this.generateTokens(token.user, token.restaurant, entityManager);
const tokens = await this.generateTokens(token.ownerId, token.restaurant, entityManager);
// Commit the transaction
await entityManager.flush();
@@ -180,7 +225,7 @@ export class TokensService {
try {
await entityManager.begin();
await entityManager.nativeDelete(RefreshToken, { user: { id: userId } });
await entityManager.nativeDelete(RefreshToken, { ownerId: userId });
this.logger.log(`Successfully deleted all refresh tokens for user ${userId}`);
await entityManager.commit();