feat: add admin tests read and update endpoints

This commit is contained in:
2026-06-06 13:33:56 +03:30
parent 39e6c96113
commit 28c1a4831e
31 changed files with 330 additions and 101 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ export class PhoneDTO {
}),
})
@Transform(({ value }) => Utils.StringUtils.normalizePhone(value as string))
phone: string;
phone!: string;
}
export class LoginDTO extends PhoneDTO {
+1 -1
View File
@@ -3,5 +3,5 @@ import { IsNotEmpty, IsString } from 'class-validator';
export class RefreshTokenDTO {
@IsNotEmpty()
@IsString()
refreshToken: string;
refreshToken!: string;
}
+1 -1
View File
@@ -9,5 +9,5 @@ export class VerifyOtpDTO extends PhoneDTO {
field: '$t(auth.fields.otp)',
}),
})
otp: string;
otp!: string;
}
@@ -3,5 +3,6 @@ Content-Type: application/json
lang: fa
{
"phone": "09121111111"
"phone": "09333026363",
"password": "Password1@"
}
@@ -2,10 +2,10 @@ POST http://localhost:3000/auth/refresh
Content-Type: application/json
// {
// "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJwaG9uZSI6IjA5MzMzMDI2MzYzIiwiaWF0IjoxNzgwMjIzNDExLCJleHAiOjE3ODAyMjcwMTEsImF1ZCI6ImxvY2FsaG9zdCIsImlzcyI6ImxvY2FsaG9zdCJ9.FNTIrk6FKO8P88yKnRCybZ6E5N3KlJaCHqZt5DMVgds",
// "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJqdGkiOiJmZDRjZGViYS1iMjUzLTQ5MjgtOGIxYS0yZTJhZDMwOTIzYzMiLCJpYXQiOjE3ODAyMjM0MTEsImV4cCI6MTc4MTA4NzQxMSwiYXVkIjoibG9jYWxob3N0IiwiaXNzIjoibG9jYWxob3N0In0.EO0OpjQix794Y7yVZ8pjLH5HngYfCTwu3lonEfXtLIQ"
// "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJwaG9uZSI6IjA5MzMzMDI2MzYzIiwiaWF0IjoxNzgwNDk0NDQ1LCJleHAiOjE3ODA0OTgwNDUsImF1ZCI6ImxvY2FsaG9zdCIsImlzcyI6ImxvY2FsaG9zdCJ9.Sy-Er8DXzEUCD6Z-GZav0XKmpIqf0sXeBkUzjIf4Ypw",
// "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJqdGkiOiIxOTA0NDljZi01ZGFiLTQ4NDYtOGU0OS1jZmNkYjhlNjI1YmQiLCJpYXQiOjE3ODA0OTQ0NDUsImV4cCI6MTc4MTM1ODQ0NSwiYXVkIjoibG9jYWxob3N0IiwiaXNzIjoibG9jYWxob3N0In0.k3ATuOrenBFRVAGUy93Kv6iCkKF7vLB2DSohoH0JpXQ"
// }
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJqdGkiOiIyZjQ1YzcxMi01ZGQzLTRhY2ItYjExYS04ZDA5YTc3YTVmYTciLCJpYXQiOjE3Nzk5NTY1OTksImV4cCI6MTc4MDgyMDU5OSwiYXVkIjoibG9jYWxob3N0IiwiaXNzIjoibG9jYWxob3N0In0.GX4kSCUCIvBVq9l4lQ8dkETvFZ1NwBIm9NGOIjBsQCc"
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEwLCJqdGkiOiJmMDA0YWNmZS03ZWU5LTQ1OTgtYjIwZi04NGM3YTA5NGU4NGIiLCJpYXQiOjE3ODAzODkxNjksImV4cCI6MTc4MTI1MzE2OSwiYXVkIjoibG9jYWxob3N0IiwiaXNzIjoibG9jYWxob3N0In0.yGKx-j0ommIdr1ARYZrXQyXRA-ZIi5Am7QS-VWlkc8w"
}
@@ -40,38 +40,32 @@ export class RefreshTokensProvider {
) {}
public async refreshTokens(refreshTokenDto: RefreshTokenDTO) {
try {
const payload = await this.jwtService.verifyAsync<RefreshTokenPayload>(
refreshTokenDto.refreshToken,
{
secret: this.jwtConfiguration.refresh.secret,
issuer: this.jwtConfiguration.issuer,
audience: this.jwtConfiguration.audience,
},
);
const payload = await this.jwtService.verifyAsync<RefreshTokenPayload>(
refreshTokenDto.refreshToken,
{
secret: this.jwtConfiguration.refresh.secret,
issuer: this.jwtConfiguration.issuer,
audience: this.jwtConfiguration.audience,
},
);
const user = await this.usersService.findOneById(payload.sub);
const user = await this.usersService.findOneById(payload.sub);
if (!payload.jti) {
throw new UnauthorizedException('auth.errors.unauthorized');
}
const existsInRedis = await this.authRedisProvider.hasRefreshToken(
payload.jti,
);
if (!existsInRedis) {
throw new UnauthorizedException('auth.errors.tokenReuse');
}
await this.authRedisProvider.revokeRefreshToken(payload.jti);
const newJti = randomUUID();
return await this.generateTokenProvider.generateTokens(user, newJti);
} catch (err) {
throw new UnauthorizedException('auth.errors.unauthorized', {
cause: err,
});
if (!payload.jti) {
throw new UnauthorizedException('auth.errors.unauthorized');
}
const existsInRedis = await this.authRedisProvider.hasRefreshToken(
payload.jti,
);
if (!existsInRedis) {
throw new UnauthorizedException('auth.errors.tokenReuse');
}
await this.authRedisProvider.revokeRefreshToken(payload.jti);
const newJti = randomUUID();
return await this.generateTokenProvider.generateTokens(user, newJti);
}
}