import { OFFICIAL_NOTICE_EXTEND_TYPE , USER_STATE } from 'common/enums' ; import { ActionFailedError , UserInputError } from 'common/errors' ; import logger from 'common/logger' ; import { fromGlobalId , getPunishExpiredDate } from 'common/utils' ; import { userQueue } from 'connectors/queue' ; import { MutationToUpdateUserStateResolver } from 'definitions' ; const resolver = async ( _ , { input : { id , state , banDays , password , emails } } , { viewer , dataSources : { userService , notificationService , atomService } } ) => { const handleBan = async ( userId ) => { notificationService . trigger ( { event : OFFICIAL_NOTICE_EXTEND_TYPE . user_banned , recipientId : userId , } ) ; if ( typeof banDays === 'number' ) { const expiredAt = getPunishExpiredDate ( banDays ) ; await userService . baseCreate ( { userId , state , expiredAt , } , 'punish_record' ) ; } } ; const handleUnban = ( userId ) => userService . archivePunishRecordsByUserId ( { userId , state : USER_STATE . banned , } ) ; const isArchived = state === USER_STATE . archived ; /**
     * Batch update with email array
     */ if ( emails && emails . length > 0 ) { if ( isArchived ) { throw new UserInputError ( 'Cannot archive users in batch' ) ; } const updatedUsers = await userService . knex . whereIn ( 'email' , emails ) . update ( { state } ) . into ( userService . table ) . returning ( '*' ) . then ( ( users ) => users . map ( ( batchUpdatedUser ) => { const { id : userId } = batchUpdatedUser ; if ( state === USER_STATE . banned ) { handleBan ( userId ) ; } return batchUpdatedUser ; } ) ) ; return updatedUsers ; } if ( ! id ) { throw new UserInputError ( 'need to provide `id` or `emails`' ) ; } const { id : dbId } = fromGlobalId ( id ) ; const user = await userService . dataloader . load ( dbId ) ; if ( user . state === USER_STATE . archived || ( state === USER_STATE . banned && user . state === USER_STATE . banned ) ) { throw new ActionFailedError ( `user has already been ${ state }` ) ; } /**
     * Archive
     */ if ( isArchived ) { if ( ! password || ! viewer . id ) { throw new UserInputError ( '`password` is required for archiving user' ) ; } else { await userService . verifyPassword ( { password , hash : viewer . passwordHash } ) ; } const archivedUser = await userService . archive ( dbId ) ; userQueue . archiveUser ( { userId : archivedUser . id } ) ; notificationService . mail . sendUserDeletedByAdmin ( { to : user . email , recipient : { displayName : user . displayName , } , language : user . language , } ) ; return [ archivedUser ] ; } /**
     * active, banned, frozen
     */ const updatedUser = await atomService . update ( { table : 'user' , where : { id : dbId } , data : { state , } , } ) ; try { await atomService . es . client . update ( { index : 'user' , id : dbId , body : { doc : { state , } , } , } ) ; } catch ( err ) { logger . error ( err ) ; } if ( state === USER_STATE . banned ) { handleBan ( updatedUser . id ) ; } else if ( state !== user . state && user . state === USER_STATE . banned ) { handleUnban ( updatedUser . id ) ; } return [ updatedUser ] ; } ; export default resolver ;