hakumizuki 4 lat temu
rodzic
commit
92f713d456

+ 2 - 0
packages/slack/package.json

@@ -15,11 +15,13 @@
     "test:lint:fix": "eslint src --ext .ts --fix"
   },
   "dependencies": {
+    "@types/http-errors": "^1.8.0",
     "axios": "^0.21.1",
     "browser-bunyan": "^1.6.3",
     "bunyan": "^1.8.15",
     "dotenv-flow": "^3.2.0",
     "extensible-custom-error": "^0.0.7",
+    "http-errors": "^1.8.0",
     "universal-bunyan": "^0.9.2"
   },
   "devDependencies": {

+ 1 - 0
packages/slack/src/index.ts

@@ -9,6 +9,7 @@ export const supportedGrowiCommands: string[] = [
 ];
 
 export * from './interfaces/growi-command';
+export * from './interfaces/http-errors';
 export * from './interfaces/request-between-growi-and-proxy';
 export * from './interfaces/request-from-slack';
 export * from './models/errors';

+ 3 - 2
packages/slack/src/middlewares/verify-growi-to-slack-request.ts

@@ -1,5 +1,6 @@
 import { Response, NextFunction } from 'express';
 
+import createError from 'http-errors';
 import loggerFactory from '../utils/logger';
 import { RequestFromGrowi } from '../interfaces/request-between-growi-and-proxy';
 
@@ -15,14 +16,14 @@ export const verifyGrowiToSlackRequest = (req: RequestFromGrowi, res: Response,
   if (str == null) {
     const message = 'The value of header \'x-growi-gtop-tokens\' must not be empty.';
     logger.warn(message, { body: req.body });
-    return res.status(400).send({ message });
+    return next(createError(400, message));
   }
 
   const tokens = str.split(',').map(value => value.trim());
   if (tokens.length === 0) {
     const message = 'The value of header \'x-growi-gtop-tokens\' must include at least one or more tokens.';
     logger.warn(message, { body: req.body });
-    return res.status(400).send({ message });
+    return next(createError(400, message));
   }
 
   req.tokenGtoPs = tokens;

+ 7 - 6
packages/slack/src/middlewares/verify-slack-request.ts

@@ -2,6 +2,7 @@ import { createHmac, timingSafeEqual } from 'crypto';
 import { stringify } from 'qs';
 import { Response, NextFunction } from 'express';
 
+import createError from 'http-errors';
 import loggerFactory from '../utils/logger';
 import { RequestFromSlack } from '../interfaces/request-from-slack';
 
@@ -17,7 +18,7 @@ export const verifySlackRequest = (req: RequestFromSlack, res: Response, next: N
   if (signingSecret == null) {
     const message = 'No signing secret.';
     logger.warn(message, { body: req.body });
-    return res.status(400).send({ message });
+    throw createError(400, message);
   }
 
   // take out slackSignature and timestamp from header
@@ -27,15 +28,15 @@ export const verifySlackRequest = (req: RequestFromSlack, res: Response, next: N
   if (slackSignature == null || timestamp == null) {
     const message = 'Forbidden. Enter from Slack workspace';
     logger.warn(message, { body: req.body });
-    return res.status(403).send({ message });
+    return next(createError(403, message));
   }
 
   // protect against replay attacks
   const time = Math.floor(new Date().getTime() / 1000);
   if (Math.abs(time - timestamp) > 300) {
     const message = 'Verification failed.';
-    logger.warn(message, { body: req.body });
-    return res.status(403).send({ message });
+    logger.warn(message, { body: req.body, errTYPE: createError(403, message).status });
+    return next(createError(403, message));
   }
 
   // generate growi signature
@@ -50,7 +51,7 @@ export const verifySlackRequest = (req: RequestFromSlack, res: Response, next: N
     return next();
   }
 
-  const message = 'Verification failed.';
+  const message = 'Verification fail';
   logger.warn(message, { body: req.body });
-  return res.status(403).send({ message });
+  throw createError(403, message);
 };

+ 1 - 0
packages/slackbot-proxy/package.json

@@ -44,6 +44,7 @@
     "express-graceful-exit": "=0.5.0",
     "extensible-custom-error": "^0.0.7",
     "helmet": "^4.6.0",
+    "http-errors": "^1.8.0",
     "method-override": "^3.0.0",
     "mysql2": "^2.2.5",
     "typeorm": "^0.2.31",

+ 1 - 0
packages/slackbot-proxy/src/Server.ts

@@ -18,6 +18,7 @@ import { createTerminus } from '@godaddy/terminus';
 
 import swaggerSettingsForDev from '~/config/swagger/config.dev';
 import swaggerSettingsForProd from '~/config/swagger/config.prod';
+import './filters/HttpErrorsFilter';
 import './filters/ResourceNotFoundFilter';
 import loggerFactory from '~/utils/logger';
 

+ 2 - 1
packages/slackbot-proxy/src/controllers/slack.ts

@@ -3,6 +3,7 @@ import {
 } from '@tsed/common';
 
 import axios from 'axios';
+import createError from 'http-errors';
 
 import { WebAPICallResult } from '@slack/web-api';
 
@@ -93,7 +94,7 @@ export class SlackCtrl {
   }
 
   @Post('/commands')
-  @UseBefore(AddSigningSecretToReq, verifySlackRequest, AuthorizeCommandMiddleware)
+  @UseBefore(AddSigningSecretToReq, verifySlackRequest, (req, res, next) => { return next(createError('Error DETEMASUYO!')) }, AuthorizeCommandMiddleware)
   async handleCommand(@Req() req: SlackOauthReq, @Res() res: Res): Promise<void|string|Res|WebAPICallResult> {
     const { body, authorizeResult } = req;
 

+ 20 - 0
packages/slackbot-proxy/src/filters/HttpErrorsFilter.ts

@@ -0,0 +1,20 @@
+import {
+  Catch, ExceptionFilterMethods, PlatformContext, PlatformResponse,
+} from '@tsed/common';
+import { CustomHttpError } from '@growi/slack';
+
+@Catch(CustomHttpError)
+export class HttpErrorsFilter implements ExceptionFilterMethods {
+
+  catch(exception: CustomHttpError, ctx: PlatformContext): PlatformResponse<any> {
+    // status が欲しい
+    console.log('CATCHEDDDDD!!!!!!');
+    const { response } = ctx;
+
+    console.log('$$$EXC$$$');
+    console.log(exception.message);
+
+    return response.status(418).body(exception.message);
+  }
+
+}

+ 21 - 0
yarn.lock

@@ -3010,6 +3010,11 @@
     "@types/qs" "*"
     "@types/serve-static" "*"
 
+"@types/http-errors@^1.8.0":
+  version "1.8.0"
+  resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69"
+  integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==
+
 "@types/is-stream@^1.1.0":
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/@types/is-stream/-/is-stream-1.1.0.tgz#b84d7bb207a210f2af9bed431dc0fbe9c4143be1"
@@ -9669,6 +9674,17 @@ http-errors@1.7.3, http-errors@~1.7.2:
     statuses ">= 1.5.0 < 2"
     toidentifier "1.0.0"
 
+http-errors@^1.8.0:
+  version "1.8.0"
+  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507"
+  integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==
+  dependencies:
+    depd "~1.1.2"
+    inherits "2.0.4"
+    setprototypeof "1.2.0"
+    statuses ">= 1.5.0 < 2"
+    toidentifier "1.0.0"
+
 http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
@@ -17082,6 +17098,11 @@ setprototypeof@1.1.1:
   resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
   integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
 
+setprototypeof@1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
+  integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
+
 sha.js@^2.4.0, sha.js@^2.4.8:
   version "2.4.9"
   resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"