Bugfix for fees / Oauth 2 implementation
This commit is contained in:
@@ -7,7 +7,7 @@ import MonthSelector from '../../components/MonthSelector';
|
|||||||
import MemberIncidentsTables from '../../components/MemberIncidentsTables';
|
import MemberIncidentsTables from '../../components/MemberIncidentsTables';
|
||||||
import GenerateFeesInORDButton from '../../components/GenerateFeesInORDButton';
|
import GenerateFeesInORDButton from '../../components/GenerateFeesInORDButton';
|
||||||
|
|
||||||
import { fetchIncidents, addFeesToOrd } from '../../store/actions';
|
import { fetchIncidents } from '../../store/actions';
|
||||||
|
|
||||||
class IncidentsReport extends Component {
|
class IncidentsReport extends Component {
|
||||||
state = {dateRange: null};
|
state = {dateRange: null};
|
||||||
@@ -31,7 +31,6 @@ class IncidentsReport extends Component {
|
|||||||
membersMap[incident.memberId] = true;
|
membersMap[incident.memberId] = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const memberIds = Object.keys(membersMap) || [];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
@@ -41,7 +40,6 @@ class IncidentsReport extends Component {
|
|||||||
<MonthSelector buttonLabel="Show report" onDatesUpdate={this.onDatesUpdate} inlineButton />
|
<MonthSelector buttonLabel="Show report" onDatesUpdate={this.onDatesUpdate} inlineButton />
|
||||||
<br/>
|
<br/>
|
||||||
<GenerateFeesInORDButton
|
<GenerateFeesInORDButton
|
||||||
memberIds={memberIds}
|
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
dateRange={dateRange}
|
dateRange={dateRange}
|
||||||
/>
|
/>
|
||||||
@@ -61,8 +59,7 @@ const mapStateToProps = (state) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
fetchIncidents: (dateRange) => fetchIncidents(dispatch, dateRange),
|
fetchIncidents: (dateRange) => fetchIncidents(dispatch, dateRange)
|
||||||
addFeesToOrd: (dateRange, memberIds) => addFeesToOrd(dispatch, dateRange, memberIds),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(IncidentsReport);
|
export default connect(mapStateToProps, mapDispatchToProps)(IncidentsReport);
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ const officeRnDAPIErrors = {
|
|||||||
FAILED_TO_DELETE_FEES: 'Failed to delete fees in ORD',
|
FAILED_TO_DELETE_FEES: 'Failed to delete fees in ORD',
|
||||||
FAILED_TO_ADD_FEES: 'Failed to add fees in ORD',
|
FAILED_TO_ADD_FEES: 'Failed to add fees in ORD',
|
||||||
MEMBERSHIPS_ARE_NOT_LOADED_CORRECTLY: 'Memberships are not loaded correctly',
|
MEMBERSHIPS_ARE_NOT_LOADED_CORRECTLY: 'Memberships are not loaded correctly',
|
||||||
|
OAUTH_FAILED: 'Failed to fetch new OAUTH token',
|
||||||
};
|
};
|
||||||
const integrationServiceErrors = {
|
const integrationServiceErrors = {
|
||||||
PROCESSING_TRY_AGAIN: 'Incident calculations are in progress. Please try again in a few minutes',
|
PROCESSING_TRY_AGAIN: 'Incident calculations are in progress. Please try again in a few minutes',
|
||||||
|
|||||||
8
cronServices/oauth.js
Normal file
8
cronServices/oauth.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { refreshOauthToken } = require('../services/officeRnD/oauth');
|
||||||
|
|
||||||
|
refreshOauthToken().then(() => process.exit()).catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
process.exit();
|
||||||
|
});
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
BASIC_AUTH_USERNAME=username
|
BASIC_AUTH_USERNAME=username
|
||||||
BASIC_AUTH_PASSWORD=password
|
BASIC_AUTH_PASSWORD=password
|
||||||
|
|
||||||
OFFICE_RnD_TOKEN=token for Office RnD API requests
|
|
||||||
MAX_BACK_TO_BACK_DIFFERENCE=Time in minutes
|
MAX_BACK_TO_BACK_DIFFERENCE=Time in minutes
|
||||||
EARLIEST_UNLOCK=Time in minutes
|
EARLIEST_UNLOCK=Time in minutes
|
||||||
|
|
||||||
@@ -32,6 +31,10 @@ DISCOUNT_LEVEL_2_HOURS=Hours requred to apply DISCOUNT_LEVEL_2_PERCENTAGE discou
|
|||||||
DISCOUNT_LEVEL_2_PERCENTAGE=Discount to apply in percentage, if DISCOUNT_LEVEL_2_HOURS of billable hours is booked
|
DISCOUNT_LEVEL_2_PERCENTAGE=Discount to apply in percentage, if DISCOUNT_LEVEL_2_HOURS of billable hours is booked
|
||||||
DISCOUNT_PLANS=Plan names for which discount is available. Comma-separated
|
DISCOUNT_PLANS=Plan names for which discount is available. Comma-separated
|
||||||
|
|
||||||
|
ORD_OAUTH_CLIENT_ID=Client ID for this app, created in ORD; Used to obtain OAUTH token
|
||||||
|
ORD_OAUTH_CLIENT_SECRET=Client secret for this app; Used to obtain OAUTH token
|
||||||
|
ORD_OAUTH_URL=https://identity.officernd.com/oauth/token
|
||||||
|
|
||||||
#More about pool option : http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html
|
#More about pool option : http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html
|
||||||
DB_POOL_MAX_CONNECTIONS=Maximum number of connection in pool (ex. 18)
|
DB_POOL_MAX_CONNECTIONS=Maximum number of connection in pool (ex. 18)
|
||||||
DB_POOL_ACQUIRE=The maximum time, in milliseconds, that pool will try to get connection before throwing error (ex. 120000)
|
DB_POOL_ACQUIRE=The maximum time, in milliseconds, that pool will try to get connection before throwing error (ex. 120000)
|
||||||
|
|||||||
@@ -1,10 +1,27 @@
|
|||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
const officeRnDToken = process.env.OFFICE_RnD_TOKEN;
|
const { getToken } = require('../services/officeRnD/oauth');
|
||||||
|
|
||||||
const API = axios.create({
|
const API = axios.create({
|
||||||
baseURL: 'https://app.officernd.com/api/v1/organizations/sima-space-test-environment',
|
baseURL: 'https://app.officernd.com/api/v1/organizations/sima-space-test-environment',
|
||||||
headers: {'Authorization': `Bearer ${officeRnDToken}`}
|
headers: {'Authorization': `Bearer TOKEN`}
|
||||||
|
});
|
||||||
|
|
||||||
|
// request interceptor
|
||||||
|
API.interceptors.request.use((config) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
getToken(true)
|
||||||
|
.then((token) => {
|
||||||
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
|
resolve(config);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, (error) => {
|
||||||
|
// Do something with request error
|
||||||
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
15
helpers/oauthApi.js
Normal file
15
helpers/oauthApi.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('dotenv').config();
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
const OAUTHUrl = process.env.ORD_OAUTH_URL;
|
||||||
|
|
||||||
|
const OAuthAPI = axios.create({
|
||||||
|
baseURL: OAUTHUrl,
|
||||||
|
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
OAuthAPI,
|
||||||
|
};
|
||||||
27
migrations/20190830134013-add-tokens-table.js
Normal file
27
migrations/20190830134013-add-tokens-table.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.createTable('accessTokens', {
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
type: Sequelize.INTEGER
|
||||||
|
},
|
||||||
|
token: Sequelize.TEXT,
|
||||||
|
validUntil: Sequelize.DATE,
|
||||||
|
createdAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
down: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.dropTable('accessTokens');
|
||||||
|
}
|
||||||
|
};
|
||||||
12
models/accessToken.js
Normal file
12
models/accessToken.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const processing = sequelize.define('accessToken', {
|
||||||
|
token: DataTypes.TEXT,
|
||||||
|
validUntil: DataTypes.DATE,
|
||||||
|
}, {});
|
||||||
|
processing.associate = function(models) {
|
||||||
|
// associations can be defined here
|
||||||
|
};
|
||||||
|
return processing;
|
||||||
|
};
|
||||||
23
package-lock.json
generated
23
package-lock.json
generated
@@ -684,8 +684,7 @@
|
|||||||
"decode-uri-component": {
|
"decode-uri-component": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"deep-extend": {
|
"deep-extend": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
@@ -3029,6 +3028,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||||
},
|
},
|
||||||
|
"query-string": {
|
||||||
|
"version": "6.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.2.tgz",
|
||||||
|
"integrity": "sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw==",
|
||||||
|
"requires": {
|
||||||
|
"decode-uri-component": "^0.2.0",
|
||||||
|
"split-on-first": "^1.0.0",
|
||||||
|
"strict-uri-encode": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"range-parser": {
|
"range-parser": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
@@ -3519,6 +3528,11 @@
|
|||||||
"through": "2"
|
"through": "2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"split-on-first": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
|
||||||
|
},
|
||||||
"split-string": {
|
"split-string": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||||
@@ -3562,6 +3576,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||||
},
|
},
|
||||||
|
"strict-uri-encode": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
|
||||||
|
},
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
"start-client": "cd client && yarn start",
|
"start-client": "cd client && yarn start",
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client",
|
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client",
|
||||||
"check-booking-changes": "node ./cronServices/checkBookingChanges.js"
|
"check-booking-changes": "node ./cronServices/checkBookingChanges.js",
|
||||||
|
"refresh-oauth": "node ./cronServices/oauth.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "11.12.x"
|
"node": "11.12.x"
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"moment-timezone": "^0.5.25",
|
"moment-timezone": "^0.5.25",
|
||||||
"pg": "^7.11.0",
|
"pg": "^7.11.0",
|
||||||
|
"query-string": "^6.8.2",
|
||||||
"sequelize": "^5.8.6",
|
"sequelize": "^5.8.6",
|
||||||
"sequelize-cli": "^5.4.0"
|
"sequelize-cli": "^5.4.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ app.use(express.static(path.join(__dirname, 'client/build')));
|
|||||||
//production mode
|
//production mode
|
||||||
if(process.env.NODE_ENV === 'production') {
|
if(process.env.NODE_ENV === 'production') {
|
||||||
app.get('*', (req, res) => {
|
app.get('*', (req, res) => {
|
||||||
res.sendfile(path.join(__dirname = 'client/build/index.html'));
|
res.sendFile(path.join(__dirname = 'client/build/index.html'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,6 +247,10 @@ const createNegativeFeeForDiscount = (memberData, dateRange) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (membershipFeeForDiscount === 0){
|
||||||
|
return null; //This member's plan is not eligible for a discount
|
||||||
|
}
|
||||||
|
|
||||||
const totalChargeFee = membershipFeeForDiscount + totalBookingChargedFee;
|
const totalChargeFee = membershipFeeForDiscount + totalBookingChargedFee;
|
||||||
|
|
||||||
let discount = 0;
|
let discount = 0;
|
||||||
@@ -261,7 +265,7 @@ const createNegativeFeeForDiscount = (memberData, dateRange) => {
|
|||||||
const discountRate = discountPercentage / 100;
|
const discountRate = discountPercentage / 100;
|
||||||
discount = totalChargeFee * discountRate;
|
discount = totalChargeFee * discountRate;
|
||||||
}else{
|
}else{
|
||||||
return null;
|
return null; //Not enough hours to earn a discount
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedName = `[Discount] Total booked : ${totalBookedHours.toFixed(2)} hrs, Total charged : ${totalChargedHours.toFixed(2)} hrs, Discount : ${discountPercentage} %`;
|
const formattedName = `[Discount] Total booked : ${totalBookedHours.toFixed(2)} hrs, Total charged : ${totalChargedHours.toFixed(2)} hrs, Discount : ${discountPercentage} %`;
|
||||||
@@ -317,7 +321,7 @@ const getMembersFeesForDateRange = (dateRange, memberIds) => {
|
|||||||
membersMap[member.memberId] = {
|
membersMap[member.memberId] = {
|
||||||
member,
|
member,
|
||||||
bookingData: Object.assign({}, oneMemberObject),
|
bookingData: Object.assign({}, oneMemberObject),
|
||||||
membershipFees: membershipsMap[member.memberId],
|
membershipFees: membershipsMap[member.memberId] || [],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ const deleteFeesFromORD = (dateRange, memberIds) => {
|
|||||||
memberIdsMap[memberId] = true;
|
memberIdsMap[memberId] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const filterByMemberIds = memberIds.length > 0;
|
||||||
|
|
||||||
const feeIdsToRemove = [];
|
const feeIdsToRemove = [];
|
||||||
|
|
||||||
fetchedFees.forEach((fee) => {
|
fetchedFees.forEach((fee) => {
|
||||||
@@ -42,7 +44,9 @@ const deleteFeesFromORD = (dateRange, memberIds) => {
|
|||||||
|
|
||||||
const isDateInDateRange = startDate.isSameOrBefore(date) && endDate.isSameOrAfter(date);
|
const isDateInDateRange = startDate.isSameOrBefore(date) && endDate.isSameOrAfter(date);
|
||||||
const manuallyAddedFee = manualFeeNames.indexOf(name) !== -1;
|
const manuallyAddedFee = manualFeeNames.indexOf(name) !== -1;
|
||||||
if (memberIdsMap[member] && isDateInDateRange && (status === UNPAID_FEE_STATUS) && !manuallyAddedFee) {
|
const memberFeesShouldBeDeleted = filterByMemberIds ? memberIdsMap[member] : true;
|
||||||
|
|
||||||
|
if (memberFeesShouldBeDeleted && isDateInDateRange && (status === UNPAID_FEE_STATUS) && !manuallyAddedFee) {
|
||||||
feeIdsToRemove.push(feeId);
|
feeIdsToRemove.push(feeId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,14 +10,18 @@ const fetchAllMembershipsForMemberIds = (memberIds) => {
|
|||||||
const memberships = result.data || [];
|
const memberships = result.data || [];
|
||||||
|
|
||||||
if (Array.isArray(memberIds)){
|
if (Array.isArray(memberIds)){
|
||||||
const filteredMemberships = [];
|
if (memberIds.length > 0){
|
||||||
memberships.forEach((membership) => {
|
const filteredMemberships = [];
|
||||||
const { member } = membership;
|
memberships.forEach((membership) => {
|
||||||
if (memberIds.indexOf(member) !== -1){
|
const { member } = membership;
|
||||||
filteredMemberships.push(membership);
|
if (memberIds.indexOf(member) !== -1){
|
||||||
}
|
filteredMemberships.push(membership);
|
||||||
});
|
}
|
||||||
resolve(filteredMemberships);
|
});
|
||||||
|
resolve(filteredMemberships);
|
||||||
|
}else{
|
||||||
|
resolve(memberships);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
reject(integrationServiceErrors.EXPECTED_MEMBER_IDS_ARRAY);
|
reject(integrationServiceErrors.EXPECTED_MEMBER_IDS_ARRAY);
|
||||||
}
|
}
|
||||||
|
|||||||
109
services/officeRnD/oauth.js
Normal file
109
services/officeRnD/oauth.js
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
'use strict';
|
||||||
|
require('dotenv').config();
|
||||||
|
const moment = require('moment');
|
||||||
|
const queryString = require('query-string');
|
||||||
|
|
||||||
|
const { OAuthAPI } = require('../../helpers/oauthApi');
|
||||||
|
const db = require('../../models/index');
|
||||||
|
const { officeRnDAPIErrors } = require('../../constants/constants');
|
||||||
|
|
||||||
|
const updateToken = (token, validUntil) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const values = {token, validUntil};
|
||||||
|
db.accessToken.update(values, {where:{}})
|
||||||
|
.then(([numberOfUpdatedRows]) => {
|
||||||
|
if (numberOfUpdatedRows > 0){
|
||||||
|
resolve(true);
|
||||||
|
}else{
|
||||||
|
db.accessToken.bulkCreate([{token, validUntil}])
|
||||||
|
.then(() => {
|
||||||
|
resolve(false);
|
||||||
|
})
|
||||||
|
.catch((error) => reject(error));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getToken = (returnTokenOnly = false) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
db.accessToken.findAll()
|
||||||
|
.then((results) => {
|
||||||
|
if (results && results.length > 0){
|
||||||
|
const token = results[0].getDataValue('token');
|
||||||
|
const validUntil = results[0].getDataValue('validUntil');
|
||||||
|
const validUntilMoment = moment(validUntil);
|
||||||
|
if (validUntilMoment.isBefore(moment())){
|
||||||
|
refreshOauthToken()
|
||||||
|
.then((oauthResult) => {
|
||||||
|
if (returnTokenOnly){
|
||||||
|
resolve(oauthResult.token);
|
||||||
|
}else{
|
||||||
|
resolve(oauthResult);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => reject(error));
|
||||||
|
}else{
|
||||||
|
if (returnTokenOnly){
|
||||||
|
resolve(token);
|
||||||
|
}else {
|
||||||
|
resolve({token, validUntil});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
refreshOauthToken()
|
||||||
|
.then((oauthResult) => {
|
||||||
|
if (returnTokenOnly){
|
||||||
|
resolve(oauthResult.token);
|
||||||
|
}else{
|
||||||
|
resolve(oauthResult);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => reject(error));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshOauthToken = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const clientID = process.env.ORD_OAUTH_CLIENT_ID;
|
||||||
|
const clientSecret = process.env.ORD_OAUTH_CLIENT_SECRET;
|
||||||
|
|
||||||
|
const OAUTHRequestBody = {
|
||||||
|
client_id: clientID,
|
||||||
|
client_secret: clientSecret,
|
||||||
|
grant_type: 'client_credentials',
|
||||||
|
scope: 'officernd.api.read officernd.api.write',
|
||||||
|
};
|
||||||
|
|
||||||
|
OAuthAPI.post('/', queryString.stringify(OAUTHRequestBody))
|
||||||
|
.then((oauthResponse) => {
|
||||||
|
const responseData = oauthResponse && oauthResponse.data ? oauthResponse.data : null;
|
||||||
|
if (responseData){
|
||||||
|
const { access_token: accessToken, expires_in: expiresIn } = responseData;
|
||||||
|
if (accessToken && expiresIn){
|
||||||
|
const validUntil = moment().add(expiresIn, 'seconds').toISOString();
|
||||||
|
updateToken(accessToken, validUntil)
|
||||||
|
.then(() => resolve({token: accessToken, validUntil}))
|
||||||
|
.catch((error) => reject(error));
|
||||||
|
}else{
|
||||||
|
reject(officeRnDAPIErrors.OAUTH_FAILED);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
reject(officeRnDAPIErrors.OAUTH_FAILED);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log('Error obtaining OAUTH token : ', error);
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getToken,
|
||||||
|
refreshOauthToken,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user