slack-app-integration.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import crypto from 'crypto';
  2. import { defaultSupportedSlackEventActions } from '@growi/slack';
  3. import mongoose from 'mongoose';
  4. import { getModelSafely } from '../util/mongoose-utils';
  5. const schema = new mongoose.Schema({
  6. tokenGtoP: { type: String, required: true, unique: true },
  7. tokenPtoG: { type: String, required: true, unique: true },
  8. isPrimary: { type: Boolean, unique: true, sparse: true },
  9. permissionsForBroadcastUseCommands: Map,
  10. permissionsForSingleUseCommands: Map,
  11. permissionsForSlackEventActions: {
  12. type: Map,
  13. default: new Map(defaultSupportedSlackEventActions.map(action => [action, false])),
  14. },
  15. });
  16. class SlackAppIntegration {
  17. crowi;
  18. static generateAccessTokens(saltForGtoP, saltForPtoG) {
  19. const now = new Date().getTime();
  20. const hasher1 = crypto.createHash('sha512');
  21. const hasher2 = crypto.createHash('sha512');
  22. const tokenGtoP = hasher1.update(`gtop-${saltForGtoP}-${now.toString()}`).digest('base64');
  23. const tokenPtoG = hasher2.update(`ptog-${saltForPtoG}-${now.toString()}`).digest('base64');
  24. return [tokenGtoP, tokenPtoG];
  25. }
  26. static async generateUniqueAccessTokens() {
  27. let duplicateTokens;
  28. let tokenGtoP;
  29. let tokenPtoG;
  30. let generateTokens;
  31. // get salt strings
  32. const saltForGtoP = this.crowi.configManager.getConfig('crowi', 'slackbot:withProxy:saltForGtoP');
  33. const saltForPtoG = this.crowi.configManager.getConfig('crowi', 'slackbot:withProxy:saltForPtoG');
  34. do {
  35. generateTokens = this.generateAccessTokens(saltForGtoP, saltForPtoG);
  36. tokenGtoP = generateTokens[0];
  37. tokenPtoG = generateTokens[1];
  38. // eslint-disable-next-line no-await-in-loop
  39. duplicateTokens = await this.findOne({ $or: [{ tokenGtoP }, { tokenPtoG }] });
  40. } while (duplicateTokens != null);
  41. return { tokenGtoP, tokenPtoG };
  42. }
  43. }
  44. const factory = (crowi) => {
  45. const modelExists = getModelSafely('SlackAppIntegration');
  46. if (modelExists != null) {
  47. return modelExists;
  48. }
  49. SlackAppIntegration.crowi = crowi;
  50. schema.loadClass(SlackAppIntegration);
  51. return mongoose.model('SlackAppIntegration', schema);
  52. };
  53. export default factory;