slack-app-integration.js 1.9 KB

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