chore(server): notifications IoC 5 - newStreamAccessRequestHandlerFactory
This commit is contained in:
@@ -21,47 +21,59 @@ import {
|
||||
} from '@/modules/emails/services/emailRendering'
|
||||
import { getServerInfo } from '@/modules/core/services/generic'
|
||||
import { db } from '@/db/knex'
|
||||
import { GetPendingAccessRequest } from '@/modules/accessrequests/domain/operations'
|
||||
|
||||
async function validateMessage(msg: NewStreamAccessRequestMessage) {
|
||||
const {
|
||||
targetUserId,
|
||||
data: { requestId }
|
||||
} = msg
|
||||
|
||||
const [request, user] = await Promise.all([
|
||||
getPendingAccessRequestFactory({ db })(requestId, AccessRequestType.Stream),
|
||||
getUser(targetUserId)
|
||||
])
|
||||
|
||||
if (!request)
|
||||
throw new NotificationValidationError('Nonexistant stream access request')
|
||||
if (!user) throw new NotificationValidationError('Nonexistant user')
|
||||
|
||||
const [streamWithRole, requester] = await Promise.all([
|
||||
getStream({
|
||||
streamId: request.resourceId,
|
||||
userId: targetUserId
|
||||
}),
|
||||
getUser(request.requesterId)
|
||||
])
|
||||
|
||||
if (!streamWithRole) throw new NotificationValidationError('Nonexistant stream')
|
||||
if (streamWithRole.role !== Roles.Stream.Owner)
|
||||
throw new NotificationValidationError(
|
||||
'Only stream owners can receive notifications about stream access requests'
|
||||
)
|
||||
if (!requester)
|
||||
throw new NotificationValidationError('User who made the request no longer exists')
|
||||
|
||||
return {
|
||||
request,
|
||||
stream: streamWithRole,
|
||||
targetUser: user,
|
||||
requester
|
||||
}
|
||||
type ValidateMessageDeps = {
|
||||
getPendingAccessRequest: GetPendingAccessRequest
|
||||
getUser: typeof getUser
|
||||
getStream: typeof getStream
|
||||
}
|
||||
|
||||
type ValidatedMessageState = Awaited<ReturnType<typeof validateMessage>>
|
||||
const validateMessageFactory =
|
||||
(deps: ValidateMessageDeps) => async (msg: NewStreamAccessRequestMessage) => {
|
||||
const {
|
||||
targetUserId,
|
||||
data: { requestId }
|
||||
} = msg
|
||||
|
||||
const [request, user] = await Promise.all([
|
||||
deps.getPendingAccessRequest(requestId, AccessRequestType.Stream),
|
||||
deps.getUser(targetUserId)
|
||||
])
|
||||
|
||||
if (!request)
|
||||
throw new NotificationValidationError('Nonexistant stream access request')
|
||||
if (!user) throw new NotificationValidationError('Nonexistant user')
|
||||
|
||||
const [streamWithRole, requester] = await Promise.all([
|
||||
deps.getStream({
|
||||
streamId: request.resourceId,
|
||||
userId: targetUserId
|
||||
}),
|
||||
deps.getUser(request.requesterId)
|
||||
])
|
||||
|
||||
if (!streamWithRole) throw new NotificationValidationError('Nonexistant stream')
|
||||
if (streamWithRole.role !== Roles.Stream.Owner)
|
||||
throw new NotificationValidationError(
|
||||
'Only stream owners can receive notifications about stream access requests'
|
||||
)
|
||||
if (!requester)
|
||||
throw new NotificationValidationError(
|
||||
'User who made the request no longer exists'
|
||||
)
|
||||
|
||||
return {
|
||||
request,
|
||||
stream: streamWithRole,
|
||||
targetUser: user,
|
||||
requester
|
||||
}
|
||||
}
|
||||
|
||||
type ValidatedMessageState = Awaited<
|
||||
ReturnType<ReturnType<typeof validateMessageFactory>>
|
||||
>
|
||||
|
||||
function buildEmailTemplateHtml(
|
||||
state: ValidatedMessageState
|
||||
@@ -106,22 +118,42 @@ function buildEmailTemplateParams(state: ValidatedMessageState): EmailTemplatePa
|
||||
}
|
||||
}
|
||||
|
||||
const handler: NotificationHandler<NewStreamAccessRequestMessage> = async (msg) => {
|
||||
const state = await validateMessage(msg)
|
||||
const htmlTemplateParams = buildEmailTemplateParams(state)
|
||||
const serverInfo = await getServerInfo()
|
||||
const { html, text } = await renderEmail(
|
||||
htmlTemplateParams,
|
||||
serverInfo,
|
||||
state.targetUser
|
||||
)
|
||||
const newStreamAccessRequestHandlerFactory =
|
||||
(
|
||||
deps: {
|
||||
getServerInfo: typeof getServerInfo
|
||||
renderEmail: typeof renderEmail
|
||||
sendEmail: typeof sendEmail
|
||||
} & ValidateMessageDeps
|
||||
): NotificationHandler<NewStreamAccessRequestMessage> =>
|
||||
async (msg) => {
|
||||
const state = await validateMessageFactory(deps)(msg)
|
||||
const htmlTemplateParams = buildEmailTemplateParams(state)
|
||||
const serverInfo = await deps.getServerInfo()
|
||||
const { html, text } = await deps.renderEmail(
|
||||
htmlTemplateParams,
|
||||
serverInfo,
|
||||
state.targetUser
|
||||
)
|
||||
|
||||
await sendEmail({
|
||||
to: state.targetUser.email,
|
||||
text,
|
||||
html,
|
||||
subject: 'A user requested access to your project'
|
||||
await deps.sendEmail({
|
||||
to: state.targetUser.email,
|
||||
text,
|
||||
html,
|
||||
subject: 'A user requested access to your project'
|
||||
})
|
||||
}
|
||||
|
||||
const handler: NotificationHandler<NewStreamAccessRequestMessage> = (...args) => {
|
||||
const newStreamAccessRequestHandler = newStreamAccessRequestHandlerFactory({
|
||||
getServerInfo,
|
||||
renderEmail,
|
||||
sendEmail,
|
||||
getUser,
|
||||
getStream,
|
||||
getPendingAccessRequest: getPendingAccessRequestFactory({ db })
|
||||
})
|
||||
return newStreamAccessRequestHandler(...args)
|
||||
}
|
||||
|
||||
export default handler
|
||||
|
||||
Reference in New Issue
Block a user