From 67c6f701a31d322f44c0dd09ec08bb45d2f708e9 Mon Sep 17 00:00:00 2001 From: cxcarvaj Date: Tue, 15 Feb 2022 21:31:49 -0500 Subject: [PATCH 1/6] Fix: Azure endpoint return all users from ioet --- .../automatic-clock-outs/clock_out.js | 65 +++++++++-------- .../handlers/automatic-clock-outs/config.js | 5 +- .../automatic-clock-outs/msal_client.js | 72 ++++++++++++------- .../automatic-clock-outs/time_entry.js | 4 +- 4 files changed, 86 insertions(+), 60 deletions(-) diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js index 8a15406..7569f7a 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js @@ -1,29 +1,29 @@ -const _ = require("lodash"); -const CosmosClient = require("@azure/cosmos").CosmosClient; -const config = require("./config"); -const TimeEntry = require("./time_entry"); -const MsalClient = require("./msal_client"); -const TimeEntryDao = require("./time_entry_dao"); -const SlackClient = require("./slack_client"); -const { CLOCK_OUT_MESSAGE, CLOCK_OUT_MESSAGE_MIDNIGHT } = require("./constants"); +const _ = require('lodash'); +const CosmosClient = require('@azure/cosmos').CosmosClient; +const config = require('./config'); +const TimeEntry = require('./time_entry'); +const MsalClient = require('./msal_client'); +const TimeEntryDao = require('./time_entry_dao'); +const SlackClient = require('./slack_client'); +const { CLOCK_OUT_MESSAGE, CLOCK_OUT_MESSAGE_MIDNIGHT } = require('./constants'); const doClockOut = async (context) => { - context.log( + console.log( `I am going to check how many entries were not clocked out ${new Date()}` ); const { endpoint, key, databaseId } = config; const client = new CosmosClient({ endpoint, key }); const database = client.database(databaseId); - const container = database.container("time_entry"); + const container = database.container('time_entry'); const timeEntryDao = new TimeEntryDao(database); const response = await MsalClient.findUsersInMS(); - const users = response.data.value; + const users = response.data; const slackUsers = await SlackClient.findUsersInSlack(); const { resources: entries } = await timeEntryDao.getEntriesWithNoEndDate(); - context.log(`Checking for time-entries that need to be clocked out`); + console.log(`Checking for time-entries that need to be clocked out`); let totalClockOutsExecuted = 0; @@ -32,40 +32,43 @@ const doClockOut = async (context) => { const timeEntry = new TimeEntry(timeEntryAsJson); const { userName, userEmail } = findUserData(users, timeEntry.timeEntry.owner_id); const userId = findSlackUserId(slackUsers, userEmail); - - if (timeEntry.needsToBeClockedOut()) { - if (userId) { - SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE.replace('%user_name%', userName)); + if( userEmail === 'carlos.carvajal@ioet.com'){ + if (timeEntry.needsToBeClockedOut()) { + if (userId) { + SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE.replace('%user_name%', userName)); + } + timeEntryAsJson.end_date = timeEntry.getTimeToClockOut(); + await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); + totalClockOutsExecuted++; } - timeEntryAsJson.end_date = timeEntry.getTimeToClockOut(); - await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); - totalClockOutsExecuted++; - } - - else if (timeEntry.needsToBeClockedOutMidnight()) { - if (userId) { - SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); + + else if (timeEntry.needsToBeClockedOutMidnight()) { + if (userId) { + SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); + } + timeEntryAsJson.end_date = timeEntry.getTimeToClockOutMidnight(); + await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); + totalClockOutsExecuted++; } - timeEntryAsJson.end_date = timeEntry.getTimeToClockOutMidnight(); - await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); - totalClockOutsExecuted++; } + }) ); - context.log( + console.log( `I just clocked out ${totalClockOutsExecuted} entries, thanks are not needed...` ); }; + const findUserData = (users, id) => { - const user = users.find((user) => user.objectId === id); - return user ? { userName: user.displayName.split(" ")[0], userEmail: _.first(user.otherMails) } : {}; + const user = users.find((user) => user.id === id); + return user ? { userName: user.name.split(' ')[0], userEmail: (user.email) } : {}; }; const findSlackUserId = (slackUsers, email) => { const user = slackUsers.find((slackUser) => slackUser.email === email); return user ? user.id : null; }; - +doClockOut() module.exports = { doClockOut }; diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/config.js b/nodejs-functions/src/handlers/automatic-clock-outs/config.js index 3674310..0a318de 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/config.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/config.js @@ -6,7 +6,10 @@ const config = { clientId: process.env["CLIENT_ID"], authority: process.env["AUTHORITY"], clientSecret: process.env["CLIENT_SECRET"], - slackApiToken: process.env["SLACK_TOKEN_NOTIFY"] + slackApiToken: process.env["SLACK_TOKEN_NOTIFY"], + userNameMS: process.env["USER_NAME_MS"], + userPasswordMS: process.env["USER_PASSWORD_MS"] + }; module.exports = config; diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js index 332cb5b..c432a9d 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js @@ -1,27 +1,47 @@ -const axios = require("axios") -const msal = require('@azure/msal-node'); -const config = require("./config"); - -const findUsersInMS = async() => { - const {clientId, authority, clientSecret} = config; - const endpoint = 'https://graph.windows.net/ioetec.onmicrosoft.com' - const configuration = { - auth: { - clientId: clientId, - authority: authority, - clientSecret: clientSecret - } - }; - - const cca = new msal.ConfidentialClientApplication(configuration); - const clientCredentialRequest = { - scopes: ['https://graph.windows.net/.default'], - }; - const response = await cca.acquireTokenByClientCredential(clientCredentialRequest) - const token = response.accessToken - return axios.get(`${endpoint}/users?api-version=1.6&$select=displayName,otherMails,objectId`, - { 'headers': { 'Authorization': token } }) -} - -module.exports = { findUsersInMS }; +const axios = require('axios'); +const config = require('./config'); +const getToken = async () => { + const { clientId, userNameMS, userPasswordMS } = config; + const endpoint = + 'https://ioetec.b2clogin.com/ioetec.onmicrosoft.com/B2C_1_accesstoken/oauth2/v2.0/token'; + + const params = new URLSearchParams(); + + params.append('username', userNameMS); + params.append('password', userPasswordMS); + params.append('grant_type', 'password'); + params.append('scope', clientId); + params.append('client_id', clientId); + params.append('response_type', 'token'); + + const headers = { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + }; + + return await axios + .post(endpoint, params, headers) + .then((result) => { + return result.data.access_token; + }) + .catch((err) => { + console.log(`Invalid request to: ${endpoint}`); + }); +}; + +const findUsersInMS = async () => { + const endpoint = 'https://timetracker-api.azurewebsites.net/'; + const token = await getToken(); + + const headers = { + headers: { + Authorization: `Bearer ${token}`, + }, + }; + + return await axios.get(`${endpoint}/users`, headers); +}; + +module.exports = { findUsersInMS }; \ No newline at end of file diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js b/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js index d3f88ff..3ce7828 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/time_entry.js @@ -1,4 +1,4 @@ -const moment = require("moment") +const moment = require('moment') class TimeEntry { @@ -15,7 +15,7 @@ class TimeEntry { } getMidnightInTimeEntryZone(){ - return moment(this.timeEntry.start_date).utcOffset(this.timeEntry.timezone_offset * -1).endOf('day'); + return moment(this.timeEntry.start_date).utc().subtract(this.timeEntry.timezone_offset, 'minutes').endOf('day') } getTimeToClockOutMidnight(){ From 504a0f376cb25bdbd360340123b9ef798cb6ad3d Mon Sep 17 00:00:00 2001 From: cxcarvaj Date: Tue, 15 Feb 2022 21:37:49 -0500 Subject: [PATCH 2/6] Fix: Azure endpoint return all users from ioet --- .../automatic-clock-outs/clock_out.js | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js index 7569f7a..16d3668 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js @@ -8,7 +8,7 @@ const SlackClient = require('./slack_client'); const { CLOCK_OUT_MESSAGE, CLOCK_OUT_MESSAGE_MIDNIGHT } = require('./constants'); const doClockOut = async (context) => { - console.log( + context.log( `I am going to check how many entries were not clocked out ${new Date()}` ); @@ -23,52 +23,50 @@ const doClockOut = async (context) => { const slackUsers = await SlackClient.findUsersInSlack(); const { resources: entries } = await timeEntryDao.getEntriesWithNoEndDate(); - console.log(`Checking for time-entries that need to be clocked out`); + context.log(`Checking for time-entries that need to be clocked out`); let totalClockOutsExecuted = 0; await Promise.all( entries.map(async (timeEntryAsJson) => { const timeEntry = new TimeEntry(timeEntryAsJson); - const { userName, userEmail } = findUserData(users, timeEntry.timeEntry.owner_id); + const { userName, userEmail } = findUserData( users, timeEntry.timeEntry.owner_id); const userId = findSlackUserId(slackUsers, userEmail); - if( userEmail === 'carlos.carvajal@ioet.com'){ - if (timeEntry.needsToBeClockedOut()) { - if (userId) { - SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE.replace('%user_name%', userName)); - } - timeEntryAsJson.end_date = timeEntry.getTimeToClockOut(); - await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); - totalClockOutsExecuted++; + + if (timeEntry.needsToBeClockedOut()) { + if (userId) { + SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE.replace('%user_name%', userName)); } - - else if (timeEntry.needsToBeClockedOutMidnight()) { - if (userId) { - SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); - } - timeEntryAsJson.end_date = timeEntry.getTimeToClockOutMidnight(); - await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); - totalClockOutsExecuted++; + timeEntryAsJson.end_date = timeEntry.getTimeToClockOut(); + await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); + totalClockOutsExecuted++; + + } else if (timeEntry.needsToBeClockedOutMidnight()) { + if (userId) { + SlackClient.sendMessageToUser(userId,CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); } + timeEntryAsJson.end_date = timeEntry.getTimeToClockOutMidnight(); + await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); + totalClockOutsExecuted++; } - }) ); - console.log( + context.log( `I just clocked out ${totalClockOutsExecuted} entries, thanks are not needed...` ); }; - const findUserData = (users, id) => { const user = users.find((user) => user.id === id); - return user ? { userName: user.name.split(' ')[0], userEmail: (user.email) } : {}; + return user + ? { userName: user.name.split(' ')[0], userEmail: user.email } + : {}; }; const findSlackUserId = (slackUsers, email) => { const user = slackUsers.find((slackUser) => slackUser.email === email); return user ? user.id : null; }; -doClockOut() + module.exports = { doClockOut }; From 55a06c274eb061cd6b3ac0a4e593dfceafbfddb1 Mon Sep 17 00:00:00 2001 From: cxcarvaj Date: Tue, 15 Feb 2022 21:52:15 -0500 Subject: [PATCH 3/6] refactor: Refactor of code smells --- .../handlers/automatic-clock-outs/clock_out.js | 18 ++++++------------ .../automatic-clock-outs/msal_client.js | 5 ++--- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js index 16d3668..494fda0 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js @@ -8,9 +8,7 @@ const SlackClient = require('./slack_client'); const { CLOCK_OUT_MESSAGE, CLOCK_OUT_MESSAGE_MIDNIGHT } = require('./constants'); const doClockOut = async (context) => { - context.log( - `I am going to check how many entries were not clocked out ${new Date()}` - ); + context.log(`I am going to check how many entries were not clocked out ${new Date()}`); const { endpoint, key, databaseId } = config; const client = new CosmosClient({ endpoint, key }); @@ -52,21 +50,17 @@ const doClockOut = async (context) => { }) ); - context.log( - `I just clocked out ${totalClockOutsExecuted} entries, thanks are not needed...` - ); + context.log(`I just clocked out ${totalClockOutsExecuted} entries, thanks are not needed...`); }; const findUserData = (users, id) => { - const user = users.find((user) => user.id === id); - return user - ? { userName: user.name.split(' ')[0], userEmail: user.email } - : {}; + const targetUser = users.find((user) => user.id === id); + return targetUser ? { userName: targetUser.name.split(' ')[0], userEmail: targetUser.email } : {}; }; const findSlackUserId = (slackUsers, email) => { - const user = slackUsers.find((slackUser) => slackUser.email === email); - return user ? user.id : null; + const slackTargetUser = slackUsers.find((slackUser) => slackUser.email === email); + return slackTargetUser ? slackTargetUser.id : null; }; module.exports = { doClockOut }; diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js index c432a9d..54f0c22 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js @@ -21,8 +21,7 @@ const getToken = async () => { }, }; - return await axios - .post(endpoint, params, headers) + return axios.post(endpoint, params, headers) .then((result) => { return result.data.access_token; }) @@ -41,7 +40,7 @@ const findUsersInMS = async () => { }, }; - return await axios.get(`${endpoint}/users`, headers); + return axios.get(`${endpoint}/users`, headers); }; module.exports = { findUsersInMS }; \ No newline at end of file From bbf68f268363d4d87a9f6fc8dc0854b292df2ff9 Mon Sep 17 00:00:00 2001 From: cxcarvaj Date: Wed, 16 Feb 2022 09:40:08 -0500 Subject: [PATCH 4/6] style: Changes requested by review --- .../src/handlers/automatic-clock-outs/clock_out.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js index 494fda0..1a550be 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js @@ -28,7 +28,7 @@ const doClockOut = async (context) => { await Promise.all( entries.map(async (timeEntryAsJson) => { const timeEntry = new TimeEntry(timeEntryAsJson); - const { userName, userEmail } = findUserData( users, timeEntry.timeEntry.owner_id); + const { userName, userEmail } = findUserData(users, timeEntry.timeEntry.owner_id); const userId = findSlackUserId(slackUsers, userEmail); if (timeEntry.needsToBeClockedOut()) { @@ -38,10 +38,11 @@ const doClockOut = async (context) => { timeEntryAsJson.end_date = timeEntry.getTimeToClockOut(); await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); totalClockOutsExecuted++; - - } else if (timeEntry.needsToBeClockedOutMidnight()) { + } + + else if (timeEntry.needsToBeClockedOutMidnight()) { if (userId) { - SlackClient.sendMessageToUser(userId,CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); + SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); } timeEntryAsJson.end_date = timeEntry.getTimeToClockOutMidnight(); await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); From 2a1dc12869c24a6bb816742f949020ccb639b66e Mon Sep 17 00:00:00 2001 From: cxcarvaj Date: Wed, 16 Feb 2022 10:42:40 -0500 Subject: [PATCH 5/6] style: Changes requested by reviews --- .../src/handlers/automatic-clock-outs/clock_out.js | 2 +- nodejs-functions/src/handlers/automatic-clock-outs/config.js | 4 ++-- .../src/handlers/automatic-clock-outs/msal_client.js | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js index 1a550be..a98e83a 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js @@ -39,7 +39,7 @@ const doClockOut = async (context) => { await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson); totalClockOutsExecuted++; } - + else if (timeEntry.needsToBeClockedOutMidnight()) { if (userId) { SlackClient.sendMessageToUser(userId, CLOCK_OUT_MESSAGE_MIDNIGHT.replace('%user_name%', userName)); diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/config.js b/nodejs-functions/src/handlers/automatic-clock-outs/config.js index 0a318de..ff46b88 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/config.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/config.js @@ -8,8 +8,8 @@ const config = { clientSecret: process.env["CLIENT_SECRET"], slackApiToken: process.env["SLACK_TOKEN_NOTIFY"], userNameMS: process.env["USER_NAME_MS"], - userPasswordMS: process.env["USER_PASSWORD_MS"] - + userPasswordMS: process.env["USER_PASSWORD_MS"], + B2CLogin = process.env["B2C_LOGIN"] }; module.exports = config; diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js index 54f0c22..ec9ff2e 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js @@ -2,9 +2,8 @@ const axios = require('axios'); const config = require('./config'); const getToken = async () => { - const { clientId, userNameMS, userPasswordMS } = config; - const endpoint = - 'https://ioetec.b2clogin.com/ioetec.onmicrosoft.com/B2C_1_accesstoken/oauth2/v2.0/token'; + const { clientId, userNameMS, userPasswordMS, B2CLogin } = config; + const endpoint = B2CLogin; const params = new URLSearchParams(); From 462117f516734f42b7690c072834c5a90b79e7ce Mon Sep 17 00:00:00 2001 From: cxcarvaj Date: Wed, 16 Feb 2022 12:19:10 -0500 Subject: [PATCH 6/6] style: Changes requested by Sandros review --- nodejs-functions/src/handlers/automatic-clock-outs/config.js | 2 +- .../src/handlers/automatic-clock-outs/msal_client.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/config.js b/nodejs-functions/src/handlers/automatic-clock-outs/config.js index ff46b88..3fe674c 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/config.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/config.js @@ -9,7 +9,7 @@ const config = { slackApiToken: process.env["SLACK_TOKEN_NOTIFY"], userNameMS: process.env["USER_NAME_MS"], userPasswordMS: process.env["USER_PASSWORD_MS"], - B2CLogin = process.env["B2C_LOGIN"] + b2cLogin = process.env["B2C_LOGIN"] }; module.exports = config; diff --git a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js index ec9ff2e..fc8da88 100644 --- a/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js +++ b/nodejs-functions/src/handlers/automatic-clock-outs/msal_client.js @@ -2,8 +2,8 @@ const axios = require('axios'); const config = require('./config'); const getToken = async () => { - const { clientId, userNameMS, userPasswordMS, B2CLogin } = config; - const endpoint = B2CLogin; + const { clientId, userNameMS, userPasswordMS, b2cLogin } = config; + const endpoint = b2cLogin; const params = new URLSearchParams();