Skip to content
Snippets Groups Projects
Commit 71847cf3 authored by Alexandros Georgantas's avatar Alexandros Georgantas Committed by Yannis Barlas
Browse files

fix(*): use utc for expiration times

parent 60252d2c
No related branches found
No related tags found
1 merge request!68fix(*): convert to timestamp before comparison
......@@ -271,10 +271,6 @@ const handleImageVersionsCreation = async (
}
}
const getExpirationTime = secondsFromNow => {
return new Date(new Date().getTime() + 1000 * parseInt(secondsFromNow, 10))
}
module.exports = {
convertFileStreamIntoBuffer,
getFileExtension,
......@@ -282,5 +278,4 @@ module.exports = {
writeFileFromStream,
handleUnsupportedImageFormats,
handleImageVersionsCreation,
getExpirationTime,
}
......@@ -2,7 +2,7 @@ const logger = require('@pubsweet/logger')
const axios = require('axios')
const config = require('config')
const { getExpirationTime } = require('../../helpers')
const { getExpirationTime } = require('../../utils/tokens')
const Identity = require('./identity.model')
......
const axios = require('axios')
const { authenticatedCall } = require('../authenticatedCall')
jest.mock('../getAuthTokens.js', () => {
return jest.fn(() => 'token')
jest.mock('../tokens', () => {
return {
getAuthTokens: jest.fn(() => 'token'),
}
})
jest.mock('axios')
......
......@@ -2,8 +2,10 @@ const axios = require('axios')
const { callMicroservice } = require('../microservices')
jest.mock('../getAccessToken', () => {
return jest.fn(() => 'token')
jest.mock('../tokens', () => {
return {
getAccessToken: jest.fn(() => 'token'),
}
})
jest.mock('axios')
......
const makeCall = require('./makeCall')
const getAuthTokens = require('./getAuthTokens')
const { getAuthTokens } = require('./tokens')
const authenticatedCall = async (userId, providerLabel, callParameters) => {
try {
......
const config = require('config')
const axios = require('axios')
const { Identity } = require('../models')
const { getExpirationTime } = require('../helpers')
const getAuthTokens = async (userId, providerLabel) => {
try {
const providerUserIdentity = await Identity.findOne({
userId,
provider: providerLabel,
})
if (!providerUserIdentity) {
throw new Error(`identity for provider ${providerLabel} does not exist`)
}
const {
oauthAccessToken,
oauthAccessTokenExpiration,
oauthRefreshToken,
oauthRefreshTokenExpiration,
} = providerUserIdentity
const accessTokenExpired = oauthAccessTokenExpiration < new Date().getTime()
if (!accessTokenExpired) {
return oauthAccessToken
}
const refreshTokenExpired =
oauthRefreshTokenExpiration < new Date().getTime()
if (refreshTokenExpired) {
throw new Error(
`refresh token for provider ${providerLabel} expired, authorization flow should (provider login) be followed by the user`,
)
}
const integrations =
config.has('integrations') && config.get('integrations')
if (!integrations) {
throw new Error('Integrations are undefined in config')
}
const externalProvider = integrations[providerLabel]
if (!externalProvider) {
throw new Error(
`Integration ${providerLabel} configuration is undefined `,
)
}
const { tokenUrl, clientId } = integrations[providerLabel]
if (!tokenUrl) {
throw new Error(`Integration ${providerLabel} tokenUrl is undefined `)
}
if (!clientId) {
throw new Error(`Integration ${providerLabel} clientId is undefined `)
}
const tokenData = new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: oauthRefreshToken,
client_id: clientId,
})
const { data } = await axios({
method: 'post',
url: tokenUrl,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: tokenData.toString(),
})
/* eslint-disable camelcase */
const { access_token, expires_in, refresh_token, refresh_expires_in } = data
if (!access_token || !expires_in || !refresh_token || !refresh_expires_in) {
throw new Error('Missing data from response!')
}
await Identity.patchAndFetchById(providerUserIdentity.id, {
oauthAccessToken: access_token,
oauthRefreshToken: refresh_token,
oauthAccessTokenExpiration: getExpirationTime(expires_in),
oauthRefreshTokenExpiration: getExpirationTime(refresh_expires_in),
})
return access_token
/* eslint-enable camelcase */
} catch (e) {
throw new Error(e)
}
}
module.exports = getAuthTokens
const makeCall = require('./makeCall')
const getAccessToken = require('./getAccessToken')
const { getAccessToken } = require('./tokens')
/**
* Calls given microservice, while taking care of authentication for you.
......
const get = require('lodash/get')
const config = require('config')
const axios = require('axios')
const moment = require('moment')
const { ServiceCredential } = require('../models')
const { Identity, ServiceCredential } = require('../models')
const getAuthTokens = async (userId, providerLabel) => {
const data = requestTokensFromProvider(userId, providerLabel, {
checkAccessToken: true,
returnAccessToken: true,
})
/* eslint-disable camelcase */
const { access_token } = data
return access_token
/* eslint-enable camelcase */
}
const getExpirationTime = secondsFromNow => {
return moment().utc().add(secondsFromNow, 'seconds').toDate()
}
const requestTokensFromProvider = async (
userId,
providerLabel,
options = {},
) => {
const { checkAccessToken, returnAccessToken } = options
const providerUserIdentity = await Identity.findOne({
userId,
provider: providerLabel,
})
if (!providerUserIdentity) {
throw new Error(`identity for provider ${providerLabel} does not exist`)
}
const {
oauthAccessToken,
oauthAccessTokenExpiration,
oauthRefreshToken,
oauthRefreshTokenExpiration,
} = providerUserIdentity
const UTCNowTimestamp = moment().utc().toDate().getTime()
if (checkAccessToken) {
const accessTokenExpired =
oauthAccessTokenExpiration.getTime() < UTCNowTimestamp
if (!accessTokenExpired) {
return oauthAccessToken
}
}
const refreshTokenExpired =
oauthRefreshTokenExpiration.getTime() < UTCNowTimestamp
if (refreshTokenExpired) {
throw new Error(
`refresh token for provider ${providerLabel} expired, authorization flow should (provider login) be followed by the user`,
)
}
const integrations = config.has('integrations') && config.get('integrations')
if (!integrations) {
throw new Error('Integrations are undefined in config')
}
const externalProvider = integrations[providerLabel]
if (!externalProvider) {
throw new Error(`Integration ${providerLabel} configuration is undefined `)
}
const { tokenUrl, clientId } = integrations[providerLabel]
if (!tokenUrl) {
throw new Error(`Integration ${providerLabel} tokenUrl is undefined `)
}
if (!clientId) {
throw new Error(`Integration ${providerLabel} clientId is undefined `)
}
const tokenData = new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: oauthRefreshToken,
client_id: clientId,
})
const { data } = await axios({
method: 'post',
url: tokenUrl,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: tokenData.toString(),
})
/* eslint-disable camelcase */
const { access_token, expires_in, refresh_token, refresh_expires_in } = data
if (!access_token || !expires_in || !refresh_token || !refresh_expires_in) {
throw new Error('Missing data from response!')
}
await Identity.patchAndFetchById(providerUserIdentity.id, {
oauthAccessToken: access_token,
oauthRefreshToken: refresh_token,
oauthAccessTokenExpiration: getExpirationTime(expires_in),
oauthRefreshTokenExpiration: getExpirationTime(refresh_expires_in),
})
if (returnAccessToken) {
return access_token
}
return true
}
const renewAuthTokens = async (userId, providerLabel) =>
requestTokensFromProvider(userId, providerLabel)
const getAccessToken = async (serviceName, renew = false) => {
try {
......@@ -98,4 +218,9 @@ const getAccessToken = async (serviceName, renew = false) => {
}
}
module.exports = getAccessToken
module.exports = {
getAuthTokens,
getAccessToken,
renewAuthTokens,
getExpirationTime,
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment