{"size": 1371, "ext": "js", "max_stars_repo_path": "plugins/astroboy-security/app/middlewares/astroboy-security-csrf.js", "max_stars_repo_name": "gentean/astroboy", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "plugins/astroboy-security/app/middlewares/astroboy-security-csrf.js", "max_issues_repo_name": "gentean/astroboy", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "plugins/astroboy-security/app/middlewares/astroboy-security-csrf.js", "max_forks_repo_name": "gentean/astroboy", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 24.4821428571, "max_line_length": 65, "alphanum_fraction": 0.5988329686}
/**
 * CSRF
 */
const Token = require('../lib/token');

class CsrfError extends Error {
  constructor(code, msg) {
    super(`code: ${code}, msg: ${msg}`);
    this.errorContent = {
      code,
      msg
    };
    this.errorType = 'CsrfError';
  }
}

module.exports = function (options = {}, app) {
  let token = new Token({
    saltLength: options.saltLength,
    secretLength: options.secretLength
  });

  return async function csrf(ctx, next) {
    if (options.excluded.indexOf(ctx.method) === -1 &&
      options.env.indexOf(process.env.NODE_ENV) > -1) {
      const csrfSecret = ctx.cookies.get(options.csrfSecretName);
      const csrfToken = ctx.header[options.csrfTokenName];

      // token 或 secret 不存在
      if (!csrfSecret || !csrfToken) {
        throw new CsrfError(1000, 'CSRF Token Not Found!');
      }
      // token 校验失败
      if (!token.verify(csrfSecret, csrfToken)) {
        throw new CsrfError(1001, 'CSRF token Invalid!');
      }
    }

    await next();

    // 如果返回 HTML 格式数据，则生成
    if (ctx.response.is('text/html')) {
      const secret = token.secretSync();
      const newToken = token.create(secret);

      ctx.cookies.set(options.csrfSecretName, secret, {
        maxAge: options.maxAge
      });
      ctx.cookies.set(options.csrfTokenName, newToken, {
        maxAge: options.maxAge,
        httpOnly: false
      });
    }

  };
};