Просмотр исходного кода

update login js for allow registration request without mail setting

ryoji-s 3 лет назад
Родитель
Сommit
4051093af3

+ 4 - 3
apps/app/src/interfaces/in-app-notification.ts

@@ -1,4 +1,5 @@
 import type { IPageSnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
 import type { IPageSnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
+import type { IUserSnapshot } from '~/models/serializers/in-app-notification-snapshot/user';
 
 
 import { IPage } from './page';
 import { IPage } from './page';
 import { IUser } from './user';
 import { IUser } from './user';
@@ -11,14 +12,14 @@ export enum InAppNotificationStatuses {
 
 
 export interface IInAppNotification {
 export interface IInAppNotification {
   user: IUser
   user: IUser
-  targetModel: 'Page'
-  target: IPage
+  targetModel: 'Page' | 'User'
+  target: IPage | IUser
   action: 'COMMENT' | 'LIKE'
   action: 'COMMENT' | 'LIKE'
   status: InAppNotificationStatuses
   status: InAppNotificationStatuses
   actionUsers: IUser[]
   actionUsers: IUser[]
   createdAt: Date
   createdAt: Date
   snapshot: string
   snapshot: string
-  parsedSnapshot?: IPageSnapshot
+  parsedSnapshot?: IPageSnapshot | IUserSnapshot
 }
 }
 
 
 /*
 /*

+ 15 - 0
apps/app/src/models/serializers/in-app-notification-snapshot/user.ts

@@ -0,0 +1,15 @@
+import type { IUser } from '~/interfaces/user';
+
+export interface IUserSnapshot {
+  username: string
+}
+
+export const stringifySnapshot = (user: IUser): string => {
+  return JSON.stringify({
+    username: user.username,
+  });
+};
+
+export const parseSnapshot = (snapshot: string): IUserSnapshot => {
+  return JSON.parse(snapshot);
+};

+ 18 - 7
apps/app/src/server/routes/login.js

@@ -10,7 +10,7 @@ module.exports = function(crowi, app) {
   const path = require('path');
   const path = require('path');
   const User = crowi.model('User');
   const User = crowi.model('User');
   const {
   const {
-    configManager, appService, aclService, mailService,
+    configManager, appService, aclService, mailService, activityService,
   } = crowi;
   } = crowi;
   const activityEvent = crowi.event('activity');
   const activityEvent = crowi.event('activity');
 
 
@@ -42,12 +42,28 @@ module.exports = function(crowi, app) {
       .forEach(result => logger.error(result.reason));
       .forEach(result => logger.error(result.reason));
   }
   }
 
 
+  async function sendNotificationToAllAdmins(user) {
+    const adminUsers = await User.findAdmins();
+    const activity = await activityService.createActivity({
+      action: SupportedAction.ACTION_USER_REGISTRATION_APPROVAL_REQUEST,
+      target: user,
+      targetModel: 'User',
+    });
+    await activityEvent.emit('updated', activity, user, adminUsers);
+    return;
+  }
+
   const registerSuccessHandler = async function(req, res, userData, registrationMode) {
   const registerSuccessHandler = async function(req, res, userData, registrationMode) {
     const parameters = { action: SupportedAction.ACTION_USER_REGISTRATION_SUCCESS };
     const parameters = { action: SupportedAction.ACTION_USER_REGISTRATION_SUCCESS };
     activityEvent.emit('update', res.locals.activity._id, parameters);
     activityEvent.emit('update', res.locals.activity._id, parameters);
 
 
+    const isMailerSetup = mailService.isMailerSetup ?? false;
+
     if (registrationMode === aclService.labels.SECURITY_REGISTRATION_MODE_RESTRICTED) {
     if (registrationMode === aclService.labels.SECURITY_REGISTRATION_MODE_RESTRICTED) {
-      await sendEmailToAllAdmins(userData);
+      sendNotificationToAllAdmins(userData);
+      if (isMailerSetup) {
+        await sendEmailToAllAdmins(userData);
+      }
       return res.apiv3({});
       return res.apiv3({});
     }
     }
 
 
@@ -142,11 +158,6 @@ module.exports = function(crowi, app) {
       }
       }
 
 
       const registrationMode = configManager.getConfig('crowi', 'security:registrationMode');
       const registrationMode = configManager.getConfig('crowi', 'security:registrationMode');
-      const isMailerSetup = mailService.isMailerSetup ?? false;
-
-      if (!isMailerSetup && registrationMode === aclService.labels.SECURITY_REGISTRATION_MODE_RESTRICTED) {
-        return res.apiv3Err(['message.email_settings_is_not_setup'], 403);
-      }
 
 
       User.createUserByEmailAndPassword(name, username, email, password, undefined, async(err, userData) => {
       User.createUserByEmailAndPassword(name, username, email, password, undefined, async(err, userData) => {
         if (err) {
         if (err) {

+ 15 - 8
apps/app/src/server/service/in-app-notification.ts

@@ -6,7 +6,8 @@ import { Types } from 'mongoose';
 
 
 import { AllEssentialActions, SupportedAction } from '~/interfaces/activity';
 import { AllEssentialActions, SupportedAction } from '~/interfaces/activity';
 import { InAppNotificationStatuses, PaginateResult } from '~/interfaces/in-app-notification';
 import { InAppNotificationStatuses, PaginateResult } from '~/interfaces/in-app-notification';
-import { stringifySnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
+import * as pageSerializers from '~/models/serializers/in-app-notification-snapshot/page';
+import * as userSerializers from '~/models/serializers/in-app-notification-snapshot/user';
 import { ActivityDocument } from '~/server/models/activity';
 import { ActivityDocument } from '~/server/models/activity';
 import {
 import {
   InAppNotification,
   InAppNotification,
@@ -17,7 +18,6 @@ import Subscription from '~/server/models/subscription';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import Crowi from '../crowi';
 import Crowi from '../crowi';
-import { PageDocument } from '../models/page';
 import { RoomPrefix, getRoomNameWithId } from '../util/socket-io-helpers';
 import { RoomPrefix, getRoomNameWithId } from '../util/socket-io-helpers';
 
 
 
 
@@ -51,11 +51,11 @@ export default class InAppNotificationService {
   }
   }
 
 
   initActivityEventListeners(): void {
   initActivityEventListeners(): void {
-    this.activityEvent.on('updated', async(activity: ActivityDocument, target: IPage, descendantsSubscribedUsers?: Ref<IUser>[]) => {
+    this.activityEvent.on('updated', async(activity: ActivityDocument, target: IPage, users?: Ref<IUser>[]) => {
       try {
       try {
         const shouldNotification = activity != null && target != null && (AllEssentialActions as ReadonlyArray<string>).includes(activity.action);
         const shouldNotification = activity != null && target != null && (AllEssentialActions as ReadonlyArray<string>).includes(activity.action);
         if (shouldNotification) {
         if (shouldNotification) {
-          await this.createInAppNotification(activity, target, descendantsSubscribedUsers);
+          await this.createInAppNotification(activity, target, users);
         }
         }
       }
       }
       catch (err) {
       catch (err) {
@@ -199,9 +199,16 @@ export default class InAppNotificationService {
     return;
     return;
   };
   };
 
 
-  createInAppNotification = async function(activity: ActivityDocument, target: IPage, descendantsSubscribedUsers?: Ref<IUser>[]): Promise<void> {
+  createInAppNotification = async function(activity: ActivityDocument, target: IPage | IUser, users?: Ref<IUser>[]): Promise<void> {
+    if (activity.action === SupportedAction.ACTION_USER_REGISTRATION_APPROVAL_REQUEST) {
+      const snapshot = userSerializers.stringifySnapshot(target);
+      await this.upsertByActivity(users, activity, snapshot);
+      await this.emitSocketIo(users);
+      return;
+    }
+
     const shouldNotification = activity != null && target != null && (AllEssentialActions as ReadonlyArray<string>).includes(activity.action);
     const shouldNotification = activity != null && target != null && (AllEssentialActions as ReadonlyArray<string>).includes(activity.action);
-    const snapshot = stringifySnapshot(target);
+    const snapshot = pageSerializers.stringifySnapshot(target);
     if (shouldNotification) {
     if (shouldNotification) {
       let mentionedUsers: IUser[] = [];
       let mentionedUsers: IUser[] = [];
       if (activity.action === SupportedAction.ACTION_COMMENT_CREATE) {
       if (activity.action === SupportedAction.ACTION_COMMENT_CREATE) {
@@ -209,9 +216,9 @@ export default class InAppNotificationService {
       }
       }
       const notificationTargetUsers = await activity?.getNotificationTargetUsers();
       const notificationTargetUsers = await activity?.getNotificationTargetUsers();
       let notificationDescendantsUsers = [];
       let notificationDescendantsUsers = [];
-      if (descendantsSubscribedUsers != null) {
+      if (users != null) {
         const User = this.crowi.model('User');
         const User = this.crowi.model('User');
-        const descendantsUsers = descendantsSubscribedUsers.filter(item => (item.toString() !== activity.user._id.toString()));
+        const descendantsUsers = users.filter(item => (item.toString() !== activity.user._id.toString()));
         notificationDescendantsUsers = await User.find({
         notificationDescendantsUsers = await User.find({
           _id: { $in: descendantsUsers },
           _id: { $in: descendantsUsers },
           status: User.STATUS_ACTIVE,
           status: User.STATUS_ACTIVE,

+ 12 - 2
apps/app/src/stores/in-app-notification.ts

@@ -1,7 +1,8 @@
 import useSWR, { SWRConfiguration, SWRResponse } from 'swr';
 import useSWR, { SWRConfiguration, SWRResponse } from 'swr';
 
 
 import type { InAppNotificationStatuses, IInAppNotification, PaginateResult } from '~/interfaces/in-app-notification';
 import type { InAppNotificationStatuses, IInAppNotification, PaginateResult } from '~/interfaces/in-app-notification';
-import { parseSnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
+import * as pageSerializers from '~/models/serializers/in-app-notification-snapshot/page';
+import * as userSerializers from '~/models/serializers/in-app-notification-snapshot/user';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import { apiv3Get } from '../client/util/apiv3-client';
 import { apiv3Get } from '../client/util/apiv3-client';
@@ -23,7 +24,16 @@ export const useSWRxInAppNotifications = <Data, Error>(
       const inAppNotificationPaginateResult = response.data as inAppNotificationPaginateResult;
       const inAppNotificationPaginateResult = response.data as inAppNotificationPaginateResult;
       inAppNotificationPaginateResult.docs.forEach((doc) => {
       inAppNotificationPaginateResult.docs.forEach((doc) => {
         try {
         try {
-          doc.parsedSnapshot = parseSnapshot(doc.snapshot as string);
+          switch (doc.targetModel) {
+            case 'Page':
+              doc.parsedSnapshot = pageSerializers.parseSnapshot(doc.snapshot);
+              break;
+            case 'User':
+              doc.parsedSnapshot = userSerializers.parseSnapshot(doc.snapshot);
+              break;
+            default:
+              throw new Error(`No serializer found for targetModel: ${doc.targetModel}`);
+          }
         }
         }
         catch (err) {
         catch (err) {
           logger.warn('Failed to parse snapshot', err);
           logger.warn('Failed to parse snapshot', err);