forgot-password.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import type { NextFunction, Request, Response } from 'express';
  2. import createError from 'http-errors';
  3. import { forgotPasswordErrorCode } from '~/interfaces/errors/forgot-password';
  4. import loggerFactory from '~/utils/logger';
  5. import type { IPasswordResetOrder } from '../models/password-reset-order';
  6. const logger = loggerFactory('growi:routes:forgot-password');
  7. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
  8. export const checkForgotPasswordEnabledMiddlewareFactory = (
  9. crowi: any,
  10. forApi = false,
  11. ) => {
  12. return (req: Request, res: Response, next: NextFunction): void => {
  13. const isPasswordResetEnabled = crowi.configManager.getConfig(
  14. 'security:passport-local:isPasswordResetEnabled',
  15. );
  16. const isLocalStrategySetup =
  17. (crowi.passportService.isLocalStrategySetup as boolean) ?? false;
  18. const isEnabled = isLocalStrategySetup && isPasswordResetEnabled;
  19. if (!isEnabled) {
  20. const message =
  21. 'Forgot-password function is unavailable because neither LocalStrategy and LdapStrategy is not setup.';
  22. logger.error(message);
  23. const statusCode = forApi ? 405 : 404;
  24. next(
  25. createError(statusCode, message, {
  26. code: forgotPasswordErrorCode.PASSWORD_RESET_IS_UNAVAILABLE,
  27. }),
  28. );
  29. return;
  30. }
  31. next();
  32. };
  33. };
  34. type Crowi = {
  35. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  36. nextApp: any;
  37. };
  38. type CrowiReq = Request & {
  39. crowi: Crowi;
  40. };
  41. export const renderForgotPassword = (crowi: Crowi) => {
  42. return (req: CrowiReq, res: Response, next: NextFunction): void => {
  43. const { nextApp } = crowi;
  44. req.crowi = crowi;
  45. nextApp.render(req, res, '/forgot-password');
  46. return;
  47. };
  48. };
  49. export const renderResetPassword = (crowi: Crowi) => {
  50. return (
  51. req: CrowiReq & { passwordResetOrder: IPasswordResetOrder },
  52. res: Response,
  53. next: NextFunction,
  54. ): void => {
  55. const { nextApp } = crowi;
  56. req.crowi = crowi;
  57. nextApp.render(req, res, '/reset-password', {
  58. email: req.passwordResetOrder.email,
  59. });
  60. return;
  61. };
  62. };
  63. // middleware to handle error
  64. export const handleErrorsMiddleware = (crowi: Crowi) => {
  65. return (
  66. error: Error & { code: string; statusCode: number },
  67. req: CrowiReq,
  68. res: Response,
  69. next: NextFunction,
  70. ): void => {
  71. if (error != null) {
  72. const { nextApp } = crowi;
  73. req.crowi = crowi;
  74. res.status(error.statusCode);
  75. nextApp.render(req, res, '/forgot-password-errors', {
  76. errorCode: error.code,
  77. });
  78. return;
  79. }
  80. next();
  81. };
  82. };