Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 98 additions & 4 deletions workers/sender/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { DecodedGroupedEvent, ProjectDBScheme, UserDBScheme, GroupedEventDBScheme } from 'hawk.types';
import {
DecodedGroupedEvent,
ProjectDBScheme,
UserDBScheme,
GroupedEventDBScheme,
WorkspaceDBScheme,
ConfirmedMemberDBScheme
} from 'hawk.types';
import { ObjectId } from 'mongodb';
import { DatabaseController } from '../../../lib/db/controller';
import { Worker } from '../../../lib/worker';
Expand All @@ -9,9 +16,14 @@ import { TemplateEventData } from '../types/template-variables/';
import NotificationsProvider from './provider';

import { ChannelType } from 'hawk-worker-notifier/types/channel';
import { SenderWorkerEventTask, SenderWorkerAssigneeTask, SenderWorkerTask } from '../types/sender-task';
import {
SenderWorkerEventTask,
SenderWorkerAssigneeTask,
SenderWorkerTask,
SenderWorkerBlockWorkspaceTask
} from '../types/sender-task';
import { decodeUnsafeFields } from '../../../lib/utils/unsafeFields';
import { Notification, EventNotification, SeveralEventsNotification, AssigneeNotification } from './../types/template-variables';
import { Notification, EventNotification, SeveralEventsNotification, AssigneeNotification } from '../types/template-variables';

/**
* Worker to send email notifications
Expand Down Expand Up @@ -92,13 +104,14 @@ export default abstract class SenderWorker extends Worker {
switch (task.type) {
case 'event': return this.handleEventTask(task as SenderWorkerEventTask);
case 'assignee': return this.handleAssigneeTask(task as SenderWorkerAssigneeTask);
case 'block-workspace': return this.handleBlockWorkspaceTask(task as SenderWorkerBlockWorkspaceTask);
}
}

/**
* Handle event task
*
* @param task - task to handke
* @param task - task to handle
*/
private async handleEventTask(task: SenderWorkerEventTask): Promise<void> {
const { projectId, ruleId, events } = task.payload;
Expand Down Expand Up @@ -212,6 +225,49 @@ export default abstract class SenderWorker extends Worker {
} as AssigneeNotification);
}

/**
* Handle task when workspace blocked
*
* @param task - task to handle
*/
private async handleBlockWorkspaceTask(task: SenderWorkerBlockWorkspaceTask): Promise<void> {
const { workspaceId } = task.payload;

const workspace = await this.getWorkspace(workspaceId);

if (!workspace) {
this.logger.error(`Cannot send block workspace notification: workspace not found. Payload: ${task}`);

return;
}

const admins = await this.getWorkspaceAdmins(workspaceId);

if (!admins) {
this.logger.error(`Cannot send block workspace notification: workspace team not found. Payload: ${task}`);

return;
}

const adminIds = admins.map(admin => admin.userId.toString());
const users = await this.getUsers(adminIds);

await Promise.all(users.map(async user => {
const channel = user.notifications.channels[this.channelType];

if (channel.isEnabled) {
await this.provider.send(channel.endpoint, {
type: 'block-workspace',
payload: {
host: process.env.GARAGE_URL,
hostOfStatic: process.env.API_STATIC_URL,
workspace,
},
});
}
}));
}

/**
* Get event data for email
*
Expand Down Expand Up @@ -266,6 +322,32 @@ export default abstract class SenderWorker extends Worker {
return connection.collection('projects').findOne({ _id: new ObjectId(projectId) });
}

/**
* Gets workspace info from database
*
* @param workspaceId - workspace id for search
*/
private async getWorkspace(workspaceId: string): Promise<WorkspaceDBScheme | null> {
const connection = await this.accountsDb.getConnection();

return connection.collection('workspaces').findOne({ _id: new ObjectId(workspaceId) });
}

/**
* Gets confirmed admins by workspace id
*
* @param workspaceId - workspace id for search
*/
private async getWorkspaceAdmins(workspaceId: string): Promise<ConfirmedMemberDBScheme[] | null> {
const connection = await this.accountsDb.getConnection();

return connection.collection(`team:${workspaceId}`).find({
userId: { $exists: true },
isAdmin: true,
})
.toArray();
}

/**
* Get user data
*
Expand All @@ -276,4 +358,16 @@ export default abstract class SenderWorker extends Worker {

return connection.collection('users').findOne({ _id: new ObjectId(userId) });
}

/**
* Gets array of users from database
*
* @param userIds - user ids for search
*/
private async getUsers(userIds: string[]): Promise<UserDBScheme[] | null> {
const connection = await this.accountsDb.getConnection();

return connection.collection('users').find({ _id: userIds.map(userId => new ObjectId(userId)) })
.toArray();
}
}
24 changes: 24 additions & 0 deletions workers/sender/types/sender-task/blockWorkspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Payload for task when workspace blocked
*/
export interface SenderWorkerBlockWorkspacePayload {
/**
* Blocked workspace id
*/
workspaceId: string;
}

/**
* Payload of an event assigning someone to resolve the issue (event)
*/
export interface SenderWorkerBlockWorkspaceTask {
/**
* Task when workspace blocked
*/
type: 'block-workspace',

/**
* Payload for task when workspace blocked
*/
payload: SenderWorkerBlockWorkspacePayload
}
4 changes: 3 additions & 1 deletion workers/sender/types/sender-task/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { SenderWorkerAssigneeTask } from './assignee';
import { SenderWorkerEventTask } from './event';
import { SenderWorkerBlockWorkspaceTask } from './blockWorkspace';

export { SenderWorkerEventTask, SenderWorkerEventPayload } from './event';
export { SenderWorkerAssigneeTask, SenderWorkerAssigneePayload } from './assignee';
export { SenderWorkerBlockWorkspaceTask, SenderWorkerBlockWorkspacePayload } from './blockWorkspace';

export type SenderWorkerTask = SenderWorkerEventTask | SenderWorkerAssigneeTask;
export type SenderWorkerTask = SenderWorkerEventTask | SenderWorkerAssigneeTask | SenderWorkerBlockWorkspaceTask;
28 changes: 28 additions & 0 deletions workers/sender/types/template-variables/blockWorkspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { CommonTemplateVariables } from './common-template';
import { WorkspaceDBScheme } from 'hawk.types';
import { Notification } from './notification';

/**
* Variables for block workspace template
*/
export interface BlockWorkspaceTemplateVariables extends CommonTemplateVariables {
/**
* Blocked workspace data
*/
workspace: WorkspaceDBScheme;
}

/**
* Object with notification type and variables for the block workspace event template
*/
export interface BlockWorkspaceNotification extends Notification<BlockWorkspaceTemplateVariables> {
/**
* Notification when workspace blocked
*/
type: 'block-workspace';

/**
* Notification payload
*/
payload: BlockWorkspaceTemplateVariables;
}
6 changes: 4 additions & 2 deletions workers/sender/types/template-variables/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { EventsTemplateVariables, EventNotification } from './event';
import { SeveralEventsNotification } from './several-events';
import { AssigneeTemplateVariables, AssigneeNotification } from './assignee';
import { BlockWorkspaceTemplateVariables, BlockWorkspaceNotification } from './blockWorkspace';

export { CommonTemplateVariables } from './common-template';
export { TemplateEventData, EventsTemplateVariables, EventNotification } from './event';
export { SeveralEventsNotification } from './several-events';
export { AssigneeTemplateVariables, AssigneeNotification } from './assignee';
export { BlockWorkspaceTemplateVariables, BlockWorkspaceNotification } from './blockWorkspace';

/**
* Variables for notify-senders wrapped in payload with type
*/
export type Notification = EventNotification | SeveralEventsNotification | AssigneeNotification;
export type Notification = EventNotification | SeveralEventsNotification | AssigneeNotification | BlockWorkspaceNotification;

/**
* Template variables for notify-senders
*/
export type TemplateVariables = EventsTemplateVariables | AssigneeTemplateVariables;
export type TemplateVariables = EventsTemplateVariables | AssigneeTemplateVariables | BlockWorkspaceTemplateVariables;