mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import assert from 'assert';
|
|
import { getLoggerFor } from '../../../../logging/LogUtil';
|
|
import { getFormDataRequestBody } from '../../util/FormDataUtil';
|
|
import { assertPassword, throwIdpInteractionError } from '../EmailPasswordUtil';
|
|
import type { AccountStore } from '../storage/AccountStore';
|
|
import type { InteractionResponseResult, InteractionHandlerInput } from './InteractionHandler';
|
|
import { InteractionHandler } from './InteractionHandler';
|
|
|
|
/**
|
|
* Handles the submission of the ResetPassword form:
|
|
* this is the form that is linked in the reset password email.
|
|
*/
|
|
export class ResetPasswordHandler extends InteractionHandler {
|
|
protected readonly logger = getLoggerFor(this);
|
|
|
|
private readonly accountStore: AccountStore;
|
|
|
|
public constructor(accountStore: AccountStore) {
|
|
super();
|
|
this.accountStore = accountStore;
|
|
}
|
|
|
|
public async handle({ operation }: InteractionHandlerInput): Promise<InteractionResponseResult> {
|
|
try {
|
|
// Extract record ID from request URL
|
|
const recordId = /\/([^/]+)$/u.exec(operation.target.path)?.[1];
|
|
// Validate input data
|
|
const { password, confirmPassword } = await getFormDataRequestBody(operation);
|
|
assert(
|
|
typeof recordId === 'string' && recordId.length > 0,
|
|
'Invalid request. Open the link from your email again',
|
|
);
|
|
assertPassword(password, confirmPassword);
|
|
|
|
await this.resetPassword(recordId, password);
|
|
return { type: 'response' };
|
|
} catch (error: unknown) {
|
|
throwIdpInteractionError(error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resets the password for the account associated with the given recordId.
|
|
*/
|
|
private async resetPassword(recordId: string, newPassword: string): Promise<void> {
|
|
const email = await this.accountStore.getForgotPasswordRecord(recordId);
|
|
assert(email, 'This reset password link is no longer valid.');
|
|
await this.accountStore.deleteForgotPasswordRecord(recordId);
|
|
await this.accountStore.changePassword(email, newPassword);
|
|
this.logger.debug(`Resetting password for user ${email}`);
|
|
}
|
|
}
|