Skip to content

Commit

Permalink
misc: encode token in DB (#98)
Browse files Browse the repository at this point in the history
* misc: encode token in DB

* chore: update tests
  • Loading branch information
embbnux authored Jul 23, 2024
1 parent e51eba5 commit 62691d7
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 65 deletions.
8 changes: 4 additions & 4 deletions src/app/bot/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async function handleAuthorize({ bot, group, user }) {
if (rcUser) {
trelloUser = await TrelloUser.findByPk(rcUser.trello_user_id);
}
if (trelloUser && trelloUser.writeable_token) {
if (trelloUser && trelloUser.getWriteableToken()) {
await bot.sendMessage(group.id, {
text: `Hi ![:Person](${user.id}), you have authorized Trello.`,
});
Expand All @@ -89,7 +89,7 @@ async function handleUnauthorize({
if (rcUser) {
trelloUser = await TrelloUser.findByPk(rcUser.trello_user_id);
}
if (!trelloUser || !trelloUser.writeable_token) {
if (!trelloUser || !trelloUser.getWriteableToken()) {
await bot.sendMessage(group.id, {
text: `Hi ![:Person](${user.id}), you have not authorized Trello yet.`,
});
Expand All @@ -105,10 +105,10 @@ async function handleUnauthorize({
const trello = new Trello({
appKey: process.env.TRELLO_APP_KEY,
redirectUrl: '',
token: trelloUser.writeable_token,
token: trelloUser.getWriteableToken(),
});
await trello.revokeToken();
trelloUser.writeable_token = '';
trelloUser.removeWriteableToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down
18 changes: 9 additions & 9 deletions src/app/handlers/interactiveMessages.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ async function notificationInteractiveMessagesHandler(req, res) {
res.send('ok');
return;
}
if (!trelloUser || !trelloUser.writeable_token) {
if (!trelloUser || !trelloUser.getWriteableToken()) {
await sendAuthorizeRequestCard(trelloWebhook.rc_webhook_id, webhookId);
res.status(200);
res.send('ok');
return;
}
trello.setToken(trelloUser.writeable_token);
trello.setToken(trelloUser.getWriteableToken());
try {
if (action === 'joinCard') {
const members = await trello.getCardMembers(body.data.cardId);
Expand All @@ -128,7 +128,7 @@ async function notificationInteractiveMessagesHandler(req, res) {
} catch (e) {
if (e.response) {
if (e.response.status === 401) {
trelloUser.writeable_token = '';
trelloUser.removeWriteableToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down Expand Up @@ -267,16 +267,16 @@ async function botInteractiveMessagesHandler(req, res) {
redirectUrl: '',
});
if (action === 'unauthorize') {
if (!trelloUser || !trelloUser.writeable_token) {
if (!trelloUser || !trelloUser.getWriteableToken()) {
botActions.setMessageCard(
bot,
cardId,
`Hi **${body.user.firstName} ${body.user.lastName}**, You have not authorized Trello yet.`
);
} else {
trello.setToken(trelloUser.writeable_token);
trello.setToken(trelloUser.getWriteableToken());
await trello.revokeToken();
trelloUser.writeable_token = '';
trelloUser.removeWriteableToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down Expand Up @@ -304,7 +304,7 @@ async function botInteractiveMessagesHandler(req, res) {
});
return;
}
if (!rcUser || !trelloUser || !trelloUser.writeable_token) {
if (!rcUser || !trelloUser || !trelloUser.getWriteableToken()) {
res.status(200);
res.json(getAuthDialog(botId, body));
await analytics.trackUserAction('cardSubmitted', body.user.extId, {
Expand All @@ -314,7 +314,7 @@ async function botInteractiveMessagesHandler(req, res) {
});
return;
}
trello.setToken(trelloUser.writeable_token);
trello.setToken(trelloUser.getWriteableToken());
if (action === 'joinCard') {
const members = await trello.getCardMembers(body.data.cardId);
if (members.find(member => member.id === trelloUser.id)) {
Expand Down Expand Up @@ -362,7 +362,7 @@ async function botInteractiveMessagesHandler(req, res) {
trello &&
e.response.config.url.indexOf('api.trello.com') > -1
) {
trelloUser.writeable_token = '';
trelloUser.removeWriteableToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down
77 changes: 75 additions & 2 deletions src/app/models/trello-user.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
const Sequelize = require('sequelize');
const crypto = require('crypto');
const { sequelize } = require('./sequelize');

function getCipherKey() {
if (!process.env.APP_SERVER_SECRET_KEY) {
throw new Error('APP_SERVER_SECRET_KEY is not defined');
}
if (process.env.APP_SERVER_SECRET_KEY.length < 32) {
// pad secret key with spaces if it is less than 32 bytes
return process.env.APP_SERVER_SECRET_KEY.padEnd(32, ' ');
}
if (process.env.APP_SERVER_SECRET_KEY.length > 32) {
// truncate secret key if it is more than 32 bytes
return process.env.APP_SERVER_SECRET_KEY.slice(0, 32);
}
return process.env.APP_SERVER_SECRET_KEY;
}

// Model for Trello User data
exports.TrelloUser = sequelize.define('trello-users', {
const TrelloUser = sequelize.define('trello-users', {
id: {
type: Sequelize.STRING, // identify for trello user
primaryKey: true,
Expand All @@ -18,5 +34,62 @@ exports.TrelloUser = sequelize.define('trello-users', {
},
writeable_token: {
type: Sequelize.STRING
}
},
encrypted_token: {
type: Sequelize.STRING
},
encrypted_writeable_token: {
type: Sequelize.STRING
},
});

function encodeToken(token) {
const cipher = crypto.createCipheriv('aes-256-cbc', getCipherKey(), Buffer.alloc(16, 0));
return cipher.update(token, 'utf8', 'hex') + cipher.final('hex');
}

function decodedCode(encryptedData) {
const decipher = crypto.createDecipheriv('aes-256-cbc', getCipherKey(), Buffer.alloc(16, 0));
return decipher.update(encryptedData, 'hex', 'utf8') + decipher.final('utf8');
}

const originalSave = TrelloUser.prototype.save;
TrelloUser.prototype.save = async function () {
if (this.token) {
// encode data to encryptedData
this.encrypted_token = encodeToken(this.token);
this.token = '';
}
if (this.writeable_token) {
// encode data to encryptedData
this.encrypted_writeable_token = encodeToken(this.writeable_token);
this.writeable_token = '';
}
return originalSave.call(this);
}

TrelloUser.prototype.removeToken = function () {
this.token = '';
this.encrypted_token = '';
};

TrelloUser.prototype.removeWriteableToken = function () {
this.writeable_token = '';
this.encrypted_writeable_token = '';
};

TrelloUser.prototype.getToken = function () {
if (this.encrypted_token) {
return decodedCode(this.encrypted_token);
}
return this.token;
};

TrelloUser.prototype.getWriteableToken = function () {
if (this.encrypted_writeable_token) {
return decodedCode(this.encrypted_writeable_token);
}
return this.writeable_token;
}

exports.TrelloUser = TrelloUser;
12 changes: 6 additions & 6 deletions src/app/routes/authorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ async function revokeToken(req, res) {
const userId = decodedToken.id;
try {
const trelloUser = await TrelloUser.findByPk(userId);
if (trelloUser && trelloUser.token) {
if (trelloUser && trelloUser.getToken()) {
const trello = new Trello({
appKey: process.env.TRELLO_APP_KEY,
redirectUrl: `${process.env.APP_SERVER}/trello/oauth-callback`,
token: trelloUser.token,
token: trelloUser.getToken(),
});
await trello.revokeToken();
trelloUser.token = '';
trelloUser.removeToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down Expand Up @@ -297,7 +297,7 @@ async function botRevokeToken(req, res) {
return;
}
trelloUser = await TrelloUser.findByPk(rcUser.trello_user_id);
if (!trelloUser || !trelloUser.writeable_token) {
if (!trelloUser || !trelloUser.getWriteableToken()) {
res.status(200);
res.json({ result: 'ok' });
return;
Expand All @@ -306,9 +306,9 @@ async function botRevokeToken(req, res) {
appKey: process.env.TRELLO_APP_KEY,
redirectUrl: '',
});
trello.setToken(trelloUser.writeable_token);
trello.setToken(trelloUser.getWriteableToken());
await trello.revokeToken();
trelloUser.writeable_token = '';
trelloUser.removeWriteableToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down
18 changes: 9 additions & 9 deletions src/app/routes/bot-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@ async function info(req, res) {
if (rcUser.trello_user_id) {
trelloUser = await TrelloUser.findByPk(rcUser.trello_user_id);
if (trelloUser) {
botInfo.trelloAuthorized = !!trelloUser.writeable_token;
botInfo.trelloAuthorized = !!trelloUser.getWriteableToken();
botInfo.trelloUser = {
fullName: '',
};
if (trelloUser.writeable_token) {
if (trelloUser.getWriteableToken()) {
const trello = new Trello({
appKey: process.env.TRELLO_APP_KEY,
redirectUrl: '',
token: trelloUser.writeable_token,
token: trelloUser.getWriteableToken(),
});
botInfo.boards = await trello.getBoards();
const trelloUserInfo = await trello.getUserInfo();
Expand All @@ -115,7 +115,7 @@ async function info(req, res) {
e.response.status === 401 &&
trelloUser
) {
trelloUser.writeable_token = '';
trelloUser.removeWriteableToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down Expand Up @@ -177,15 +177,15 @@ async function saveSubscription(req, res) {
return;
}
trelloUser = await TrelloUser.findByPk(rcUser.trello_user_id);
if (!trelloUser || !trelloUser.writeable_token) {
if (!trelloUser || !trelloUser.getWriteableToken()) {
res.status(401);
res.send('Trello authorization required');
return;
}
const trello = new Trello({
appKey: process.env.TRELLO_APP_KEY,
redirectUrl: '',
token: trelloUser.writeable_token,
token: trelloUser.getWriteableToken(),
});
let trelloWebhook;
if (subscriptionId) {
Expand Down Expand Up @@ -246,7 +246,7 @@ async function saveSubscription(req, res) {
e.response.status === 401 &&
trelloUser
) {
trelloUser.writeable_token = '';
trelloUser.removeWriteableToken();
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
Expand Down Expand Up @@ -334,7 +334,7 @@ async function removeSubscription(req, res) {
return;
}
trelloUser = await TrelloUser.findByPk(rcUser.trello_user_id);
if (!trelloUser || !trelloUser.writeable_token) {
if (!trelloUser || !trelloUser.getWriteableToken()) {
res.status(401);
res.send('Trello authorization required');
return;
Expand All @@ -349,7 +349,7 @@ async function removeSubscription(req, res) {
const trello = new Trello({
appKey: process.env.TRELLO_APP_KEY,
redirectUrl: '',
token: trelloUser.writeable_token,
token: trelloUser.getWriteableToken(),
});
await trello.deleteWebhook({ id: trelloWebhook.trello_webhook_id });
}
Expand Down
14 changes: 9 additions & 5 deletions src/app/routes/maintain.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ async function removeUserName(req, res) {
lastKey = '';
}
for (const trelloUser of trelloUsers) {
if (!!trelloUser.username || !!trelloUser.fullName) {
await TrelloUser.update({
username: '',
fullName: '',
}, { where: { id: trelloUser.id } });
if (
trelloUser.username ||
trelloUser.fullName ||
trelloUser.writeable_token ||
trelloUser.token
) {
trelloUser.username = '';
trelloUser.fullName = '';
await trelloUser.save();
}
}
res.status(200);
Expand Down
12 changes: 6 additions & 6 deletions src/app/routes/notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async function onRcWebhookRemoved(trello, trelloWebhook, trelloUser) {
if (!trelloUser) {
trelloUser = await TrelloUser.findByPk(trelloWebhook.trello_user_id);
}
trello.setToken(trelloUser.token);
trello.setToken(trelloUser.getToken());
await trello.deleteWebhook({ id: trelloWebhook.trello_webhook_id });
await trelloWebhook.destroy();
const rcWebhookId = getRCWebhookId(trelloWebhook.rc_webhook_id);
Expand All @@ -55,7 +55,7 @@ async function onBotRemoved(trello, trelloWebhook, trelloUser) {
if (!trelloUser) {
trelloUser = await TrelloUser.findByPk(trelloWebhook.trello_user_id);
}
trello.setToken(trelloUser.writeable_token);
trello.setToken(trelloUser.getWriteableToken());
await trello.deleteWebhook({ id: trelloWebhook.trello_webhook_id });
}

Expand All @@ -79,9 +79,9 @@ async function notification(req, res) {
if (shouldUpdateBoardLabels(req.body.action.type)) {
trelloUser = await TrelloUser.findByPk(trelloWebhook.trello_user_id);
if (isBotNotification) {
trello.setToken(trelloUser.writeable_token);
trello.setToken(trelloUser.getWriteableToken());
} else {
trello.setToken(trelloUser.token);
trello.setToken(trelloUser.getToken());
}
await updateBoardLabels(trello, trelloWebhook);
}
Expand All @@ -93,9 +93,9 @@ async function notification(req, res) {
trelloUser = await TrelloUser.findByPk(trelloWebhook.trello_user_id);
}
if (isBotNotification) {
trello.setToken(trelloUser.writeable_token);
trello.setToken(trelloUser.getWriteableToken());
} else {
trello.setToken(trelloUser.token);
trello.setToken(trelloUser.getToken());
}
card = await trello.getCard(req.body.action.data.card.id);
if (!trelloWebhook.config.labels) {
Expand Down
Loading

0 comments on commit 62691d7

Please sign in to comment.