Ver Fonte

Merge pull request #4543 from weseek/imprv/80112-serialize-actionUser-securely

Imprv/80112 serialize action user securely
cao há 4 anos atrás
pai
commit
64d05845fb

+ 1 - 1
packages/app/src/components/InAppNotification/InAppNotification.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 
 import { UserPicture } from '@growi/ui';
-import { InAppNotification as IInAppNotification } from '../../interfaces/in-app-notification';
+import { IInAppNotification } from '../../interfaces/in-app-notification';
 import { PageUpdateNotification, PageCommentNotification } from './NotificationContent';
 
 interface Props {

+ 1 - 1
packages/app/src/components/InAppNotification/InAppNotificationDropdown.tsx

@@ -6,7 +6,7 @@ import loggerFactory from '~/utils/logger';
 
 import AppContainer from '../../client/services/AppContainer';
 import { withUnstatedContainers } from '../UnstatedUtils';
-import { InAppNotification as IInAppNotification } from '../../interfaces/in-app-notification';
+import { IInAppNotification } from '../../interfaces/in-app-notification';
 import { InAppNotification } from './InAppNotification';
 import SocketIoContainer from '../../client/services/SocketIoContainer';
 

+ 2 - 1
packages/app/src/components/InAppNotification/NotificationContent.tsx

@@ -1,6 +1,7 @@
 import React from 'react';
 import { PagePathLabel } from '@growi/ui';
-import { InAppNotification as IInAppNotification } from '../../interfaces/in-app-notification';
+import { IInAppNotification } from '../../interfaces/in-app-notification';
+
 import FormattedDistanceDate from '../FormattedDistanceDate';
 
 interface Props {

+ 1 - 1
packages/app/src/interfaces/in-app-notification.ts

@@ -1,5 +1,5 @@
 // refer types https://github.com/crowi/crowi/blob/eecf2bc821098d2516b58104fe88fae81497d3ea/client/types/crowi.d.ts
-export interface InAppNotification {
+export interface IInAppNotification {
   _id: string
   user: string
   targetModel: 'Page'

+ 0 - 4
packages/app/src/server/models/activity.ts

@@ -96,10 +96,6 @@ activitySchema.methods.getNotificationTargetUsers = async function() {
   return activeNotificationUsers;
 };
 
-activitySchema.statics.getActionUsersFromActivities = function(activities) {
-  return activities.map(({ user }) => user).filter((user, i, self) => self.indexOf(user) === i);
-};
-
 activitySchema.post('save', async(savedActivity: ActivityDocument) => {
   let targetUsers: Types.ObjectId[] = [];
   try {

+ 0 - 7
packages/app/src/server/models/in-app-notification.ts

@@ -81,13 +81,6 @@ const inAppNotificationSchema = new Schema<InAppNotificationDocument, InAppNotif
 });
 inAppNotificationSchema.plugin(mongoosePaginate);
 
-inAppNotificationSchema.virtual('actionUsers').get(function(this: InAppNotificationDocument) {
-
-  const actionUsers = Activity.getActionUsersFromActivities((this.activities as any) as ActivityDocument[]);
-
-  return actionUsers;
-});
-
 const transform = (doc, ret) => {
   delete ret.activities;
 };

+ 22 - 3
packages/app/src/server/routes/apiv3/in-app-notification.ts

@@ -1,4 +1,5 @@
 import { InAppNotification } from '../../models/in-app-notification';
+import { IInAppNotification } from '../../../interfaces/in-app-notification';
 
 const express = require('express');
 const { serializeUserSecurely } = require('../../models/serializers/user-serializer');
@@ -30,15 +31,33 @@ module.exports = (crowi) => {
 
     const paginationResult = await inAppNotificationService.getLatestNotificationsByUser(user._id, requestLimit, offset);
 
-    // TODO: serialize actionUsers as well by #80112
-    paginationResult.docs.forEach((doc) => {
+
+    const getActionUsersFromActivities = function(activities) {
+      return activities.map(({ user }) => user).filter((user, i, self) => self.indexOf(user) === i);
+    };
+
+    const serializedDocs: Array<IInAppNotification> = paginationResult.docs.map((doc) => {
       if (doc.user != null && doc.user instanceof User) {
         doc.user = serializeUserSecurely(doc.user);
       }
+      // To add a new property into mongoose doc, need to change the format of doc to an object
+      const docObj: IInAppNotification = doc.toObject();
+      const actionUsersNew = getActionUsersFromActivities(doc.activities);
+
+      const serializedActionUsers = actionUsersNew.map((actionUser) => {
+        return serializeUserSecurely(actionUser);
+      });
+
+      docObj.actionUsers = serializedActionUsers;
+      return docObj;
     });
 
-    return res.apiv3(paginationResult);
+    const serializedPaginationResult = {
+      ...paginationResult,
+      docs: serializedDocs,
+    };
 
+    return res.apiv3(serializedPaginationResult);
   });
 
   router.get('/status', accessTokenParser, loginRequiredStrictly, async(req, res) => {