questionnaire.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import crypto from 'crypto';
  2. import * as os from 'node:os';
  3. import { IUserHasId } from '~/interfaces/user';
  4. import { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
  5. import {
  6. GrowiWikiType, GrowiExternalAuthProviderType, IGrowiInfo, GrowiServiceType, GrowiAttachmentType, GrowiDeploymentType,
  7. } from '../../interfaces/growi-info';
  8. import { StatusType } from '../../interfaces/questionnaire-answer-status';
  9. import { IUserInfo, UserType } from '../../interfaces/user-info';
  10. import QuestionnaireAnswerStatus from '../models/questionnaire-answer-status';
  11. import QuestionnaireOrder, { QuestionnaireOrderDocument } from '../models/questionnaire-order';
  12. import { isShowableCondition } from '../util/condition';
  13. class QuestionnaireService {
  14. crowi: any;
  15. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  16. constructor(crowi) {
  17. this.crowi = crowi;
  18. }
  19. async getGrowiInfo(): Promise<IGrowiInfo> {
  20. const User = this.crowi.model('User');
  21. const appSiteUrl = this.crowi.appService.getSiteUrl();
  22. const hasher = crypto.createHash('sha256');
  23. hasher.update(appSiteUrl);
  24. const appSiteUrlHashed = hasher.digest('hex');
  25. const currentUsersCount = await User.countDocuments();
  26. const currentActiveUsersCount = await User.countActiveUsers();
  27. const wikiMode = this.crowi.configManager.getConfig('crowi', 'security:wikiMode');
  28. const wikiType = wikiMode === 'private' ? GrowiWikiType.closed : GrowiWikiType.open;
  29. const activeExternalAccountTypes: GrowiExternalAuthProviderType[] = Object.values(GrowiExternalAuthProviderType).filter((type) => {
  30. return this.crowi.configManager.getConfig('crowi', `security:passport-${type}:isEnabled`);
  31. });
  32. const typeStr = this.crowi.configManager.getConfig('crowi', 'app:serviceType');
  33. const type = Object.values(GrowiServiceType).includes(typeStr) ? typeStr : null;
  34. const attachmentTypeStr = this.crowi.configManager.getConfig('crowi', 'app:fileUploadType');
  35. const attachmentType = Object.values(GrowiAttachmentType).includes(attachmentTypeStr) ? attachmentTypeStr : null;
  36. const deploymentTypeStr = this.crowi.configManager.getConfig('crowi', 'app:deploymentType');
  37. const deploymentType = Object.values(GrowiDeploymentType).includes(deploymentTypeStr) ? deploymentTypeStr : null;
  38. return {
  39. version: this.crowi.version,
  40. osInfo: {
  41. type: os.type(),
  42. platform: os.platform(),
  43. arch: os.arch(),
  44. totalmem: os.totalmem(),
  45. },
  46. appSiteUrl: this.crowi.configManager.getConfig('crowi', 'questionnaire:isAppSiteUrlHashed') ? null : appSiteUrl,
  47. appSiteUrlHashed,
  48. type,
  49. currentUsersCount,
  50. currentActiveUsersCount,
  51. wikiType,
  52. attachmentType,
  53. activeExternalAccountTypes,
  54. deploymentType,
  55. };
  56. }
  57. getUserInfo(user: IUserHasId | null, appSiteUrlHashed: string): IUserInfo {
  58. if (user != null) {
  59. const hasher = crypto.createHmac('sha256', appSiteUrlHashed);
  60. hasher.update(user._id.toString());
  61. return {
  62. userIdHash: hasher.digest('hex'),
  63. type: user.admin ? UserType.admin : UserType.general,
  64. userCreatedAt: user.createdAt,
  65. };
  66. }
  67. return { type: UserType.guest };
  68. }
  69. async getQuestionnaireOrdersToShow(userInfo: IUserInfo, growiInfo: IGrowiInfo, userId: ObjectIdLike | null): Promise<QuestionnaireOrderDocument[]> {
  70. const currentDate = new Date();
  71. let questionnaireOrders = await QuestionnaireOrder.find({
  72. showUntil: {
  73. $gte: currentDate,
  74. },
  75. });
  76. if (userId != null) {
  77. const statuses = await QuestionnaireAnswerStatus.find({ userId, questionnaireOrderId: { $in: questionnaireOrders.map(d => d._id) } });
  78. questionnaireOrders = questionnaireOrders.filter((order) => {
  79. const status = statuses.find(s => s.questionnaireOrderId.toString() === order._id.toString());
  80. return !status || status?.status === StatusType.not_answered;
  81. });
  82. }
  83. return questionnaireOrders
  84. .filter((order) => {
  85. return isShowableCondition(order, userInfo, growiInfo);
  86. });
  87. }
  88. }
  89. export default QuestionnaireService;