1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-10-18 20:09:08 +02:00

feat: changing password will expire reset password tokens (#3451)

This commit is contained in:
Jaanus Sellin 2023-04-05 12:39:52 +03:00 committed by GitHub
parent 0491c08d5e
commit 80bea14d42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 5 deletions

View File

@ -61,6 +61,10 @@ export default class ResetTokenService {
}
}
expireExistingTokensForUser = async (userId: number): Promise<void> => {
return this.store.expireExistingTokensForUser(userId);
};
async isValid(token: string): Promise<IResetToken> {
let t;
try {
@ -109,7 +113,7 @@ export default class ResetTokenService {
): Promise<IResetToken> {
const token = await this.generateToken();
const expiry = new Date(Date.now() + expiryDelta);
await this.store.expireExistingTokensForUser(tokenUser);
await this.expireExistingTokensForUser(tokenUser);
return this.store.insert({
reset_token: token,
user_id: tokenUser,

View File

@ -351,6 +351,7 @@ class UserService {
const passwordHash = await bcrypt.hash(password, saltRounds);
await this.store.setPasswordHash(userId, passwordHash);
await this.sessionService.deleteSessionsForUser(userId);
await this.resetTokenService.expireExistingTokensForUser(userId);
}
async getUserForToken(token: string): Promise<TokenUserSchema> {
@ -388,7 +389,6 @@ class UserService {
});
if (allowed) {
await this.changePassword(user.id, password);
await this.sessionService.deleteSessionsForUser(user.id);
} else {
throw new InvalidTokenError();
}

View File

@ -33,5 +33,5 @@ export interface IResetTokenStore extends Store<IResetToken, string> {
useToken(token: IResetQuery): Promise<boolean>;
deleteFromQuery(query: IResetTokenQuery): Promise<void>;
deleteExpired(): Promise<void>;
expireExistingTokensForUser(user_id: number): Promise<void>;
expireExistingTokensForUser(userId: number): Promise<void>;
}

View File

@ -168,7 +168,7 @@ test('Trying to reset password with same token twice does not work', async () =>
token,
password,
})
.expect(403)
.expect(401)
.expect((res) => {
expect(res.body.details[0].message).toBeTruthy();
});
@ -191,7 +191,7 @@ test('Calling validate endpoint with already existing session should destroy ses
await request.get('/api/admin/features').expect(200);
const url = await resetTokenService.createResetPasswordUrl(
user.id,
adminUser.username,
adminUser.username!,
);
const relative = getBackendResetUrl(url);
@ -267,3 +267,31 @@ test('Trying to change password to undefined should yield 400 without crashing t
})
.expect(400);
});
test('changing password should expire all active tokens', async () => {
const url = await resetTokenService.createResetPasswordUrl(
user.id,
adminUser.username,
);
const relative = getBackendResetUrl(url);
const {
body: { token },
} = await app.request
.get(relative)
.expect(200)
.expect('Content-Type', /json/);
await app.request
.post(`/api/admin/user-admin/${user.id}/change-password`)
.send({ password: 'simple123-_ASsad' })
.expect(200);
await app.request
.post('/auth/reset/password')
.send({
token,
password,
})
.expect(401);
});