forked from FoundKeyGang/FoundKey
server: enhance reset-password endpoint
- Add a rate limit analogous to request-reset-password.
See also a0ef32f4f6
.
- Delete an expired reset request if found.
- Return a proper error.
- Use time constants.
Changelog: Changed
This commit is contained in:
parent
384e8c49b7
commit
4dc97d5b65
1 changed files with 21 additions and 6 deletions
|
@ -1,5 +1,6 @@
|
||||||
import bcrypt from 'bcryptjs';
|
import bcrypt from 'bcryptjs';
|
||||||
import { UserProfiles, PasswordResetRequests } from '@/models/index.js';
|
import { UserProfiles, PasswordResetRequests } from '@/models/index.js';
|
||||||
|
import { MINUTE } from '@/const.js';
|
||||||
import define from '../define.js';
|
import define from '../define.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
@ -9,8 +10,17 @@ export const meta = {
|
||||||
|
|
||||||
description: 'Complete the password reset that was previously requested.',
|
description: 'Complete the password reset that was previously requested.',
|
||||||
|
|
||||||
errors: {
|
limit: {
|
||||||
|
duration: HOUR,
|
||||||
|
max: 3,
|
||||||
|
},
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchResetRequest: {
|
||||||
|
message: 'No such reset request.',
|
||||||
|
code: 'NO_SUCH_RESET_REQUEST',
|
||||||
|
id: '6382759d-294c-43de-89b3-4e825006ca43',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@ -25,13 +35,18 @@ export const paramDef = {
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
const req = await PasswordResetRequests.findOneByOrFail({
|
const req = await PasswordResetRequests.findOneBy({
|
||||||
token: ps.token,
|
token: ps.token,
|
||||||
});
|
});
|
||||||
|
if (req == null) throw new ApiError(meta.errors.noSuchResetRequest);
|
||||||
|
|
||||||
// 発行してから30分以上経過していたら無効
|
// expires after 30 minutes
|
||||||
if (Date.now() - req.createdAt.getTime() > 1000 * 60 * 30) {
|
// This is a secondary check just in case the expiry task is broken,
|
||||||
throw new Error(); // TODO
|
// the expiry task is badly aligned with this expiration or something
|
||||||
|
// else strange is going on.
|
||||||
|
if (Date.now() - req.createdAt.getTime() > 30 * MINUTE) {
|
||||||
|
await PasswordResetRequests.delete(req.id);
|
||||||
|
throw new ApiError(meta.errors.noSuchResetRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate hash of password
|
// Generate hash of password
|
||||||
|
@ -42,5 +57,5 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
password: hash,
|
password: hash,
|
||||||
});
|
});
|
||||||
|
|
||||||
PasswordResetRequests.delete(req.id);
|
await PasswordResetRequests.delete(req.id);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue