From cee4129c165afaa913e0dfd65e69557ecad91039 Mon Sep 17 00:00:00 2001
From: Maksim Eltyshev
Date: Mon, 8 Apr 2024 00:26:33 +0200
Subject: [PATCH] fix: Refactoring
---
docker-compose.yml | 20 +++---
server/.env.sample | 19 +++---
server/api/controllers/cards/delete.js | 1 +
server/api/helpers/actions/create-one.js | 34 ++++++++---
server/api/helpers/cards/create-one.js | 8 ---
server/api/helpers/cards/delete-one.js | 15 +++--
server/api/helpers/cards/update-one.js | 12 ----
.../api/helpers/notifications/create-one.js | 2 +
server/api/helpers/utils/send-email.js | 2 +-
.../api/helpers/utils/send-slack-message.js | 53 ++++++++++++++++
server/api/services/slack.js | 61 -------------------
server/config/custom.js | 17 +++---
12 files changed, 125 insertions(+), 119 deletions(-)
create mode 100644 server/api/helpers/utils/send-slack-message.js
delete mode 100644 server/api/services/slack.js
diff --git a/docker-compose.yml b/docker-compose.yml
index 0a294fb..f7935aa 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -31,14 +31,6 @@ services:
# - DEFAULT_ADMIN_NAME=Demo Demo
# - DEFAULT_ADMIN_USERNAME=demo
- # Email Notifications (https://nodemailer.com/smtp/)
- # - SMTP_HOST=
- # - SMTP_PORT=587
- # - SMTP_SECURE=true
- # - SMTP_USER=
- # - SMTP_PASSWORD=
- # - SMTP_FROM="Demo Demo"
-
# - OIDC_ISSUER=
# - OIDC_CLIENT_ID=
# - OIDC_CLIENT_SECRET=
@@ -52,8 +44,16 @@ services:
# - OIDC_IGNORE_ROLES=true
# - OIDC_ENFORCED=true
- # - SLACK_BOT_TOKEN=xoxb-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx
- # - SLACK_CHANNEL_ID=xxxxxxxxxx
+ # Email Notifications (https://nodemailer.com/smtp/)
+ # - SMTP_HOST=
+ # - SMTP_PORT=587
+ # - SMTP_SECURE=true
+ # - SMTP_USER=
+ # - SMTP_PASSWORD=
+ # - SMTP_FROM="Demo Demo"
+
+ # - SLACK_BOT_TOKEN=
+ # - SLACK_CHANNEL_ID=
depends_on:
postgres:
condition: service_healthy
diff --git a/server/.env.sample b/server/.env.sample
index fb5a828..15d66ed 100644
--- a/server/.env.sample
+++ b/server/.env.sample
@@ -22,14 +22,6 @@ SECRET_KEY=notsecretkey
# DEFAULT_ADMIN_NAME=Demo Demo
# DEFAULT_ADMIN_USERNAME=demo
-# Email Notifications (https://nodemailer.com/smtp/)
-# SMTP_HOST=
-# SMTP_PORT=587
-# SMTP_SECURE=true
-# SMTP_USER=
-# SMTP_PASSWORD=
-# SMTP_FROM="Demo Demo"
-
# OIDC_ISSUER=
# OIDC_CLIENT_ID=
# OIDC_CLIENT_SECRET=
@@ -43,6 +35,17 @@ SECRET_KEY=notsecretkey
# OIDC_IGNORE_ROLES=true
# OIDC_ENFORCED=true
+# Email Notifications (https://nodemailer.com/smtp/)
+# SMTP_HOST=
+# SMTP_PORT=587
+# SMTP_SECURE=true
+# SMTP_USER=
+# SMTP_PASSWORD=
+# SMTP_FROM="Demo Demo"
+
+# SLACK_BOT_TOKEN=
+# SLACK_CHANNEL_ID=
+
## Do not edit this
TZ=UTC
diff --git a/server/api/controllers/cards/delete.js b/server/api/controllers/cards/delete.js
index e2b6d00..dad82de 100755
--- a/server/api/controllers/cards/delete.js
+++ b/server/api/controllers/cards/delete.js
@@ -47,6 +47,7 @@ module.exports = {
card = await sails.helpers.cards.deleteOne.with({
record: card,
+ user: currentUser,
request: this.req,
});
diff --git a/server/api/helpers/actions/create-one.js b/server/api/helpers/actions/create-one.js
index 773e0ce..b03adfd 100644
--- a/server/api/helpers/actions/create-one.js
+++ b/server/api/helpers/actions/create-one.js
@@ -1,5 +1,3 @@
-const services = require('../../services/slack');
-
const valuesValidator = (value) => {
if (!_.isPlainObject(value)) {
return false;
@@ -16,6 +14,30 @@ const valuesValidator = (value) => {
return true;
};
+const buildAndSendSlackMessage = async (user, card, action) => {
+ const cardLink = `<${sails.config.custom.baseUrl}/cards/${card.id}|${card.name}>`;
+
+ let markdown;
+ switch (action.type) {
+ case Action.Types.CREATE_CARD:
+ markdown = `${cardLink} was created by ${user.name} in *${action.data.list.name}*`;
+
+ break;
+ case Action.Types.MOVE_CARD:
+ markdown = `${cardLink} was moved by ${user.name} to *${action.data.toList.name}*`;
+
+ break;
+ case Action.Types.COMMENT_CARD:
+ markdown = `*${user.name}* commented on ${cardLink}:\n>${action.data.text}`;
+
+ break;
+ default:
+ return;
+ }
+
+ await sails.helpers.utils.sendSlackMessage(markdown);
+};
+
module.exports = {
inputs: {
values: {
@@ -69,11 +91,9 @@ module.exports = {
),
);
- const cardUrl = services.buildCardUrl(values.card);
- const messageText = `*${inputs.values.user.name}* commented on ${cardUrl}:\n>${values.data.text}`;
- services.sendSlackMessage(messageText).catch((error) => {
- sails.log.error('Failed to send Slack message:', error.message);
- });
+ if (sails.config.custom.slackBotToken) {
+ buildAndSendSlackMessage(values.user, values.card, action);
+ }
return action;
},
diff --git a/server/api/helpers/cards/create-one.js b/server/api/helpers/cards/create-one.js
index 0a04016..847a00c 100644
--- a/server/api/helpers/cards/create-one.js
+++ b/server/api/helpers/cards/create-one.js
@@ -1,5 +1,3 @@
-const services = require('../../services/slack');
-
const valuesValidator = (value) => {
if (!_.isPlainObject(value)) {
return false;
@@ -113,12 +111,6 @@ module.exports = {
board: inputs.board,
});
- const cardUrl = services.buildCardUrl(card);
- const messageText = `${cardUrl} was created by ${values.creatorUser.name} in *${values.list.name}*`;
- services.sendSlackMessage(messageText).catch((error) => {
- sails.log.error('Failed to send Slack message:', error.message);
- });
-
return card;
},
};
diff --git a/server/api/helpers/cards/delete-one.js b/server/api/helpers/cards/delete-one.js
index 111247e..a947f73 100644
--- a/server/api/helpers/cards/delete-one.js
+++ b/server/api/helpers/cards/delete-one.js
@@ -1,4 +1,6 @@
-const services = require('../../services/slack');
+const buildAndSendSlackMessage = async (user, card) => {
+ await sails.helpers.utils.sendSlackMessage(`*${card.name}* was deleted by ${user.name}`);
+};
module.exports = {
inputs: {
@@ -6,6 +8,10 @@ module.exports = {
type: 'ref',
required: true,
},
+ user: {
+ type: 'ref',
+ required: true,
+ },
request: {
type: 'ref',
},
@@ -24,10 +30,9 @@ module.exports = {
inputs.request,
);
- const messageText = `*${card.name}* was deleted by ${inputs.request.name}`;
- services.sendSlackMessage(messageText).catch((error) => {
- sails.log.error('Failed to send Slack message:', error.message);
- });
+ if (sails.config.custom.slackBotToken) {
+ buildAndSendSlackMessage(inputs.user, card);
+ }
}
return card;
diff --git a/server/api/helpers/cards/update-one.js b/server/api/helpers/cards/update-one.js
index a496a1e..4363f9b 100644
--- a/server/api/helpers/cards/update-one.js
+++ b/server/api/helpers/cards/update-one.js
@@ -1,5 +1,3 @@
-const services = require('../../services/slack');
-
const valuesValidator = (value) => {
if (!_.isPlainObject(value)) {
return false;
@@ -271,16 +269,6 @@ module.exports = {
}
}
- const cardMoved = inputs.values.list !== undefined;
-
- if (cardMoved) {
- const cardUrl = services.buildCardUrl(card);
- const messageText = `${cardUrl} was moved by ${inputs.user.name} to *${inputs.list.name}*`;
- services.sendSlackMessage(messageText).catch((error) => {
- sails.log.error('Failed to send Slack message:', error.message);
- });
- }
-
return card;
},
};
diff --git a/server/api/helpers/notifications/create-one.js b/server/api/helpers/notifications/create-one.js
index 271a917..f24e4bf 100644
--- a/server/api/helpers/notifications/create-one.js
+++ b/server/api/helpers/notifications/create-one.js
@@ -27,6 +27,7 @@ const buildAndSendEmail = async (user, board, card, action, notifiableUser) => {
`from ${action.data.fromList.name} to ${action.data.toList.name} ` +
`on ${board.name}
`,
};
+
break;
case Action.Types.COMMENT_CARD:
emailData = {
@@ -37,6 +38,7 @@ const buildAndSendEmail = async (user, board, card, action, notifiableUser) => {
`on ${board.name}` +
`${action.data.text}
`,
};
+
break;
default:
return;
diff --git a/server/api/helpers/utils/send-email.js b/server/api/helpers/utils/send-email.js
index 5d9be72..7b8d08b 100644
--- a/server/api/helpers/utils/send-email.js
+++ b/server/api/helpers/utils/send-email.js
@@ -25,7 +25,7 @@ module.exports = {
sails.log.info('Email sent: %s', info.messageId);
} catch (error) {
- sails.log.error(error);
+ sails.log.error(error); // TODO: provide description text?
}
},
};
diff --git a/server/api/helpers/utils/send-slack-message.js b/server/api/helpers/utils/send-slack-message.js
new file mode 100644
index 0000000..573fcf8
--- /dev/null
+++ b/server/api/helpers/utils/send-slack-message.js
@@ -0,0 +1,53 @@
+const POST_MESSAGE_API_URL = 'https://slack.com/api/chat.postMessage';
+
+module.exports = {
+ inputs: {
+ markdown: {
+ type: 'string',
+ required: true,
+ },
+ },
+
+ async fn(inputs) {
+ const headers = {
+ Authorization: `Bearer ${sails.config.custom.slackBotToken}`,
+ 'Content-Type': 'application/json; charset=utf-8',
+ };
+
+ const body = {
+ blocks: [
+ {
+ type: 'section',
+ text: {
+ type: 'mrkdwn',
+ text: inputs.markdown,
+ },
+ },
+ ],
+ channel: sails.config.custom.slackChannelId,
+ };
+
+ let response;
+ try {
+ response = await fetch(POST_MESSAGE_API_URL, {
+ headers,
+ method: 'POST',
+ body: JSON.stringify(body),
+ });
+ } catch (error) {
+ sails.log.error(error); // TODO: provide description text?
+ return;
+ }
+
+ if (!response.ok) {
+ sails.log.error('Error sending to Slack: %s', response.error);
+ return;
+ }
+
+ const responseJson = await response.json();
+
+ if (!responseJson.ok) {
+ sails.log.error('Error sending to Slack: %s', responseJson.error);
+ }
+ },
+};
diff --git a/server/api/services/slack.js b/server/api/services/slack.js
deleted file mode 100644
index 2aa5f54..0000000
--- a/server/api/services/slack.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const slackPostUrl = 'https://slack.com/api/chat.postMessage';
-const channelId = process.env.SLACK_CHANNEL_ID;
-const slackAPIToken = process.env.SLACK_BOT_TOKEN;
-const plankaProdUrl = process.env.BASE_URL;
-
-async function sendSlackMessage(messageText) {
- if (!slackAPIToken) {
- throw new Error('No Slack BOT token found');
- }
-
- const postData = {
- blocks: [
- {
- type: 'section',
- text: {
- type: 'mrkdwn',
- text: messageText,
- },
- },
- ],
- channel: channelId,
- };
-
- const config = {
- headers: {
- 'Content-Type': 'application/json; charset=utf-8',
- Authorization: `Bearer ${slackAPIToken}`,
- },
- };
-
- const response = await fetch(slackPostUrl, {
- method: 'POST',
- headers: config.headers,
- body: JSON.stringify(postData),
- });
-
- if (!response.ok) {
- sails.log.Error('Error sending to Slack :', response.error);
- return Promise.reject(response);
- }
-
- const responseText = await new Response(response.body).text();
- const jsonBody = JSON.parse(responseText);
- if (!jsonBody.ok) {
- sails.log.Error('Error sending to Slack :', jsonBody.error);
- return Promise.reject(response);
- }
-
- return response;
-}
-
-function buildCardUrl(card) {
- const url = `${plankaProdUrl}/cards/${card.id}`;
- const cardUrl = `<${url}|${card.name}>`;
- return cardUrl;
-}
-
-module.exports = {
- sendSlackMessage,
- buildCardUrl,
-};
diff --git a/server/config/custom.js b/server/config/custom.js
index 7647324..ac344d0 100644
--- a/server/config/custom.js
+++ b/server/config/custom.js
@@ -34,13 +34,6 @@ module.exports.custom = {
defaultAdminEmail:
process.env.DEFAULT_ADMIN_EMAIL && process.env.DEFAULT_ADMIN_EMAIL.toLowerCase(),
- smtpHost: process.env.SMTP_HOST,
- smtpPort: process.env.SMTP_PORT || 587,
- smtpSecure: process.env.SMTP_SECURE === 'true',
- smtpUser: process.env.SMTP_USER,
- smtpPassword: process.env.SMTP_PASSWORD,
- smtpFrom: process.env.SMTP_FROM,
-
oidcIssuer: process.env.OIDC_ISSUER,
oidcClientId: process.env.OIDC_CLIENT_ID,
oidcClientSecret: process.env.OIDC_CLIENT_SECRET,
@@ -58,4 +51,14 @@ module.exports.custom = {
oidcRedirectUri: `${
sails.config.environment === 'production' ? process.env.BASE_URL : 'http://localhost:3000'
}/oidc-callback`,
+
+ smtpHost: process.env.SMTP_HOST,
+ smtpPort: process.env.SMTP_PORT || 587,
+ smtpSecure: process.env.SMTP_SECURE === 'true',
+ smtpUser: process.env.SMTP_USER,
+ smtpPassword: process.env.SMTP_PASSWORD,
+ smtpFrom: process.env.SMTP_FROM,
+
+ slackBotToken: process.env.SLACK_BOT_TOKEN,
+ slackChannelId: process.env.SLACK_CHANNEL_ID,
};