mirror of
https://github.com/stonith404/pingvin-share.git
synced 2025-01-29 01:28:59 -05:00
feat: delete all sessions if password was changed
This commit is contained in:
parent
74e8956106
commit
02e41e2437
3 changed files with 59 additions and 20 deletions
|
@ -21,6 +21,7 @@ import { AuthRegisterDTO } from "./dto/authRegister.dto";
|
||||||
import { AuthSignInDTO } from "./dto/authSignIn.dto";
|
import { AuthSignInDTO } from "./dto/authSignIn.dto";
|
||||||
import { AuthSignInTotpDTO } from "./dto/authSignInTotp.dto";
|
import { AuthSignInTotpDTO } from "./dto/authSignInTotp.dto";
|
||||||
import { EnableTotpDTO } from "./dto/enableTotp.dto";
|
import { EnableTotpDTO } from "./dto/enableTotp.dto";
|
||||||
|
import { TokenDTO } from "./dto/token.dto";
|
||||||
import { UpdatePasswordDTO } from "./dto/updatePassword.dto";
|
import { UpdatePasswordDTO } from "./dto/updatePassword.dto";
|
||||||
import { VerifyTotpDTO } from "./dto/verifyTotp.dto";
|
import { VerifyTotpDTO } from "./dto/verifyTotp.dto";
|
||||||
import { JwtGuard } from "./guard/jwt.guard";
|
import { JwtGuard } from "./guard/jwt.guard";
|
||||||
|
@ -45,8 +46,8 @@ export class AuthController {
|
||||||
|
|
||||||
response = this.addTokensToResponse(
|
response = this.addTokensToResponse(
|
||||||
response,
|
response,
|
||||||
result.accessToken,
|
result.refreshToken,
|
||||||
result.refreshToken
|
result.accessToken
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -64,8 +65,8 @@ export class AuthController {
|
||||||
if (result.accessToken && result.refreshToken) {
|
if (result.accessToken && result.refreshToken) {
|
||||||
response = this.addTokensToResponse(
|
response = this.addTokensToResponse(
|
||||||
response,
|
response,
|
||||||
result.accessToken,
|
result.refreshToken,
|
||||||
result.refreshToken
|
result.accessToken
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,17 +84,28 @@ export class AuthController {
|
||||||
|
|
||||||
response = this.addTokensToResponse(
|
response = this.addTokensToResponse(
|
||||||
response,
|
response,
|
||||||
result.accessToken,
|
result.refreshToken,
|
||||||
result.refreshToken
|
result.accessToken
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
return new TokenDTO().from(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch("password")
|
@Patch("password")
|
||||||
@UseGuards(JwtGuard)
|
@UseGuards(JwtGuard)
|
||||||
async updatePassword(@GetUser() user: User, @Body() dto: UpdatePasswordDTO) {
|
async updatePassword(
|
||||||
await this.authService.updatePassword(user, dto.oldPassword, dto.password);
|
@GetUser() user: User,
|
||||||
|
@Res({ passthrough: true }) response: Response,
|
||||||
|
@Body() dto: UpdatePasswordDTO
|
||||||
|
) {
|
||||||
|
const result = await this.authService.updatePassword(
|
||||||
|
user,
|
||||||
|
dto.oldPassword,
|
||||||
|
dto.password
|
||||||
|
);
|
||||||
|
|
||||||
|
response = this.addTokensToResponse(response, result.refreshToken);
|
||||||
|
return new TokenDTO().from(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("token")
|
@Post("token")
|
||||||
|
@ -108,7 +120,7 @@ export class AuthController {
|
||||||
request.cookies.refresh_token
|
request.cookies.refresh_token
|
||||||
);
|
);
|
||||||
response.cookie("access_token", accessToken);
|
response.cookie("access_token", accessToken);
|
||||||
return { accessToken };
|
return new TokenDTO().from({ accessToken });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("signOut")
|
@Post("signOut")
|
||||||
|
@ -146,15 +158,16 @@ export class AuthController {
|
||||||
|
|
||||||
private addTokensToResponse(
|
private addTokensToResponse(
|
||||||
response: Response,
|
response: Response,
|
||||||
accessToken: string,
|
refreshToken?: string,
|
||||||
refreshToken: string
|
accessToken?: string
|
||||||
) {
|
) {
|
||||||
response.cookie("access_token", accessToken);
|
if (accessToken) response.cookie("access_token", accessToken);
|
||||||
response.cookie("refresh_token", refreshToken, {
|
if (refreshToken)
|
||||||
path: "/api/auth/token",
|
response.cookie("refresh_token", refreshToken, {
|
||||||
httpOnly: true,
|
path: "/api/auth/token",
|
||||||
maxAge: 1000 * 60 * 60 * 24 * 30 * 3,
|
httpOnly: true,
|
||||||
});
|
maxAge: 1000 * 60 * 60 * 24 * 30 * 3,
|
||||||
|
});
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,10 +87,16 @@ export class AuthService {
|
||||||
|
|
||||||
const hash = await argon.hash(newPassword);
|
const hash = await argon.hash(newPassword);
|
||||||
|
|
||||||
return await this.prisma.user.update({
|
await this.prisma.refreshToken.deleteMany({
|
||||||
|
where: { userId: user.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.prisma.user.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
data: { password: hash },
|
data: { password: hash },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this.createRefreshToken(user.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async createAccessToken(user: User, refreshTokenId: string) {
|
async createAccessToken(user: User, refreshTokenId: string) {
|
||||||
|
@ -112,7 +118,12 @@ export class AuthService {
|
||||||
refreshTokenId: string;
|
refreshTokenId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.prisma.refreshToken.delete({ where: { id: refreshTokenId } });
|
await this.prisma.refreshToken
|
||||||
|
.delete({ where: { id: refreshTokenId } })
|
||||||
|
.catch((e) => {
|
||||||
|
// Ignore error if refresh token doesn't exist
|
||||||
|
if (e.code != "P2025") throw e;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshAccessToken(refreshToken: string) {
|
async refreshAccessToken(refreshToken: string) {
|
||||||
|
|
15
backend/src/auth/dto/token.dto.ts
Normal file
15
backend/src/auth/dto/token.dto.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Expose, plainToClass } from "class-transformer";
|
||||||
|
|
||||||
|
export class TokenDTO {
|
||||||
|
@Expose()
|
||||||
|
accessToken: string;
|
||||||
|
|
||||||
|
@Expose()
|
||||||
|
refreshToken: string;
|
||||||
|
|
||||||
|
from(partial: Partial<TokenDTO>) {
|
||||||
|
return plainToClass(TokenDTO, partial, {
|
||||||
|
excludeExtraneousValues: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue