将 Helmet 升级到 v4.5.0 并需要与 IHelmetContentSecurityPolicyDirectives 等效的类型

Upgrading Helmet to v4.5.0 and needing equivalent type to IHelmetContentSecurityPolicyDirectives

刚刚修改了 NodeJS/Typescript 应用程序中使用的依赖项,但在头盔从版本“3.23.2”更改为“4.5.0”时遇到了障碍。

我已经从 package.json 文件中删除了依赖项 "@types/helmet": "0.0.47"。

编译导致以下语义错误:

src/loaders/security.ts(2,18): error TS2305: Module '"helmet"' has no exported member 'IHelmetContentSecurityPolicyDirectives'.
src/options.ts(1,10): error TS2305: Module '"helmet"' has no exported member 'IHelmetContentSecurityPolicyDirectives'.

options.ts 包括:

import { IHelmetContentSecurityPolicyDirectives } from 'helmet';

export interface Options {
  redirectUrl: string;
  mountPath: string;
  serviceName?: string;
  views?: string | string[];
  csp?: IHelmetContentSecurityPolicyDirectives;
  i18n?: I18nOptions;
}

security.ts 定义为:

import { Application } from 'express';
import helmet, { IHelmetContentSecurityPolicyDirectives } from 'helmet';
import logger from '../lib/logger';

const configureSecurity = (app: Application, csp: IHelmetContentSecurityPolicyDirectives | undefined): void => {
  logger.info('Configuring Security using Helmet');
  const defaultSrc = (csp && csp.defaultSrc) || [];
  const styleSrc = (csp && csp.styleSrc) || [];
  const scriptSrc = (csp && csp.scriptSrc) || [];
  app.use(helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: [...defaultSrc, "'self'"],
        styleSrc: [...styleSrc, "'self'"],
        scriptSrc: [
          ...scriptSrc,
          "'self'",
          "'sha256-+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'",
          "'sha256-+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'",
        ],
      },
    },
  }));
};

export default configureSecurity;

对于 csp 类型,我不知道用什么代替 IHelmetContentSecurityPolicyDirectives

这里是头盔的维护者。

Helmet v3 没有官方的 TypeScript 定义,而 Helmet v4 有。简而言之,您看到这个问题是因为 Helmet v3 的社区制作类型没有完全映射到 Helmet v4 中的官方类型。

您正在寻找 IHelmetContentSecurityPolicyDirectives 的替代品。这是来自 Helmet 的内容安全策略模块的官方类型定义的 a snippet

export interface ContentSecurityPolicyOptions {
  directives?: Record<
    string,
    | Iterable<ContentSecurityPolicyDirectiveValue>
    | typeof dangerouslyDisableDefaultSrc
  >;
  reportOnly?: boolean;
}

ContentSecurityPolicyOptionsdirectives键是旧IHelmetContentSecurityPolicyDirectives的“转世”。

我看到两个选项:

  1. 自己定义类型,然后使用。例如:

    type CspDirectiveValue =
      | string
      | ((req: IncomingMessage, res: ServerResponse) => string);
    
    type CspDirectives = Record<string, Iterable<CspDirectiveValue>>;
    

    然后您可以使用 CspDirectives 代替旧的 IHelmetContentSecurityPolicyDirectives 类型。

  2. 稍微修改一下代码。

    您可以更新 Options 界面以采用 所有 头盔选项:

    import helmet from 'helmet';
    
    export interface Options {
      // ...
      helmetOptions: Parameters<typeof helmet>[0];
      // ...
    }
    

    然后您可以在 configureSecurity:

    中使用它
    const configureSecurity = (app: Application, helmetOptions: Parameters<typeof helmet>[0]): void => {
      // ...
      app.use(helmetOptions);
    };
    

    您的实际代码可能会有所不同。